ReactOS 0.4.15-dev-7958-gcd0bb1a
winldr.c File Reference
#include <freeldr.h>
#include <ndk/asm.h>
#include <internal/i386/intrin_i.h>
#include "../../winldr.h"
#include <debug.h>
Include dependency graph for winldr.c:

Go to the source code of this file.

Classes

struct  GDTIDT
 

Macros

#define KIP0PCRADDRESS   0xffdff000
 
#define SELFMAP_ENTRY   0x300
 
#define DPL_SYSTEM   0
 
#define DPL_USER   3
 
#define TYPE_TSS16A   0x01
 
#define TYPE_LDT   0x02
 
#define TYPE_TSS16B   0x03
 
#define TYPE_CALL16   0x04
 
#define TYPE_TASK   0x05
 
#define TYPE_INT16   0x06
 
#define TYPE_TRAP16   0x07
 
#define TYPE_TSS32A   0x09
 
#define TYPE_TSS32B   0x0B
 
#define TYPE_CALL32   0x0C
 
#define TYPE_INT32   0x0E
 
#define TYPE_TRAP32   0x0F
 
#define DESCRIPTOR_ACCESSED   0x1
 
#define DESCRIPTOR_READ_WRITE   0x2
 
#define DESCRIPTOR_EXECUTE_READ   0x2
 
#define DESCRIPTOR_EXPAND_DOWN   0x4
 
#define DESCRIPTOR_CONFORMING   0x4
 
#define DESCRIPTOR_CODE   0x8
 
#define TYPE_CODE   (0x10 | DESCRIPTOR_CODE | DESCRIPTOR_EXECUTE_READ)
 
#define TYPE_DATA   (0x10 | DESCRIPTOR_READ_WRITE)
 
#define ExtendedBIOSDataArea   ((PULONG)0x740)
 
#define ExtendedBIOSDataSize   ((PULONG)0x744)
 
#define RomFontPointers   ((PULONG)0x700)
 

Functions

 DBG_DEFAULT_CHANNEL (WINDOWS)
 
static BOOLEAN MempAllocatePageTables (VOID)
 
static VOID MempAllocatePTE (ULONG Entry, PHARDWARE_PTE *PhysicalPT, PHARDWARE_PTE *KernelPT)
 
BOOLEAN MempSetupPaging (IN PFN_NUMBER StartPage, IN PFN_COUNT NumberOfPages, IN BOOLEAN KernelMapping)
 
VOID MempUnmapPage (PFN_NUMBER Page)
 
static VOID WinLdrpMapApic (VOID)
 
static BOOLEAN WinLdrMapSpecialPages (void)
 
static void WinLdrSetupSpecialDataPointers (VOID)
 
void WinLdrSetupMachineDependent (PLOADER_PARAMETER_BLOCK LoaderBlock)
 
VOID WinLdrSetProcessorContext (_In_ USHORT OperatingSystemVersion)
 

Variables

PHARDWARE_PTE PDE
 
PHARDWARE_PTE HalPageTable
 
PUCHAR PhysicalPageTablesBuffer
 
PUCHAR KernelPageTablesBuffer
 
ULONG PhysicalPageTables
 
ULONG KernelPageTables
 
ULONG PcrBasePage
 
ULONG TssBasePage
 
PVOID GdtIdt
 

Macro Definition Documentation

◆ DESCRIPTOR_ACCESSED

#define DESCRIPTOR_ACCESSED   0x1

Definition at line 58 of file winldr.c.

◆ DESCRIPTOR_CODE

#define DESCRIPTOR_CODE   0x8

Definition at line 63 of file winldr.c.

◆ DESCRIPTOR_CONFORMING

#define DESCRIPTOR_CONFORMING   0x4

Definition at line 62 of file winldr.c.

◆ DESCRIPTOR_EXECUTE_READ

#define DESCRIPTOR_EXECUTE_READ   0x2

Definition at line 60 of file winldr.c.

◆ DESCRIPTOR_EXPAND_DOWN

#define DESCRIPTOR_EXPAND_DOWN   0x4

Definition at line 61 of file winldr.c.

◆ DESCRIPTOR_READ_WRITE

#define DESCRIPTOR_READ_WRITE   0x2

Definition at line 59 of file winldr.c.

◆ DPL_SYSTEM

#define DPL_SYSTEM   0

Definition at line 39 of file winldr.c.

◆ DPL_USER

#define DPL_USER   3

Definition at line 40 of file winldr.c.

◆ ExtendedBIOSDataArea

#define ExtendedBIOSDataArea   ((PULONG)0x740)

Definition at line 346 of file winldr.c.

◆ ExtendedBIOSDataSize

#define ExtendedBIOSDataSize   ((PULONG)0x744)

Definition at line 347 of file winldr.c.

◆ KIP0PCRADDRESS

#define KIP0PCRADDRESS   0xffdff000

Definition at line 21 of file winldr.c.

◆ RomFontPointers

#define RomFontPointers   ((PULONG)0x700)

Definition at line 348 of file winldr.c.

◆ SELFMAP_ENTRY

#define SELFMAP_ENTRY   0x300

Definition at line 23 of file winldr.c.

◆ TYPE_CALL16

#define TYPE_CALL16   0x04

Definition at line 45 of file winldr.c.

◆ TYPE_CALL32

#define TYPE_CALL32   0x0C

Definition at line 53 of file winldr.c.

◆ TYPE_CODE

#define TYPE_CODE   (0x10 | DESCRIPTOR_CODE | DESCRIPTOR_EXECUTE_READ)

Definition at line 65 of file winldr.c.

◆ TYPE_DATA

#define TYPE_DATA   (0x10 | DESCRIPTOR_READ_WRITE)

Definition at line 66 of file winldr.c.

◆ TYPE_INT16

#define TYPE_INT16   0x06

Definition at line 47 of file winldr.c.

◆ TYPE_INT32

#define TYPE_INT32   0x0E

Definition at line 55 of file winldr.c.

◆ TYPE_LDT

#define TYPE_LDT   0x02

Definition at line 43 of file winldr.c.

◆ TYPE_TASK

#define TYPE_TASK   0x05

Definition at line 46 of file winldr.c.

◆ TYPE_TRAP16

#define TYPE_TRAP16   0x07

Definition at line 48 of file winldr.c.

◆ TYPE_TRAP32

#define TYPE_TRAP32   0x0F

Definition at line 56 of file winldr.c.

◆ TYPE_TSS16A

#define TYPE_TSS16A   0x01

Definition at line 42 of file winldr.c.

◆ TYPE_TSS16B

#define TYPE_TSS16B   0x03

Definition at line 44 of file winldr.c.

◆ TYPE_TSS32A

#define TYPE_TSS32A   0x09

Definition at line 50 of file winldr.c.

◆ TYPE_TSS32B

#define TYPE_TSS32B   0x0B

Definition at line 52 of file winldr.c.

Function Documentation

◆ DBG_DEFAULT_CHANNEL()

DBG_DEFAULT_CHANNEL ( WINDOWS  )

◆ MempAllocatePageTables()

static BOOLEAN MempAllocatePageTables ( VOID  )
static

Definition at line 111 of file winldr.c.

112{
113 ULONG NumPageTables, TotalSize;
115 // It's better to allocate PDE + PTEs contiguous
116
117 // Max number of entries = MaxPageNum >> 10
118 // FIXME: This is a number to describe ALL physical memory
119 // and windows doesn't expect ALL memory mapped...
120 NumPageTables = TotalPagesInLookupTable >> 10;
121
122 TRACE("NumPageTables = %d\n", NumPageTables);
123
124 // Allocate memory block for all these things:
125 // PDE, HAL mapping page table, physical mapping, kernel mapping
126 TotalSize = (1 + 1 + NumPageTables * 2) * MM_PAGE_SIZE;
127
128 // PDE+HAL+KernelPTEs == MemoryData
130
131 // Physical PTEs = FirmwareTemporary
132 PhysicalPageTablesBuffer = (PUCHAR)Buffer + TotalSize - NumPageTables*MM_PAGE_SIZE;
134 NumPageTables*MM_PAGE_SIZE,
136
137 // This check is now redundant
138 if (Buffer + (TotalSize - NumPageTables*MM_PAGE_SIZE) !=
140 {
141 TRACE("There was a problem allocating two adjacent blocks of memory!\n");
142 }
143
145 {
146 UiMessageBox("Impossible to allocate memory block for page tables!");
147 return FALSE;
148 }
149
150 // Zero all this memory block
151 RtlZeroMemory(Buffer, TotalSize);
152
153 // Set up pointers correctly now
155
156 // Map the page directory at 0xC0000000 (maps itself)
157 PDE[SELFMAP_ENTRY].PageFrameNumber = (ULONG)PDE >> MM_PAGE_SHIFT;
160
161 // The last PDE slot is allocated for HAL's memory mapping (Virtual Addresses 0xFFC00000 - 0xFFFFFFFF)
162 HalPageTable = (PHARDWARE_PTE)&Buffer[MM_PAGE_SIZE*1];
163
164 // Map it
165 PDE[1023].PageFrameNumber = (ULONG)HalPageTable >> MM_PAGE_SHIFT;
166 PDE[1023].Valid = 1;
167 PDE[1023].Write = 1;
168
169 // Store pointer to the table for easier access
170 KernelPageTablesBuffer = &Buffer[MM_PAGE_SIZE*2];
171
172 // Zero counters of page tables used
175
176 return TRUE;
177}
PUCHAR KernelPageTablesBuffer
Definition: winldr.c:99
#define SELFMAP_ENTRY
Definition: winldr.c:23
PHARDWARE_PTE PDE
Definition: winldr.c:95
ULONG KernelPageTables
Definition: winldr.c:101
PUCHAR PhysicalPageTablesBuffer
Definition: winldr.c:98
PHARDWARE_PTE HalPageTable
Definition: winldr.c:96
ULONG PhysicalPageTables
Definition: winldr.c:100
VOID MmSetMemoryType(PVOID MemoryAddress, SIZE_T MemorySize, TYPE_OF_MEMORY NewType)
Definition: mm.c:144
PVOID MmAllocateMemoryWithType(SIZE_T MemorySize, TYPE_OF_MEMORY MemoryType)
Definition: mm.c:31
PFN_NUMBER TotalPagesInLookupTable
Definition: meminit.c:27
VOID UiMessageBox(_In_ PCSTR Format,...)
Definition: ui.c:359
Definition: bufpool.h:45
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define PHARDWARE_PTE
Definition: mmtypes.h:187
@ LoaderMemoryData
Definition: arc.h:194
@ LoaderFirmwareTemporary
Definition: arc.h:179
#define TRACE(s)
Definition: solgame.cpp:4
ULONG64 PageFrameNumber
Definition: mmtypes.h:78
ULONG64 Write
Definition: mmtypes.h:67
ULONG64 Valid
Definition: mmtypes.h:66
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59

◆ MempAllocatePTE()

static VOID MempAllocatePTE ( ULONG  Entry,
PHARDWARE_PTE PhysicalPT,
PHARDWARE_PTE KernelPT 
)
static

Definition at line 181 of file winldr.c.

182{
183 //TRACE("Creating PDE Entry %X\n", Entry);
184
185 // Identity mapping
186 *PhysicalPT = (PHARDWARE_PTE)&PhysicalPageTablesBuffer[PhysicalPageTables*MM_PAGE_SIZE];
188
189 PDE[Entry].PageFrameNumber = (ULONG)*PhysicalPT >> MM_PAGE_SHIFT;
190 PDE[Entry].Valid = 1;
191 PDE[Entry].Write = 1;
192
193 if (Entry+(KSEG0_BASE >> 22) > 1023)
194 {
195 TRACE("WARNING! Entry: %X > 1023\n", Entry+(KSEG0_BASE >> 22));
196 }
197
198 // Kernel-mode mapping
199 *KernelPT = (PHARDWARE_PTE)&KernelPageTablesBuffer[KernelPageTables*MM_PAGE_SIZE];
201
202 PDE[Entry+(KSEG0_BASE >> 22)].PageFrameNumber = ((ULONG)*KernelPT >> MM_PAGE_SHIFT);
203 PDE[Entry+(KSEG0_BASE >> 22)].Valid = 1;
204 PDE[Entry+(KSEG0_BASE >> 22)].Write = 1;
205}
#define KSEG0_BASE
Definition: ketypes.h:354
base of all file and directory entries
Definition: entries.h:83
static BOOL Write(PBYTE Address, PBYTE Data, SIZE_T Size)
Definition: vmhorizon.c:15

Referenced by MempSetupPaging().

◆ MempSetupPaging()

BOOLEAN MempSetupPaging ( IN PFN_NUMBER  StartPage,
IN PFN_COUNT  NumberOfPages,
IN BOOLEAN  KernelMapping 
)

Definition at line 208 of file winldr.c.

211{
212 PHARDWARE_PTE PhysicalPT;
213 PHARDWARE_PTE KernelPT;
215
216 TRACE("MempSetupPaging: SP 0x%X, Number: 0x%X, Kernel: %s\n",
217 StartPage, NumberOfPages, KernelMapping ? "yes" : "no");
218
219 // HACK
220 if (StartPage+NumberOfPages >= 0x80000)
221 {
222 //
223 // We cannot map this as it requires more than 1 PDE
224 // and in fact it's not possible at all ;)
225 //
226 //TRACE("skipping...\n");
227 return TRUE;
228 }
229
230 //
231 // Now actually set up the page tables for identity mapping
232 //
233 for (Page = StartPage; Page < StartPage + NumberOfPages; Page++)
234 {
235 Entry = Page >> 10;
236
237 if (((PULONG)PDE)[Entry] == 0)
238 {
239 MempAllocatePTE(Entry, &PhysicalPT, &KernelPT);
240 }
241 else
242 {
243 PhysicalPT = (PHARDWARE_PTE)(PDE[Entry].PageFrameNumber << MM_PAGE_SHIFT);
244 KernelPT = (PHARDWARE_PTE)(PDE[Entry+(KSEG0_BASE >> 22)].PageFrameNumber << MM_PAGE_SHIFT);
245 }
246
247 PhysicalPT[Page & 0x3ff].PageFrameNumber = Page;
248 PhysicalPT[Page & 0x3ff].Valid = 1;
249 PhysicalPT[Page & 0x3ff].Write = (Page != 0);
250
251 if (KernelMapping)
252 {
253 if (KernelPT[Page & 0x3ff].Valid) WARN("KernelPT already mapped\n");
254 KernelPT[Page & 0x3ff].PageFrameNumber = Page;
255 KernelPT[Page & 0x3ff].Valid = (Page != 0);
256 KernelPT[Page & 0x3ff].Write = (Page != 0);
257 }
258 }
259
260 return TRUE;
261}
static VOID MempAllocatePTE(ULONG Entry, PHARDWARE_PTE *PhysicalPT, PHARDWARE_PTE *KernelPT)
Definition: winldr.c:181
#define WARN(fmt,...)
Definition: debug.h:112
_In_ PVOID _Out_opt_ BOOLEAN _Out_opt_ PPFN_NUMBER Page
Definition: mm.h:1306
uint32_t * PULONG
Definition: typedefs.h:59
int WINAPI StartPage(_In_ HDC)
ULONG PFN_COUNT
Definition: mmtypes.h:102

◆ MempUnmapPage()

VOID MempUnmapPage ( PFN_NUMBER  Page)

Definition at line 264 of file winldr.c.

265{
266 PHARDWARE_PTE KernelPT;
267 PFN_NUMBER Entry = (Page >> 10) + (KSEG0_BASE >> 22);
268
269 /* Don't unmap page directory or HAL entries */
270 if (Entry == SELFMAP_ENTRY || Entry == 1023)
271 return;
272
273 if (PDE[Entry].Valid)
274 {
275 KernelPT = (PHARDWARE_PTE)(PDE[Entry].PageFrameNumber << MM_PAGE_SHIFT);
276
277 if (KernelPT)
278 {
279 KernelPT[Page & 0x3ff].PageFrameNumber = 0;
280 KernelPT[Page & 0x3ff].Valid = 0;
281 KernelPT[Page & 0x3ff].Write = 0;
282 }
283 }
284}
ULONG PFN_NUMBER
Definition: ke.h:9

◆ WinLdrMapSpecialPages()

static BOOLEAN WinLdrMapSpecialPages ( void  )
static

Definition at line 320 of file winldr.c.

321{
322 TRACE("HalPageTable: 0x%X\n", HalPageTable);
323
324 /*
325 * The Page Tables have been setup, make special handling
326 * for the boot processor PCR and KI_USER_SHARED_DATA.
327 */
328 HalPageTable[(KI_USER_SHARED_DATA - 0xFFC00000) >> MM_PAGE_SHIFT].PageFrameNumber = PcrBasePage+1;
329 HalPageTable[(KI_USER_SHARED_DATA - 0xFFC00000) >> MM_PAGE_SHIFT].Valid = 1;
330 HalPageTable[(KI_USER_SHARED_DATA - 0xFFC00000) >> MM_PAGE_SHIFT].Write = 1;
331
332 HalPageTable[(KIP0PCRADDRESS - 0xFFC00000) >> MM_PAGE_SHIFT].PageFrameNumber = PcrBasePage;
333 HalPageTable[(KIP0PCRADDRESS - 0xFFC00000) >> MM_PAGE_SHIFT].Valid = 1;
334 HalPageTable[(KIP0PCRADDRESS - 0xFFC00000) >> MM_PAGE_SHIFT].Write = 1;
335
336 /* Map APIC */
338
339 /* Map VGA memory */
340 //VideoMemoryBase = MmMapIoSpace(0xb8000, 4000, MmNonCached);
341 //TRACE("VideoMemoryBase: 0x%X\n", VideoMemoryBase);
342
343 return TRUE;
344}
#define KIP0PCRADDRESS
Definition: amd64.h:27
static VOID WinLdrpMapApic(VOID)
Definition: winldr.c:212
ULONG_PTR PcrBasePage
Definition: winldr.c:27
#define KI_USER_SHARED_DATA

Referenced by WinLdrSetupMachineDependent().

◆ WinLdrpMapApic()

static VOID WinLdrpMapApic ( VOID  )
static

Definition at line 288 of file winldr.c.

289{
290 BOOLEAN LocalAPIC;
291 LARGE_INTEGER MsrValue;
292 ULONG APICAddress, CpuInfo[4];
293
294 /* Check if we have a local APIC */
295 __cpuid((int*)CpuInfo, 1);
296 LocalAPIC = (((CpuInfo[3] >> 9) & 1) != 0);
297
298 /* If there is no APIC, just return */
299 if (!LocalAPIC)
300 return;
301
302 /* Read the APIC Address */
303 MsrValue.QuadPart = __readmsr(0x1B);
304 APICAddress = (MsrValue.LowPart & 0xFFFFF000);
305
306 TRACE("Local APIC detected at address 0x%x\n",
307 APICAddress);
308
309 /* Map it */
310 HalPageTable[(APIC_BASE - 0xFFC00000) >> MM_PAGE_SHIFT].PageFrameNumber
311 = APICAddress >> MM_PAGE_SHIFT;
312 HalPageTable[(APIC_BASE - 0xFFC00000) >> MM_PAGE_SHIFT].Valid = 1;
313 HalPageTable[(APIC_BASE - 0xFFC00000) >> MM_PAGE_SHIFT].Write = 1;
314 HalPageTable[(APIC_BASE - 0xFFC00000) >> MM_PAGE_SHIFT].WriteThrough = 1;
315 HalPageTable[(APIC_BASE - 0xFFC00000) >> MM_PAGE_SHIFT].CacheDisable = 1;
316}
unsigned char BOOLEAN
PPC_QUAL void __cpuid(int CPUInfo[], const int InfoType)
Definition: intrin_ppc.h:682
PPC_QUAL unsigned long long __readmsr()
Definition: intrin_ppc.h:741
#define APIC_BASE
Definition: ketypes.h:339
LONGLONG QuadPart
Definition: typedefs.h:114
ULONG LowPart
Definition: typedefs.h:106

◆ WinLdrSetProcessorContext()

VOID WinLdrSetProcessorContext ( _In_ USHORT  OperatingSystemVersion)

Definition at line 432 of file winldr.c.

434{
435 GDTIDT GdtDesc, IdtDesc, OldIdt;
436 PKGDTENTRY pGdt;
437 PKIDTENTRY pIdt;
438 USHORT Ldt = 0;
439 ULONG Pcr;
440 ULONG Tss;
441 //ULONG i;
442
443 Pcr = KIP0PCRADDRESS;
444 Tss = KSEG0_BASE | (TssBasePage << MM_PAGE_SHIFT);
445
446 TRACE("GdtIdt %p, Pcr %p, Tss 0x%08x\n",
447 GdtIdt, Pcr, Tss);
448
449 /* Enable paging */
450 //BS->ExitBootServices(ImageHandle,MapKey);
451
452 /* Disable Interrupts */
453 _disable();
454
455 /* Re-initialize EFLAGS */
456 __writeeflags(0);
457
458 /* Set the PDBR */
460
461 /* Enable paging by modifying CR0 */
463
464 /* The Kernel expects the boot processor PCR to be zero-filled on startup */
465 RtlZeroMemory((PVOID)Pcr, MM_PAGE_SIZE);
466
467 /* Get old values of GDT and IDT */
469 __sidt(&IdtDesc);
470
471 /* Save old IDT */
472 OldIdt.Base = IdtDesc.Base;
473 OldIdt.Limit = IdtDesc.Limit;
474
475 /* Prepare new IDT+GDT */
476 GdtDesc.Base = KSEG0_BASE | (ULONG_PTR)GdtIdt;
477 GdtDesc.Limit = NUM_GDT * sizeof(KGDTENTRY) - 1;
478 IdtDesc.Base = (ULONG)((PUCHAR)GdtDesc.Base + GdtDesc.Limit + 1);
479 IdtDesc.Limit = NUM_IDT * sizeof(KIDTENTRY) - 1;
480
481 // ========================
482 // Fill all descriptors now
483 // ========================
484
485 pGdt = (PKGDTENTRY)GdtDesc.Base;
486 pIdt = (PKIDTENTRY)IdtDesc.Base;
487
488 /* KGDT_NULL (0x00) Null Selector - Unused */
489 KiSetGdtEntry(KiGetGdtEntry(pGdt, KGDT_NULL), 0x0000, 0, 0, DPL_SYSTEM, 0);
490 // DumpGDTEntry(GdtDesc.Base, KGDT_NULL);
491
492 /* KGDT_R0_CODE (0x08) Ring 0 Code selector - Flat 4Gb */
493 KiSetGdtEntry(KiGetGdtEntry(pGdt, KGDT_R0_CODE), 0x0000, 0xFFFFFFFF,
495 // DumpGDTEntry(GdtDesc.Base, KGDT_R0_CODE);
496
497 /* KGDT_R0_DATA (0x10) Ring 0 Data selector - Flat 4Gb */
498 KiSetGdtEntry(KiGetGdtEntry(pGdt, KGDT_R0_DATA), 0x0000, 0xFFFFFFFF,
500 // DumpGDTEntry(GdtDesc.Base, KGDT_R0_DATA);
501
502 /* KGDT_R3_CODE (0x18) Ring 3 Code Selector - Flat 2Gb */
503 KiSetGdtEntry(KiGetGdtEntry(pGdt, KGDT_R3_CODE), 0x0000, 0xFFFFFFFF,
504 TYPE_CODE, DPL_USER, 2);
505 // DumpGDTEntry(GdtDesc.Base, KGDT_R3_CODE);
506
507 /* KGDT_R3_DATA (0x20) Ring 3 Data Selector - Flat 2Gb */
508 KiSetGdtEntry(KiGetGdtEntry(pGdt, KGDT_R3_DATA), 0x0000, 0xFFFFFFFF,
509 TYPE_DATA, DPL_USER, 2);
510 // DumpGDTEntry(GdtDesc.Base, KGDT_R3_DATA);
511
512 /* KGDT_TSS (0x28) TSS Selector (Ring 0) */
514 0x78-1 /* FIXME: Check this; would be sizeof(KTSS)-1 */,
516 // DumpGDTEntry(GdtDesc.Base, KGDT_TSS);
517
518 /*
519 * KGDT_R0_PCR (0x30) PCR Selector (Ring 0)
520 *
521 * IMPORTANT COMPATIBILITY NOTE:
522 * Windows <= Server 2003 sets a Base == KIP0PCRADDRESS (0xffdff000 on x86)
523 * with a Limit of 1 page (LimitLow == 1, Granularity == 1, that is interpreted
524 * as a "Limit" == 0x1fff but is incorrect, of course).
525 * On Windows Longhorn/Vista+ however, the Base is not hardcoded to KIP0PCRADDRESS
526 * and the limit is set in bytes (Granularity == 0):
527 * Longhorn/Vista reports LimitLow == 0x0fff == MM_PAGE_SIZE - 1, whereas
528 * Windows 7+ uses larger sizes there (not aligned on a page boundary).
529 */
530 if (OperatingSystemVersion < _WIN32_WINNT_VISTA)
531 {
532 /* Server 2003 way */
535 }
536 else
537 {
538 /* Vista+ way */
539 KiSetGdtEntry(KiGetGdtEntry(pGdt, KGDT_R0_PCR), (ULONG32)Pcr, MM_PAGE_SIZE - 1,
541 }
542
543 // DumpGDTEntry(GdtDesc.Base, KGDT_R0_PCR);
544
545 /* KGDT_R3_TEB (0x38) Thread Environment Block Selector (Ring 3) */
546 KiSetGdtEntry(KiGetGdtEntry(pGdt, KGDT_R3_TEB), 0x0000, 0x0FFF,
548 // DumpGDTEntry(GdtDesc.Base, KGDT_R3_TEB);
549
550 /* KGDT_VDM_TILE (0x40) VDM BIOS Data Area Selector (Ring 3) */
551 KiSetGdtEntry(KiGetGdtEntry(pGdt, KGDT_VDM_TILE), 0x0400, 0xFFFF,
552 TYPE_DATA, DPL_USER, 0);
553 // DumpGDTEntry(GdtDesc.Base, KGDT_VDM_TILE);
554
555 /* KGDT_LDT (0x48) LDT Selector (Reserved) */
556 KiSetGdtEntry(KiGetGdtEntry(pGdt, KGDT_LDT), 0x0000, 0, 0, DPL_SYSTEM, 0);
557 // DumpGDTEntry(GdtDesc.Base, KGDT_LDT);
558
559 /* KGDT_DF_TSS (0x50) Double-Fault Task Switch Selector (Ring 0) */
560 KiSetGdtEntry(KiGetGdtEntry(pGdt, KGDT_DF_TSS), 0x20000 /* FIXME: Not correct! */,
561 0xFFFF /* FIXME: Not correct! */,
563 // DumpGDTEntry(GdtDesc.Base, KGDT_DF_TSS);
564
565 /* KGDT_NMI_TSS (0x58) NMI Task Switch Selector (Ring 0) */
566 KiSetGdtEntry(KiGetGdtEntry(pGdt, KGDT_NMI_TSS), 0x20000, 0xFFFF,
568 // DumpGDTEntry(GdtDesc.Base, KGDT_NMI_TSS);
569
570 /* Selector (0x60) - Unused (Reserved) on Windows Longhorn/Vista+ */
571 KiSetGdtEntry(KiGetGdtEntry(pGdt, 0x60), 0x20000 /* FIXME: Maybe not correct, but noone cares */,
572 0xFFFF, TYPE_DATA, DPL_SYSTEM, 0);
573 // DumpGDTEntry(GdtDesc.Base, 0x60);
574
575 /* Video Display Buffer Selector (0x68) - Unused (Reserved) on Windows Longhorn/Vista+ */
576 KiSetGdtEntry(KiGetGdtEntry(pGdt, 0x68), 0xB8000, 0x3FFF,
578 // DumpGDTEntry(GdtDesc.Base, 0x68);
579
580 /*
581 * GDT Alias Selector (points to GDT) (0x70)
582 *
583 * IMPORTANT COMPATIBILITY NOTE:
584 * The Base is not fixed to 0xFFFF7000 on Windows Longhorn/Vista+.
585 */
586 KiSetGdtEntry(KiGetGdtEntry(pGdt, 0x70), 0xFFFF7000 /* GdtDesc.Base ?? */, GdtDesc.Limit,
588 // DumpGDTEntry(GdtDesc.Base, 0x70);
589
590 /*
591 * Windows <= Server 2003 defines three additional unused but valid
592 * descriptors there, possibly for debugging purposes only.
593 * They are not present on Windows Longhorn/Vista+.
594 */
595 // KiSetGdtEntry(KiGetGdtEntry(pGdt, 0x78), 0x80400000, 0xffff, TYPE_CODE, DPL_SYSTEM, 0);
596 // KiSetGdtEntry(KiGetGdtEntry(pGdt, 0x80), 0x80400000, 0xffff, TYPE_DATA, DPL_SYSTEM, 0);
597 // KiSetGdtEntry(KiGetGdtEntry(pGdt, 0x88), 0x0000, 0, TYPE_DATA, DPL_SYSTEM, 0);
598
599 /* Copy the old IDT */
600 RtlCopyMemory(pIdt, (PVOID)OldIdt.Base, OldIdt.Limit + 1);
601
602 /* Mask interrupts */
603 //asm("cli\n"); // they are already masked before enabling paged mode
604
605 /* Load GDT+IDT */
607 __lidt(&IdtDesc);
608
609 /* Jump to proper CS and clear prefetch queue */
610#if defined(__GNUC__) || defined(__clang__)
611 asm("ljmp $0x08, $1f\n"
612 "1:\n");
613#elif defined(_MSC_VER)
614 /* We cannot express the above in MASM so we use this far return instead */
615 __asm
616 {
617 push 8
618 push offset resume
619 retf
620 resume:
621 };
622#else
623#error
624#endif
625
626 /* Set SS selector */
627 Ke386SetSs(KGDT_R0_DATA);
628
629 /* Set DS and ES selectors */
630 Ke386SetDs(KGDT_R0_DATA);
631 Ke386SetEs(KGDT_R0_DATA); // This is vital for rep stosd
632
633 /* LDT = not used ever, thus set to 0 */
634 Ke386SetLocalDescriptorTable(Ldt);
635
636 /* Load TSR */
637 Ke386SetTr(KGDT_TSS);
638
639 /* Clear GS */
640 Ke386SetGs(0);
641
642 /* Set FS to PCR */
643 Ke386SetFs(KGDT_R0_PCR);
644
645 // Real end of the function, just for information
646 /* do not uncomment!
647 pop edi;
648 pop esi;
649 pop ebx;
650 mov esp, ebp;
651 pop ebp;
652 ret
653 */
654}
FORCEINLINE PKGDTENTRY64 KiGetGdtEntry(PVOID pGdt, USHORT Selector)
Definition: intrin_i.h:13
PVOID GdtIdt
Definition: winldr.c:26
ULONG_PTR TssBasePage
Definition: winldr.c:28
#define TYPE_CODE
Definition: winldr.c:65
#define DPL_USER
Definition: winldr.c:40
#define TYPE_DATA
Definition: winldr.c:66
#define DPL_SYSTEM
Definition: winldr.c:39
#define DESCRIPTOR_ACCESSED
Definition: winldr.c:58
#define TYPE_TSS32A
Definition: winldr.c:50
unsigned int ULONG32
Definition: basetsd.h:123
#define ULONG_PTR
Definition: config.h:101
GLintptr offset
Definition: glext.h:5920
#define Ke386GetGlobalDescriptorTable
Definition: intrin_i.h:452
#define Ke386SetGlobalDescriptorTable
Definition: intrin_i.h:453
FORCEINLINE VOID KiSetGdtEntryEx(_Inout_ PKGDTENTRY Entry, _In_ ULONG32 Base, _In_ ULONG Limit, _In_ UCHAR Type, _In_ UCHAR Dpl, _In_ BOOLEAN Granularity, _In_ UCHAR SegMode)
Definition: intrin_i.h:50
FORCEINLINE VOID KiSetGdtEntry(_Inout_ PKGDTENTRY Entry, _In_ ULONG32 Base, _In_ ULONG Limit, _In_ UCHAR Type, _In_ UCHAR Dpl, _In_ UCHAR SegMode)
Definition: intrin_i.h:73
void __cdecl _disable(void)
Definition: intrin_arm.h:365
__INTRIN_INLINE void __writeeflags(uintptr_t Value)
Definition: intrin_x86.h:1669
__INTRIN_INLINE void __lidt(void *Source)
Definition: intrin_x86.h:2018
__INTRIN_INLINE unsigned long __readcr0(void)
Definition: intrin_x86.h:1804
__INTRIN_INLINE void __writecr3(unsigned int Data)
Definition: intrin_x86.h:1794
__INTRIN_INLINE void __writecr0(unsigned int Data)
Definition: intrin_x86.h:1789
__INTRIN_INLINE void __sidt(void *Destination)
Definition: intrin_x86.h:2023
#define CR0_PG
Definition: asm.h:255
#define KIDTENTRY
Definition: ketypes.h:564
#define PKGDTENTRY
Definition: ketypes.h:523
#define KGDTENTRY
Definition: ketypes.h:522
#define KGDT_R3_DATA
Definition: ketypes.h:126
#define KGDT_R3_CODE
Definition: ketypes.h:125
#define KGDT_NMI_TSS
Definition: ketypes.h:133
#define KGDT_R3_TEB
Definition: ketypes.h:129
#define KGDT_TSS
Definition: ketypes.h:127
#define KGDT_R0_PCR
Definition: ketypes.h:128
#define KGDT_LDT
Definition: ketypes.h:131
#define KGDT_DF_TSS
Definition: ketypes.h:132
#define KGDT_R0_CODE
Definition: ketypes.h:123
#define KGDT_VDM_TILE
Definition: ketypes.h:130
#define KGDT_R0_DATA
Definition: ketypes.h:124
#define KGDT_NULL
Definition: ketypes.h:122
#define NUM_IDT
Definition: winldr.h:17
#define NUM_GDT
Definition: winldr.h:16
unsigned short USHORT
Definition: pedump.c:61
static void push(calc_node_t *op)
Definition: rpn_ieee.c:113
#define _WIN32_WINNT_VISTA
Definition: sdkddkver.h:25
Definition: winldr.c:28
USHORT Limit
Definition: winldr.c:29
ULONG Base
Definition: winldr.c:30
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG_PTR
Definition: typedefs.h:65

◆ WinLdrSetupMachineDependent()

void WinLdrSetupMachineDependent ( PLOADER_PARAMETER_BLOCK  LoaderBlock)

Definition at line 371 of file winldr.c.

372{
373 ULONG TssSize;
374 //ULONG TssPages;
375 ULONG_PTR Pcr = 0;
376 ULONG_PTR Tss = 0;
377 ULONG BlockSize, NumPages;
378
379 LoaderBlock->u.I386.CommonDataArea = NULL; // Force No ABIOS support
380 LoaderBlock->u.I386.MachineType = MACHINE_TYPE_ISA;
381
382 /* Allocate 2 pages for PCR: one for the boot processor PCR and one for KI_USER_SHARED_DATA */
384 PcrBasePage = Pcr >> MM_PAGE_SHIFT;
385 if (Pcr == 0)
386 {
387 UiMessageBox("Could not allocate PCR.");
388 return;
389 }
390
391 /* Allocate TSS */
392 TssSize = (sizeof(KTSS) + MM_PAGE_SIZE) & ~(MM_PAGE_SIZE - 1);
393 //TssPages = TssSize / MM_PAGE_SIZE;
394
396 TssBasePage = Tss >> MM_PAGE_SHIFT;
397 if (Tss == 0)
398 {
399 UiMessageBox("Could not allocate TSS.");
400 return;
401 }
402
403 /* Allocate space for new GDT + IDT */
404 BlockSize = NUM_GDT*sizeof(KGDTENTRY) + NUM_IDT*sizeof(KIDTENTRY);//FIXME: Use GDT/IDT limits here?
405 NumPages = (BlockSize + MM_PAGE_SIZE - 1) >> MM_PAGE_SHIFT;
406 GdtIdt = (PKGDTENTRY)MmAllocateMemoryWithType(NumPages * MM_PAGE_SIZE, LoaderMemoryData);
407 if (GdtIdt == NULL)
408 {
409 UiMessageBox("Could not allocate pages for GDT+IDT!");
410 return;
411 }
412
413 /* Zero newly prepared GDT+IDT */
414 RtlZeroMemory(GdtIdt, NumPages << MM_PAGE_SHIFT);
415
416 // Before we start mapping pages, create a block of memory, which will contain
417 // PDE and PTEs
419 {
420 BugCheck("MempAllocatePageTables failed!\n");
421 }
422
423 /* Map stuff like PCR, KI_USER_SHARED_DATA and Apic */
425
426 /* Set some special fields */
428}
static BOOLEAN MempAllocatePageTables(VOID)
Definition: winldr.c:34
static void WinLdrSetupSpecialDataPointers(VOID)
Definition: winldr.c:351
static BOOLEAN WinLdrMapSpecialPages(void)
Definition: winldr.c:320
#define BugCheck(fmt,...)
Definition: debug.h:118
#define KTSS
Definition: ketypes.h:1006
#define MACHINE_TYPE_ISA
Definition: ketypes.h:113
@ LoaderStartupPcrPage
Definition: arc.h:191
ULONG MachineType
Definition: arc.h:454
PVOID CommonDataArea
Definition: arc.h:453
union _LOADER_PARAMETER_BLOCK::@3379 u
I386_LOADER_BLOCK I386
Definition: arc.h:562

◆ WinLdrSetupSpecialDataPointers()

static void WinLdrSetupSpecialDataPointers ( VOID  )
static

Definition at line 351 of file winldr.c.

352{
353 /* Get the address of the BIOS ROM fonts. Win 2003 videoprt reads these
354 values from address 0x700 .. 0x718 and store them in the registry
355 in HKLM\System\CurrentControlSet\Control\Wow\RomFontPointers */
357
358 /* Store address of the extended BIOS data area in 0x740 */
360
362 {
363 WARN("Couldn't get address of extended BIOS data area\n");
364 }
365 else
366 {
367 TRACE("*ExtendedBIOSDataArea = 0x%lx\n", *ExtendedBIOSDataArea);
368 }
369}
#define RomFontPointers
Definition: winldr.c:348
#define ExtendedBIOSDataArea
Definition: winldr.c:346
#define ExtendedBIOSDataSize
Definition: winldr.c:347
#define MachGetExtendedBIOSData(ExtendedBIOSDataArea, ExtendedBIOSDataSize)
Definition: machine.h:122
#define MachVideoGetFontsFromFirmware(RomFontPointers)
Definition: machine.h:100

Referenced by WinLdrSetupMachineDependent().

Variable Documentation

◆ GdtIdt

PVOID GdtIdt

Definition at line 105 of file winldr.c.

◆ HalPageTable

PHARDWARE_PTE HalPageTable

Definition at line 96 of file winldr.c.

Referenced by MempAllocatePageTables(), WinLdrMapSpecialPages(), and WinLdrpMapApic().

◆ KernelPageTables

ULONG KernelPageTables

Definition at line 101 of file winldr.c.

Referenced by MempAllocatePageTables(), and MempAllocatePTE().

◆ KernelPageTablesBuffer

PUCHAR KernelPageTablesBuffer

Definition at line 99 of file winldr.c.

Referenced by MempAllocatePageTables(), and MempAllocatePTE().

◆ PcrBasePage

ULONG PcrBasePage

Definition at line 103 of file winldr.c.

◆ PDE

◆ PhysicalPageTables

ULONG PhysicalPageTables

Definition at line 100 of file winldr.c.

Referenced by MempAllocatePageTables(), and MempAllocatePTE().

◆ PhysicalPageTablesBuffer

PUCHAR PhysicalPageTablesBuffer

Definition at line 98 of file winldr.c.

Referenced by MempAllocatePageTables(), and MempAllocatePTE().

◆ TssBasePage

ULONG TssBasePage

Definition at line 104 of file winldr.c.