Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenwinldr.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: EFI Windows Loader 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: freeldr/winldr/i386/wlmemory.c 00005 * PURPOSE: Memory related routines 00006 * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org) 00007 */ 00008 00009 /* INCLUDES ***************************************************************/ 00010 00011 #include <freeldr.h> 00012 00013 #include <ndk/asm.h> 00014 #include <debug.h> 00015 00016 // This is needed because headers define wrong one for ReactOS 00017 #undef KIP0PCRADDRESS 00018 #define KIP0PCRADDRESS 0xffdff000 00019 00020 #define HYPER_SPACE_ENTRY 0x300 00021 00022 // This is needed only for SetProcessorContext routine 00023 #pragma pack(2) 00024 typedef struct 00025 { 00026 USHORT Limit; 00027 ULONG Base; 00028 } GDTIDT; 00029 #pragma pack(4) 00030 00031 DBG_DEFAULT_CHANNEL(WINDOWS); 00032 00033 /* GLOBALS ***************************************************************/ 00034 00035 PHARDWARE_PTE PDE; 00036 PHARDWARE_PTE HalPageTable; 00037 00038 PUCHAR PhysicalPageTablesBuffer; 00039 PUCHAR KernelPageTablesBuffer; 00040 ULONG PhysicalPageTables; 00041 ULONG KernelPageTables; 00042 00043 ULONG PcrBasePage; 00044 ULONG TssBasePage; 00045 PVOID GdtIdt; 00046 00047 /* FUNCTIONS **************************************************************/ 00048 00049 BOOLEAN 00050 MempAllocatePageTables() 00051 { 00052 ULONG NumPageTables, TotalSize; 00053 PUCHAR Buffer; 00054 // It's better to allocate PDE + PTEs contigiuos 00055 00056 // Max number of entries = MaxPageNum >> 10 00057 // FIXME: This is a number to describe ALL physical memory 00058 // and windows doesn't expect ALL memory mapped... 00059 NumPageTables = TotalPagesInLookupTable >> 10; 00060 00061 TRACE("NumPageTables = %d\n", NumPageTables); 00062 00063 // Allocate memory block for all these things: 00064 // PDE, HAL mapping page table, physical mapping, kernel mapping 00065 TotalSize = (1 + 1 + NumPageTables * 2) * MM_PAGE_SIZE; 00066 00067 // PDE+HAL+KernelPTEs == MemoryData 00068 Buffer = MmAllocateMemoryWithType(TotalSize, LoaderMemoryData); 00069 00070 // Physical PTEs = FirmwareTemporary 00071 PhysicalPageTablesBuffer = (PUCHAR)Buffer + TotalSize - NumPageTables*MM_PAGE_SIZE; 00072 MmSetMemoryType(PhysicalPageTablesBuffer, 00073 NumPageTables*MM_PAGE_SIZE, 00074 LoaderFirmwareTemporary); 00075 00076 // This check is now redundant 00077 if (Buffer + (TotalSize - NumPageTables*MM_PAGE_SIZE) != 00078 PhysicalPageTablesBuffer) 00079 { 00080 TRACE("There was a problem allocating two adjacent blocks of memory!"); 00081 } 00082 00083 if (Buffer == NULL || PhysicalPageTablesBuffer == NULL) 00084 { 00085 UiMessageBox("Impossible to allocate memory block for page tables!"); 00086 return FALSE; 00087 } 00088 00089 // Zero all this memory block 00090 RtlZeroMemory(Buffer, TotalSize); 00091 00092 // Set up pointers correctly now 00093 PDE = (PHARDWARE_PTE)Buffer; 00094 00095 // Map the page directory at 0xC0000000 (maps itself) 00096 PDE[HYPER_SPACE_ENTRY].PageFrameNumber = (ULONG)PDE >> MM_PAGE_SHIFT; 00097 PDE[HYPER_SPACE_ENTRY].Valid = 1; 00098 PDE[HYPER_SPACE_ENTRY].Write = 1; 00099 00100 // The last PDE slot is allocated for HAL's memory mapping (Virtual Addresses 0xFFC00000 - 0xFFFFFFFF) 00101 HalPageTable = (PHARDWARE_PTE)&Buffer[MM_PAGE_SIZE*1]; 00102 00103 // Map it 00104 PDE[1023].PageFrameNumber = (ULONG)HalPageTable >> MM_PAGE_SHIFT; 00105 PDE[1023].Valid = 1; 00106 PDE[1023].Write = 1; 00107 00108 // Store pointer to the table for easier access 00109 KernelPageTablesBuffer = &Buffer[MM_PAGE_SIZE*2]; 00110 00111 // Zero counters of page tables used 00112 PhysicalPageTables = 0; 00113 KernelPageTables = 0; 00114 00115 return TRUE; 00116 } 00117 00118 VOID 00119 MempAllocatePTE(ULONG Entry, PHARDWARE_PTE *PhysicalPT, PHARDWARE_PTE *KernelPT) 00120 { 00121 //Print(L"Creating PDE Entry %X\n", Entry); 00122 00123 // Identity mapping 00124 *PhysicalPT = (PHARDWARE_PTE)&PhysicalPageTablesBuffer[PhysicalPageTables*MM_PAGE_SIZE]; 00125 PhysicalPageTables++; 00126 00127 PDE[Entry].PageFrameNumber = (ULONG)*PhysicalPT >> MM_PAGE_SHIFT; 00128 PDE[Entry].Valid = 1; 00129 PDE[Entry].Write = 1; 00130 00131 if (Entry+(KSEG0_BASE >> 22) > 1023) 00132 { 00133 TRACE("WARNING! Entry: %X > 1023\n", Entry+(KSEG0_BASE >> 22)); 00134 } 00135 00136 // Kernel-mode mapping 00137 *KernelPT = (PHARDWARE_PTE)&KernelPageTablesBuffer[KernelPageTables*MM_PAGE_SIZE]; 00138 KernelPageTables++; 00139 00140 PDE[Entry+(KSEG0_BASE >> 22)].PageFrameNumber = ((ULONG)*KernelPT >> MM_PAGE_SHIFT); 00141 PDE[Entry+(KSEG0_BASE >> 22)].Valid = 1; 00142 PDE[Entry+(KSEG0_BASE >> 22)].Write = 1; 00143 } 00144 00145 BOOLEAN 00146 MempSetupPaging(IN PFN_NUMBER StartPage, 00147 IN PFN_COUNT NumberOfPages, 00148 IN BOOLEAN KernelMapping) 00149 { 00150 PHARDWARE_PTE PhysicalPT; 00151 PHARDWARE_PTE KernelPT; 00152 PFN_COUNT Entry, Page; 00153 00154 TRACE("MempSetupPaging: SP 0x%X, Number: 0x%X, Kernel: %s\n", 00155 StartPage, NumberOfPages, KernelMapping ? "yes" : "no"); 00156 00157 // HACK 00158 if (StartPage+NumberOfPages >= 0x80000) 00159 { 00160 // 00161 // We can't map this as it requires more than 1 PDE 00162 // and in fact it's not possible at all ;) 00163 // 00164 //Print(L"skipping...\n"); 00165 return TRUE; 00166 } 00167 00168 // 00169 // Now actually set up the page tables for identity mapping 00170 // 00171 for (Page = StartPage; Page < StartPage + NumberOfPages; Page++) 00172 { 00173 Entry = Page >> 10; 00174 00175 if (((PULONG)PDE)[Entry] == 0) 00176 { 00177 MempAllocatePTE(Entry, &PhysicalPT, &KernelPT); 00178 } 00179 else 00180 { 00181 PhysicalPT = (PHARDWARE_PTE)(PDE[Entry].PageFrameNumber << MM_PAGE_SHIFT); 00182 KernelPT = (PHARDWARE_PTE)(PDE[Entry+(KSEG0_BASE >> 22)].PageFrameNumber << MM_PAGE_SHIFT); 00183 } 00184 00185 PhysicalPT[Page & 0x3ff].PageFrameNumber = Page; 00186 PhysicalPT[Page & 0x3ff].Valid = (Page != 0); 00187 PhysicalPT[Page & 0x3ff].Write = (Page != 0); 00188 00189 if (KernelMapping) 00190 { 00191 if (KernelPT[Page & 0x3ff].Valid) WARN("xxx already mapped \n"); 00192 KernelPT[Page & 0x3ff].PageFrameNumber = Page; 00193 KernelPT[Page & 0x3ff].Valid = (Page != 0); 00194 KernelPT[Page & 0x3ff].Write = (Page != 0); 00195 } 00196 } 00197 00198 return TRUE; 00199 } 00200 00201 VOID 00202 MempUnmapPage(PFN_NUMBER Page) 00203 { 00204 PHARDWARE_PTE KernelPT; 00205 PFN_NUMBER Entry = (Page >> 10) + (KSEG0_BASE >> 22); 00206 00207 /* Don't unmap hyperspace or HAL entries */ 00208 if (Entry == HYPER_SPACE_ENTRY || Entry == 1023) 00209 return; 00210 00211 if (PDE[Entry].Valid) 00212 { 00213 KernelPT = (PHARDWARE_PTE)(PDE[Entry].PageFrameNumber << MM_PAGE_SHIFT); 00214 00215 if (KernelPT) 00216 { 00217 KernelPT[Page & 0x3ff].PageFrameNumber = 0; 00218 KernelPT[Page & 0x3ff].Valid = 0; 00219 KernelPT[Page & 0x3ff].Write = 0; 00220 } 00221 } 00222 } 00223 00224 VOID 00225 WinLdrpMapApic() 00226 { 00227 BOOLEAN LocalAPIC; 00228 LARGE_INTEGER MsrValue; 00229 ULONG APICAddress, CpuInfo[4]; 00230 00231 /* Check if we have a local APIC */ 00232 __cpuid((int*)CpuInfo, 1); 00233 LocalAPIC = (((CpuInfo[3] >> 9) & 1) != 0); 00234 00235 /* If there is no APIC, just return */ 00236 if (!LocalAPIC) 00237 return; 00238 00239 /* Read the APIC Address */ 00240 MsrValue.QuadPart = __readmsr(0x1B); 00241 APICAddress = (MsrValue.LowPart & 0xFFFFF000); 00242 00243 TRACE("Local APIC detected at address 0x%x\n", 00244 APICAddress); 00245 00246 /* Map it */ 00247 HalPageTable[(APIC_BASE - 0xFFC00000) >> MM_PAGE_SHIFT].PageFrameNumber 00248 = APICAddress >> MM_PAGE_SHIFT; 00249 HalPageTable[(APIC_BASE - 0xFFC00000) >> MM_PAGE_SHIFT].Valid = 1; 00250 HalPageTable[(APIC_BASE - 0xFFC00000) >> MM_PAGE_SHIFT].Write = 1; 00251 HalPageTable[(APIC_BASE - 0xFFC00000) >> MM_PAGE_SHIFT].WriteThrough = 1; 00252 HalPageTable[(APIC_BASE - 0xFFC00000) >> MM_PAGE_SHIFT].CacheDisable = 1; 00253 } 00254 00255 BOOLEAN 00256 WinLdrMapSpecialPages(void) 00257 { 00258 00259 //VideoDisplayString(L"Hello from VGA, going into the kernel\n"); 00260 TRACE("HalPageTable: 0x%X\n", HalPageTable); 00261 00262 // Page Tables have been setup, make special handling for PCR and TSS 00263 // (which is done in BlSetupFotNt in usual ntldr) 00264 HalPageTable[(KI_USER_SHARED_DATA - 0xFFC00000) >> MM_PAGE_SHIFT].PageFrameNumber = PcrBasePage+1; 00265 HalPageTable[(KI_USER_SHARED_DATA - 0xFFC00000) >> MM_PAGE_SHIFT].Valid = 1; 00266 HalPageTable[(KI_USER_SHARED_DATA - 0xFFC00000) >> MM_PAGE_SHIFT].Write = 1; 00267 00268 HalPageTable[(KIP0PCRADDRESS - 0xFFC00000) >> MM_PAGE_SHIFT].PageFrameNumber = PcrBasePage; 00269 HalPageTable[(KIP0PCRADDRESS - 0xFFC00000) >> MM_PAGE_SHIFT].Valid = 1; 00270 HalPageTable[(KIP0PCRADDRESS - 0xFFC00000) >> MM_PAGE_SHIFT].Write = 1; 00271 00272 // Map APIC 00273 WinLdrpMapApic(); 00274 00275 // Map VGA memory 00276 //VideoMemoryBase = MmMapIoSpace(0xb8000, 4000, MmNonCached); 00277 //TRACE("VideoMemoryBase: 0x%X\n", VideoMemoryBase); 00278 00279 return TRUE; 00280 } 00281 00282 #define ExtendedBIOSDataArea ((PULONG)0x740) 00283 #define ExtendedBIOSDataSize ((PULONG)0x744) 00284 #define RomFontPointers ((PULONG)0x700) 00285 00286 enum 00287 { 00288 INT1FhFont = 0x00, 00289 INT43hFont = 0x01, 00290 ROM_8x14CharacterFont = 0x02, 00291 ROM_8x8DoubleDotFontLo = 0x03, 00292 ROM_8x8DoubleDotFontHi = 0x04, 00293 ROM_AlphaAlternate = 0x05, 00294 ROM_8x16Font = 0x06, 00295 ROM_Alternate9x16Font = 0x07, 00296 UltraVision_8x20Font = 0x11, 00297 UltraVision_8x10Font = 0x12, 00298 }; 00299 00300 void WinLdrSetupSpecialDataPointers() 00301 { 00302 REGS BiosRegs; 00303 00304 /* Get the address of the bios rom fonts. Win 2003 videoprt reads these 00305 values from address 0x700 .. 0x718 and store them in the registry 00306 in HKLM\System\CurrentControlSet\Control\Wow\RomFontPointers 00307 Int 10h, AX=1130h, BH = pointer specifier 00308 returns: es:bp = address */ 00309 BiosRegs.d.eax = 0x1130; 00310 BiosRegs.b.bh = ROM_8x14CharacterFont; 00311 Int386(0x10, &BiosRegs, &BiosRegs); 00312 RomFontPointers[0] = BiosRegs.w.es << 4 | BiosRegs.w.bp; 00313 00314 BiosRegs.b.bh = ROM_8x8DoubleDotFontLo; 00315 Int386(0x10, &BiosRegs, &BiosRegs); 00316 RomFontPointers[1] = BiosRegs.w.es << 16 | BiosRegs.w.bp; 00317 00318 BiosRegs.b.bh = ROM_8x8DoubleDotFontHi; 00319 Int386(0x10, &BiosRegs, &BiosRegs); 00320 RomFontPointers[2] = BiosRegs.w.es << 16 | BiosRegs.w.bp; 00321 00322 BiosRegs.b.bh = ROM_AlphaAlternate; 00323 Int386(0x10, &BiosRegs, &BiosRegs); 00324 RomFontPointers[3] = BiosRegs.w.es << 16 | BiosRegs.w.bp; 00325 00326 BiosRegs.b.bh = ROM_8x16Font; 00327 Int386(0x10, &BiosRegs, &BiosRegs); 00328 RomFontPointers[4] = BiosRegs.w.es << 16 | BiosRegs.w.bp; 00329 00330 BiosRegs.b.bh = ROM_Alternate9x16Font; 00331 Int386(0x10, &BiosRegs, &BiosRegs); 00332 RomFontPointers[5] = BiosRegs.w.es << 16 | BiosRegs.w.bp; 00333 00334 /* Store address of the extended bios data area in 0x740 */ 00335 BiosRegs.d.eax = 0xC100; 00336 Int386(0x15, &BiosRegs, &BiosRegs); 00337 if (INT386_SUCCESS(BiosRegs)) 00338 { 00339 *ExtendedBIOSDataArea = BiosRegs.w.es << 4; 00340 *ExtendedBIOSDataSize = 1024; 00341 TRACE("*ExtendedBIOSDataArea = 0x%lx\n", *ExtendedBIOSDataArea); 00342 } 00343 else 00344 { 00345 WARN("Couldn't get address of extended BIOS data area\n"); 00346 *ExtendedBIOSDataArea = 0; 00347 *ExtendedBIOSDataSize = 0; 00348 } 00349 } 00350 00351 void WinLdrSetupMachineDependent(PLOADER_PARAMETER_BLOCK LoaderBlock) 00352 { 00353 ULONG TssSize; 00354 //ULONG TssPages; 00355 ULONG_PTR Pcr = 0; 00356 ULONG_PTR Tss = 0; 00357 ULONG BlockSize, NumPages; 00358 00359 LoaderBlock->u.I386.CommonDataArea = NULL; // Force No ABIOS support 00360 LoaderBlock->u.I386.MachineType = MACHINE_TYPE_ISA; 00361 00362 /* Allocate 2 pages for PCR */ 00363 Pcr = (ULONG_PTR)MmAllocateMemoryWithType(2 * MM_PAGE_SIZE, LoaderStartupPcrPage); 00364 PcrBasePage = Pcr >> MM_PAGE_SHIFT; 00365 00366 if (Pcr == 0) 00367 { 00368 UiMessageBox("Can't allocate PCR\n"); 00369 return; 00370 } 00371 00372 /* Allocate TSS */ 00373 TssSize = (sizeof(KTSS) + MM_PAGE_SIZE) & ~(MM_PAGE_SIZE - 1); 00374 //TssPages = TssSize / MM_PAGE_SIZE; 00375 00376 Tss = (ULONG_PTR)MmAllocateMemoryWithType(TssSize, LoaderMemoryData); 00377 00378 TssBasePage = Tss >> MM_PAGE_SHIFT; 00379 00380 /* Allocate space for new GDT + IDT */ 00381 BlockSize = NUM_GDT*sizeof(KGDTENTRY) + NUM_IDT*sizeof(KIDTENTRY);//FIXME: Use GDT/IDT limits here? 00382 NumPages = (BlockSize + MM_PAGE_SIZE - 1) >> MM_PAGE_SHIFT; 00383 GdtIdt = (PKGDTENTRY)MmAllocateMemoryWithType(NumPages * MM_PAGE_SIZE, LoaderMemoryData); 00384 00385 if (GdtIdt == NULL) 00386 { 00387 UiMessageBox("Can't allocate pages for GDT+IDT!\n"); 00388 return; 00389 } 00390 00391 /* Zero newly prepared GDT+IDT */ 00392 RtlZeroMemory(GdtIdt, NumPages << MM_PAGE_SHIFT); 00393 00394 // Before we start mapping pages, create a block of memory, which will contain 00395 // PDE and PTEs 00396 if (MempAllocatePageTables() == FALSE) 00397 { 00398 BugCheck("MempAllocatePageTables failed!\n"); 00399 } 00400 00401 /* Map stuff like PCR, KI_USER_SHARED_DATA and Apic */ 00402 WinLdrMapSpecialPages(); 00403 00404 /* Set some special fields */ 00405 WinLdrSetupSpecialDataPointers(); 00406 } 00407 00408 00409 VOID 00410 WinLdrSetProcessorContext(void) 00411 { 00412 GDTIDT GdtDesc, IdtDesc, OldIdt; 00413 PKGDTENTRY pGdt; 00414 PKIDTENTRY pIdt; 00415 USHORT Ldt = 0; 00416 ULONG Pcr; 00417 ULONG Tss; 00418 //ULONG i; 00419 00420 Pcr = KIP0PCRADDRESS; 00421 Tss = KSEG0_BASE | (TssBasePage << MM_PAGE_SHIFT); 00422 00423 TRACE("GDtIdt %p, Pcr %p, Tss 0x%08X\n", 00424 GdtIdt, Pcr, Tss); 00425 00426 // Enable paging 00427 //BS->ExitBootServices(ImageHandle,MapKey); 00428 00429 // Disable Interrupts 00430 _disable(); 00431 00432 // Re-initalize EFLAGS 00433 __writeeflags(0); 00434 00435 // Set the PDBR 00436 __writecr3((ULONG_PTR)PDE); 00437 00438 // Enable paging by modifying CR0 00439 __writecr0(__readcr0() | CR0_PG); 00440 00441 // Kernel expects the PCR to be zero-filled on startup 00442 // FIXME: Why zero it here when we can zero it right after allocation? 00443 RtlZeroMemory((PVOID)Pcr, MM_PAGE_SIZE); //FIXME: Why zero only 1 page when we allocate 2? 00444 00445 // Get old values of GDT and IDT 00446 Ke386GetGlobalDescriptorTable(&GdtDesc); 00447 __sidt(&IdtDesc); 00448 00449 // Save old IDT 00450 OldIdt.Base = IdtDesc.Base; 00451 OldIdt.Limit = IdtDesc.Limit; 00452 00453 // Prepare new IDT+GDT 00454 GdtDesc.Base = KSEG0_BASE | (ULONG_PTR)GdtIdt; 00455 GdtDesc.Limit = NUM_GDT * sizeof(KGDTENTRY) - 1; 00456 IdtDesc.Base = (ULONG)((PUCHAR)GdtDesc.Base + GdtDesc.Limit + 1); 00457 IdtDesc.Limit = NUM_IDT * sizeof(KIDTENTRY) - 1; 00458 00459 // ======================== 00460 // Fill all descriptors now 00461 // ======================== 00462 00463 pGdt = (PKGDTENTRY)GdtDesc.Base; 00464 pIdt = (PKIDTENTRY)IdtDesc.Base; 00465 00466 // 00467 // Code selector (0x8) 00468 // Flat 4Gb 00469 // 00470 pGdt[1].LimitLow = 0xFFFF; 00471 pGdt[1].BaseLow = 0; 00472 pGdt[1].HighWord.Bytes.BaseMid = 0; 00473 pGdt[1].HighWord.Bytes.Flags1 = 0x9A; 00474 pGdt[1].HighWord.Bytes.Flags2 = 0xCF; 00475 pGdt[1].HighWord.Bytes.BaseHi = 0; 00476 00477 // 00478 // Data selector (0x10) 00479 // Flat 4Gb 00480 // 00481 pGdt[2].LimitLow = 0xFFFF; 00482 pGdt[2].BaseLow = 0; 00483 pGdt[2].HighWord.Bytes.BaseMid = 0; 00484 pGdt[2].HighWord.Bytes.Flags1 = 0x92; 00485 pGdt[2].HighWord.Bytes.Flags2 = 0xCF; 00486 pGdt[2].HighWord.Bytes.BaseHi = 0; 00487 00488 // 00489 // Selector (0x18) 00490 // Flat 2Gb 00491 // 00492 pGdt[3].LimitLow = 0xFFFF; 00493 pGdt[3].BaseLow = 0; 00494 pGdt[3].HighWord.Bytes.BaseMid = 0; 00495 pGdt[3].HighWord.Bytes.Flags1 = 0xFA; 00496 pGdt[3].HighWord.Bytes.Flags2 = 0xCF; 00497 pGdt[3].HighWord.Bytes.BaseHi = 0; 00498 00499 // 00500 // Selector (0x20) 00501 // Flat 2Gb 00502 // 00503 pGdt[4].LimitLow = 0xFFFF; 00504 pGdt[4].BaseLow = 0; 00505 pGdt[4].HighWord.Bytes.BaseMid = 0; 00506 pGdt[4].HighWord.Bytes.Flags1 = 0xF2; 00507 pGdt[4].HighWord.Bytes.Flags2 = 0xCF; 00508 pGdt[4].HighWord.Bytes.BaseHi = 0; 00509 00510 // 00511 // TSS Selector (0x28) 00512 // 00513 pGdt[5].LimitLow = 0x78-1; //FIXME: Check this 00514 pGdt[5].BaseLow = (USHORT)(Tss & 0xffff); 00515 pGdt[5].HighWord.Bytes.BaseMid = (UCHAR)((Tss >> 16) & 0xff); 00516 pGdt[5].HighWord.Bytes.Flags1 = 0x89; 00517 pGdt[5].HighWord.Bytes.Flags2 = 0x00; 00518 pGdt[5].HighWord.Bytes.BaseHi = (UCHAR)((Tss >> 24) & 0xff); 00519 00520 // 00521 // PCR Selector (0x30) 00522 // 00523 pGdt[6].LimitLow = 0x01; 00524 pGdt[6].BaseLow = (USHORT)(Pcr & 0xffff); 00525 pGdt[6].HighWord.Bytes.BaseMid = (UCHAR)((Pcr >> 16) & 0xff); 00526 pGdt[6].HighWord.Bytes.Flags1 = 0x92; 00527 pGdt[6].HighWord.Bytes.Flags2 = 0xC0; 00528 pGdt[6].HighWord.Bytes.BaseHi = (UCHAR)((Pcr >> 24) & 0xff); 00529 00530 // 00531 // Selector (0x38) 00532 // 00533 pGdt[7].LimitLow = 0xFFFF; 00534 pGdt[7].BaseLow = 0; 00535 pGdt[7].HighWord.Bytes.BaseMid = 0; 00536 pGdt[7].HighWord.Bytes.Flags1 = 0xF3; 00537 pGdt[7].HighWord.Bytes.Flags2 = 0x40; 00538 pGdt[7].HighWord.Bytes.BaseHi = 0; 00539 00540 // 00541 // Some BIOS stuff (0x40) 00542 // 00543 pGdt[8].LimitLow = 0xFFFF; 00544 pGdt[8].BaseLow = 0x400; 00545 pGdt[8].HighWord.Bytes.BaseMid = 0; 00546 pGdt[8].HighWord.Bytes.Flags1 = 0xF2; 00547 pGdt[8].HighWord.Bytes.Flags2 = 0x0; 00548 pGdt[8].HighWord.Bytes.BaseHi = 0; 00549 00550 // 00551 // Selector (0x48) 00552 // 00553 pGdt[9].LimitLow = 0; 00554 pGdt[9].BaseLow = 0; 00555 pGdt[9].HighWord.Bytes.BaseMid = 0; 00556 pGdt[9].HighWord.Bytes.Flags1 = 0; 00557 pGdt[9].HighWord.Bytes.Flags2 = 0; 00558 pGdt[9].HighWord.Bytes.BaseHi = 0; 00559 00560 // 00561 // Selector (0x50) 00562 // 00563 pGdt[10].LimitLow = 0xFFFF; //FIXME: Not correct! 00564 pGdt[10].BaseLow = 0; 00565 pGdt[10].HighWord.Bytes.BaseMid = 0x2; 00566 pGdt[10].HighWord.Bytes.Flags1 = 0x89; 00567 pGdt[10].HighWord.Bytes.Flags2 = 0; 00568 pGdt[10].HighWord.Bytes.BaseHi = 0; 00569 00570 // 00571 // Selector (0x58) 00572 // 00573 pGdt[11].LimitLow = 0xFFFF; 00574 pGdt[11].BaseLow = 0; 00575 pGdt[11].HighWord.Bytes.BaseMid = 0x2; 00576 pGdt[11].HighWord.Bytes.Flags1 = 0x9A; 00577 pGdt[11].HighWord.Bytes.Flags2 = 0; 00578 pGdt[11].HighWord.Bytes.BaseHi = 0; 00579 00580 // 00581 // Selector (0x60) 00582 // 00583 pGdt[12].LimitLow = 0xFFFF; 00584 pGdt[12].BaseLow = 0; //FIXME: Maybe not correct, but noone cares 00585 pGdt[12].HighWord.Bytes.BaseMid = 0x2; 00586 pGdt[12].HighWord.Bytes.Flags1 = 0x92; 00587 pGdt[12].HighWord.Bytes.Flags2 = 0; 00588 pGdt[12].HighWord.Bytes.BaseHi = 0; 00589 00590 // 00591 // Video buffer Selector (0x68) 00592 // 00593 pGdt[13].LimitLow = 0x3FFF; 00594 pGdt[13].BaseLow = 0x8000; 00595 pGdt[13].HighWord.Bytes.BaseMid = 0x0B; 00596 pGdt[13].HighWord.Bytes.Flags1 = 0x92; 00597 pGdt[13].HighWord.Bytes.Flags2 = 0; 00598 pGdt[13].HighWord.Bytes.BaseHi = 0; 00599 00600 // 00601 // Points to GDT (0x70) 00602 // 00603 pGdt[14].LimitLow = NUM_GDT*sizeof(KGDTENTRY) - 1; 00604 pGdt[14].BaseLow = 0x7000; 00605 pGdt[14].HighWord.Bytes.BaseMid = 0xFF; 00606 pGdt[14].HighWord.Bytes.Flags1 = 0x92; 00607 pGdt[14].HighWord.Bytes.Flags2 = 0; 00608 pGdt[14].HighWord.Bytes.BaseHi = 0xFF; 00609 00610 // 00611 // Some unused descriptors should go here 00612 // 00613 00614 // Copy the old IDT 00615 RtlCopyMemory(pIdt, (PVOID)OldIdt.Base, OldIdt.Limit + 1); 00616 00617 // Mask interrupts 00618 //asm("cli\n"); // they are already masked before enabling paged mode 00619 00620 // Load GDT+IDT 00621 Ke386SetGlobalDescriptorTable(&GdtDesc); 00622 __lidt(&IdtDesc); 00623 00624 // Jump to proper CS and clear prefetch queue 00625 #if defined(__GNUC__) 00626 asm("ljmp $0x08, $1f\n" 00627 "1:\n"); 00628 #elif defined(_MSC_VER) 00629 /* We can't express the above in MASM so we use this far return instead */ 00630 __asm 00631 { 00632 push 8 00633 push offset resume 00634 retf 00635 resume: 00636 }; 00637 #else 00638 #error 00639 #endif 00640 00641 // Set SS selector 00642 Ke386SetSs(0x10); // DataSelector=0x10 00643 00644 // Set DS and ES selectors 00645 Ke386SetDs(0x10); 00646 Ke386SetEs(0x10); // this is vital for rep stosd 00647 00648 // LDT = not used ever, thus set to 0 00649 Ke386SetLocalDescriptorTable(Ldt); 00650 00651 // Load TSR 00652 Ke386SetTr(KGDT_TSS); 00653 00654 // Clear GS 00655 Ke386SetGs(0); 00656 00657 // Set FS to PCR 00658 Ke386SetFs(0x30); 00659 00660 // Real end of the function, just for information 00661 /* do not uncomment! 00662 pop edi; 00663 pop esi; 00664 pop ebx; 00665 mov esp, ebp; 00666 pop ebp; 00667 ret 00668 */ 00669 } 00670 00671 #if DBG 00672 VOID 00673 MempDump() 00674 { 00675 ULONG *PDE_Addr=(ULONG *)PDE;//0xC0300000; 00676 int i, j; 00677 00678 TRACE("\nPDE\n"); 00679 00680 for (i=0; i<128; i++) 00681 { 00682 TRACE("0x%04X | ", i*8); 00683 00684 for (j=0; j<8; j++) 00685 { 00686 TRACE("0x%08X ", PDE_Addr[i*8+j]); 00687 } 00688 00689 TRACE("\n"); 00690 } 00691 } 00692 #endif 00693 Generated on Sun May 27 2012 04:19:07 for ReactOS by
1.7.6.1
|