Author: fireball
Date: Tue Oct 10 19:20:03 2006
New Revision: 24483
URL:
http://svn.reactos.org/svn/reactos?rev=24483&view=rev
Log:
- Add global var for keeping size of NLS data in pages
- Restructure memory-map building loop to create special descriptor for NLS data
- Fix a bug in memory-map building loop which lead to not covering last XXX pages of
memory
Modified:
trunk/reactos/boot/freeldr/freeldr/windows/wlmemory.c (contents, props changed)
trunk/reactos/boot/freeldr/freeldr/windows/wlregistry.c
Modified: trunk/reactos/boot/freeldr/freeldr/windows/wlmemory.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/windo…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/windows/wlmemory.c (original)
+++ trunk/reactos/boot/freeldr/freeldr/windows/wlmemory.c Tue Oct 10 19:20:03 2006
@@ -1,948 +1,991 @@
-/*
- * PROJECT: EFI Windows Loader
- * LICENSE: GPL - See COPYING in the top level directory
- * FILE: freeldr/winldr/wlmemory.c
- * PURPOSE: Memory related routines
- * PROGRAMMERS: Aleksey Bragin (aleksey(a)reactos.org)
- */
-
-/* INCLUDES ***************************************************************/
-
-#include <freeldr.h>
-
-#include <ndk/asm.h>
-
-#define NDEBUG
-#include <debug.h>
-
-// This is needed because headers define wrong one for ReactOS
-#undef KIP0PCRADDRESS
-#define KIP0PCRADDRESS 0xffdff000
-
-//
-// This is the zone which is used by the OS loader
-//
-#define LOADER_HIGH_ZONE ((16*1024*1024) >> MM_PAGE_SHIFT) //16Mb page
-
-#define HYPER_SPACE_ENTRY 0x300
-
-//TODO: Check if this is correct
-PCHAR MemTypeDesc[] = {
- "ExceptionBlock ",
- "SystemBlock ",
- "Free ",
- "Bad ",
- "LoadedProgram ",
- "FirmwareTemporary ",
- "FirmwarePermanent ",
- "OsloaderHeap ",
- "OsloaderStack ",
- "SystemCode ",
- "HalCode ",
- "BootDriver ",
- "ConsoleInDriver ",
- "ConsoleOutDriver ",
- "StartupDpcStack ",
- "StartupKernelStack",
- "StartupPanicStack ",
- "StartupPcrPage ",
- "StartupPdrPage ",
- "RegistryData ",
- "MemoryData ",
- "NlsData ",
- "SpecialMemory ",
- "BBTMemory ",
- "Maximum "
- };
-
-VOID
-WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock);
-
-
-VOID
-MempAddMemoryBlock(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
- UINT64 BasePage,
- UINT64 PageCount,
- ULONG Type);
-VOID
-WinLdrInsertDescriptor(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
- IN PMEMORY_ALLOCATION_DESCRIPTOR NewDescriptor);
-
-VOID
-WinLdrRemoveDescriptor(IN PMEMORY_ALLOCATION_DESCRIPTOR Descriptor);
-
-VOID
-WinLdrSetProcessorContext(PVOID GdtIdt, IN ULONG Pcr, IN ULONG Tss);
-
-// This is needed only for SetProcessorContext routine
-#pragma pack(2)
- typedef struct
- {
- USHORT Limit;
- ULONG Base;
- } GDTIDT;
-#pragma pack(4)
-
-// this is needed for new IDT filling
-#if 0
-extern ULONG_PTR i386DivideByZero;
-extern ULONG_PTR i386DebugException;
-extern ULONG_PTR i386NMIException;
-extern ULONG_PTR i386Breakpoint;
-extern ULONG_PTR i386Overflow;
-extern ULONG_PTR i386BoundException;
-extern ULONG_PTR i386InvalidOpcode;
-extern ULONG_PTR i386FPUNotAvailable;
-extern ULONG_PTR i386DoubleFault;
-extern ULONG_PTR i386CoprocessorSegment;
-extern ULONG_PTR i386InvalidTSS;
-extern ULONG_PTR i386SegmentNotPresent;
-extern ULONG_PTR i386StackException;
-extern ULONG_PTR i386GeneralProtectionFault;
-extern ULONG_PTR i386PageFault; // exc 14
-extern ULONG_PTR i386CoprocessorError; // exc 16
-extern ULONG_PTR i386AlignmentCheck; // exc 17
-#endif
-
-/* GLOBALS ***************************************************************/
-
-PHARDWARE_PTE PDE;
-PHARDWARE_PTE HalPT;
-
-PUCHAR PhysicalPageTablesBuffer;
-PUCHAR KernelPageTablesBuffer;
-ULONG PhysicalPageTables;
-ULONG KernelPageTables;
-
-MEMORY_ALLOCATION_DESCRIPTOR Mad[1024];
-ULONG MadCount = 0;
-
-
-/* FUNCTIONS **************************************************************/
-
-BOOLEAN
-MempAllocatePageTables()
-{
- ULONG NumPageTables, TotalSize;
- PUCHAR Buffer;
- // It's better to allocate PDE + PTEs contigiuos
-
- // Max number of entries = MaxPageNum >> 10
- // FIXME: This is a number to describe ALL physical memory
- // and windows doesn't expect ALL memory mapped...
- NumPageTables = (GetSystemMemorySize() >> MM_PAGE_SHIFT) >> 10;
-
- DbgPrint((DPRINT_WINDOWS, "NumPageTables = %d\n", NumPageTables));
-
- // Allocate memory block for all these things:
- // PDE, HAL mapping page table, physical mapping, kernel mapping
- TotalSize = (1+1+NumPageTables*2)*MM_PAGE_SIZE;
- Buffer = MmAllocateMemory(TotalSize);
-
- if (Buffer == NULL)
- {
- UiMessageBox("Impossible to allocate memory block for page tables!");
- return FALSE;
- }
-
- // Zero all this memory block
- RtlZeroMemory(Buffer, TotalSize);
-
- // Set up pointers correctly now
- PDE = (PHARDWARE_PTE)Buffer;
-
- // Map the page directory at 0xC0000000 (maps itself)
- PDE[HYPER_SPACE_ENTRY].PageFrameNumber = (ULONG)PDE >> MM_PAGE_SHIFT;
- PDE[HYPER_SPACE_ENTRY].Valid = 1;
- PDE[HYPER_SPACE_ENTRY].Write = 1;
-
- // The last PDE slot is allocated for HAL's memory mapping (Virtual Addresses
0xFFC00000 - 0xFFFFFFFF)
- HalPT = (PHARDWARE_PTE)&Buffer[MM_PAGE_SIZE*1];
-
- // Map it
- PDE[1023].PageFrameNumber = (ULONG)HalPT >> MM_PAGE_SHIFT;
- PDE[1023].Valid = 1;
- PDE[1023].Write = 1;
-
- // Store pointers to the tables for easier access
- PhysicalPageTablesBuffer = &Buffer[MM_PAGE_SIZE*2];
- KernelPageTablesBuffer = PhysicalPageTablesBuffer + NumPageTables*MM_PAGE_SIZE;
-
- // Zero counters of page tables used
- PhysicalPageTables = 0;
- KernelPageTables = 0;
-
- return TRUE;
-}
-
-VOID
-MempAllocatePTE(ULONG Entry, PHARDWARE_PTE *PhysicalPT, PHARDWARE_PTE *KernelPT)
-{
- //Print(L"Creating PDE Entry %X\n", Entry);
-
- // Identity mapping
- *PhysicalPT =
(PHARDWARE_PTE)&PhysicalPageTablesBuffer[PhysicalPageTables*MM_PAGE_SIZE];
- PhysicalPageTables++;
-
- PDE[Entry].PageFrameNumber = (ULONG)*PhysicalPT >> MM_PAGE_SHIFT;
- PDE[Entry].Valid = 1;
- PDE[Entry].Write = 1;
-
- if (Entry+(KSEG0_BASE >> 22) > 1023)
- {
- DbgPrint((DPRINT_WINDOWS, "WARNING! Entry: %X > 1023\n", Entry+(KSEG0_BASE
>> 22)));
- }
-
- // Kernel-mode mapping
- *KernelPT = (PHARDWARE_PTE)&KernelPageTablesBuffer[KernelPageTables*MM_PAGE_SIZE];
- KernelPageTables++;
-
- PDE[Entry+(KSEG0_BASE >> 22)].PageFrameNumber = ((ULONG)*KernelPT >>
MM_PAGE_SHIFT);
- PDE[Entry+(KSEG0_BASE >> 22)].Valid = 1;
- PDE[Entry+(KSEG0_BASE >> 22)].Write = 1;
-}
-
-BOOLEAN
-MempSetupPaging(IN ULONG StartPage,
- IN ULONG NumberOfPages)
-{
- PHARDWARE_PTE PhysicalPT;
- PHARDWARE_PTE KernelPT;
- ULONG Entry, Page;
-
- //Print(L"MempSetupPaging: SP 0x%X, Number: 0x%X\n", StartPage,
NumberOfPages);
-
- // HACK
- if (StartPage+NumberOfPages >= 0x80000)
- {
- //
- // We can't map this as it requires more than 1 PDE
- // and in fact it's not possible at all ;)
- //
- //Print(L"skipping...\n");
- return TRUE;
- }
-
- //
- // Now actually set up the page tables for identity mapping
- //
- for (Page=StartPage; Page < StartPage+NumberOfPages; Page++)
- {
- Entry = Page >> 10;
-
- if (((PULONG)PDE)[Entry] == 0)
- {
- MempAllocatePTE(Entry, &PhysicalPT, &KernelPT);
- }
- else
- {
- PhysicalPT = (PHARDWARE_PTE)(PDE[Entry].PageFrameNumber << MM_PAGE_SHIFT);
- KernelPT = (PHARDWARE_PTE)(PDE[Entry+(KSEG0_BASE >> 22)].PageFrameNumber
<< MM_PAGE_SHIFT);
- }
-
- if (Page == 0)
- {
- PhysicalPT[Page & 0x3ff].PageFrameNumber = Page;
- PhysicalPT[Page & 0x3ff].Valid = 0;
- PhysicalPT[Page & 0x3ff].Write = 0;
-
- KernelPT[Page & 0x3ff].PageFrameNumber = Page;
- KernelPT[Page & 0x3ff].Valid = 0;
- KernelPT[Page & 0x3ff].Write = 0;
- }
- else
- {
- PhysicalPT[Page & 0x3ff].PageFrameNumber = Page;
- PhysicalPT[Page & 0x3ff].Valid = 1;
- PhysicalPT[Page & 0x3ff].Write = 1;
-
- KernelPT[Page & 0x3ff].PageFrameNumber = Page;
- KernelPT[Page & 0x3ff].Valid = 1;
- KernelPT[Page & 0x3ff].Write = 1;
- }
- }
-
- return TRUE;
-}
-
-VOID
-MempAddMemoryBlock(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
- UINT64 BasePage,
- UINT64 PageCount,
- ULONG Type)
-{
- BOOLEAN Status;
-
- //
- // Check for some weird stuff at the top
- //
- if (BasePage + PageCount > 0xF0000)
- {
- //
- // Just skip this, without even adding to MAD list
- //
- return;
- }
-
- //
- // Base page and page count are always set
- //
- Mad[MadCount].BasePage = BasePage;
- Mad[MadCount].PageCount = PageCount;
-
- //
- // Check if it's more than the allowed for OS loader
- // if yes - don't map the pages, just add as FirmwareTemporary
- //
- if (BasePage + PageCount > LOADER_HIGH_ZONE)
- {
- Mad[MadCount].MemoryType = LoaderFirmwareTemporary;
-
- WinLdrInsertDescriptor(LoaderBlock, &Mad[MadCount]);
- MadCount++;
-
- Status = MempSetupPaging(BasePage, PageCount);
- if (!Status)
- {
- DbgPrint((DPRINT_WINDOWS, "Error during WinLdrpSetupPaging\n"));
- return;
- }
- return;
- }
-
- if (BasePage == 0xFFF && PageCount == 1)
- {
- Mad[MadCount].MemoryType = LoaderSpecialMemory;
-
- WinLdrInsertDescriptor(LoaderBlock, &Mad[MadCount]);
- MadCount++;
-
- //
- // Map it
- //
- Status = MempSetupPaging(BasePage, PageCount);
- if (!Status)
- {
- DbgPrint((DPRINT_WINDOWS, "Error during MempSetupPaging\n"));
- return;
- }
- }
- else if (BasePage == 0 && PageCount == 1)
- {
- Mad[MadCount].MemoryType = LoaderFirmwarePermanent;
-
- WinLdrInsertDescriptor(LoaderBlock, &Mad[MadCount]);
- MadCount++;
-
- //
- // Map it
- //
- Status = MempSetupPaging(BasePage, PageCount);
- if (!Status)
- {
- DbgPrint((DPRINT_WINDOWS, "Error during MempSetupPaging\n"));
- return;
- }
- }
- else
- {
- //
- // Now choose memory type as usual. FIXME!!!
- //
- if (Type == 0)
- {
- Mad[MadCount].MemoryType = LoaderFree;
- }
- else if (Type != 0 && Type != 1)
- {
- Mad[MadCount].MemoryType = LoaderFirmwarePermanent;
- }
- else if (Type == 1)
- {
- Mad[MadCount].MemoryType = LoaderSystemCode;
- }
- else
- {
- Mad[MadCount].MemoryType = LoaderFirmwarePermanent;
- }
-
- //
- // Add descriptor
- //
- WinLdrInsertDescriptor(LoaderBlock, &Mad[MadCount]);
- MadCount++;
-
- //
- // Map it
- //
- Status = MempSetupPaging(BasePage, PageCount);
- if (!Status)
- {
- DbgPrint((DPRINT_WINDOWS, "Error during MempSetupPaging\n"));
- return;
- }
- }
-}
-
-BOOLEAN
-WinLdrTurnOnPaging(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
- ULONG PcrBasePage,
- ULONG TssBasePage,
- PVOID GdtIdt)
-{
- ULONG i, PagesCount;
- ULONG LastPageIndex, LastPageType;
- PPAGE_LOOKUP_TABLE_ITEM MemoryMap;
- ULONG NoEntries;
- PKTSS Tss;
-
- //
- // Creating a suitable memory map for the Windows can be tricky, so let's
- // give a few advices:
- // 1) One must not map the whole available memory pages to PDE!
- // Map only what's needed - 16Mb, 24Mb, 32Mb max I think,
- // thus occupying 4, 6 or 8 PDE entries for identical mapping,
- // the same quantity for KSEG0_BASE mapping, one more entry for
- // hyperspace and one more entry for HAL physical pages mapping.
- // 2) Memory descriptors must map *the whole* physical memory
- // showing any memory above 16/24/32 as FirmwareTemporary
- //
- // 3) Overall memory blocks count must not exceed 30
- //
-
- //
- // During MmInitMachineDependent, the kernel zeroes PDE at the following address
- // 0xC0300000 - 0xC03007FC
- //
- // Then it finds the best place for non-paged pool:
- // StartPde C0300F70, EndPde C0300FF8, NumberOfPages C13, NextPhysPage 3AD
- //
-
- // Before we start mapping pages, create a block of memory, which will contain
- // PDE and PTEs
- if (MempAllocatePageTables() == FALSE)
- return FALSE;
-
- // Setup an entry for each descriptor
- MemoryMap = MmGetMemoryMap(&NoEntries);
- if (MemoryMap == NULL)
- {
- UiMessageBox("Can not retrieve the current memory map");
- return FALSE;
- }
-
- DbgPrint((DPRINT_WINDOWS, "Got memory map with %d entries\n"));
-
- // Construct a good memory map from what we've got
- PagesCount = 1;
- LastPageIndex = 0;
- LastPageType = MemoryMap[0].PageAllocated;
- for(i=1;i<NoEntries;i++)
- {
- if (MemoryMap[i].PageAllocated == LastPageType)
- {
- PagesCount++;
- }
- else
- {
- // Add the region
- MempAddMemoryBlock(LoaderBlock, LastPageIndex, PagesCount, LastPageType);
-
- // Reset our counter vars
- LastPageIndex = i;
- LastPageType = MemoryMap[i].PageAllocated;
- PagesCount = 1;
- }
- }
-
- DbgPrint((DPRINT_WINDOWS, "MadCount: %d\n", MadCount));
-
- WinLdrpDumpMemoryDescriptors(LoaderBlock); //FIXME: Delete!
-
- // Map our loader image, so we can continue running
- /*Status = MempSetupPaging(OsLoaderBase >> MM_PAGE_SHIFT, OsLoaderSize >>
MM_PAGE_SHIFT);
- if (!Status)
- {
- UiMessageBox("Error during MempSetupPaging");
- return;
- }*/
-
- //VideoDisplayString(L"Hello from VGA, going into the kernel\n");
- DbgPrint((DPRINT_WINDOWS, "HalPT: 0x%X\n", HalPT));
-
- // Page Tables have been setup, make special handling for PCR and TSS
- // (which is done in BlSetupFotNt in usual ntldr)
- HalPT[(KI_USER_SHARED_DATA - 0xFFC00000) >> MM_PAGE_SHIFT].PageFrameNumber =
PcrBasePage+1;
- HalPT[(KI_USER_SHARED_DATA - 0xFFC00000) >> MM_PAGE_SHIFT].Valid = 1;
- HalPT[(KI_USER_SHARED_DATA - 0xFFC00000) >> MM_PAGE_SHIFT].Write = 1;
-
- HalPT[(KIP0PCRADDRESS - 0xFFC00000) >> MM_PAGE_SHIFT].PageFrameNumber =
PcrBasePage;
- HalPT[(KIP0PCRADDRESS - 0xFFC00000) >> MM_PAGE_SHIFT].Valid = 1;
- HalPT[(KIP0PCRADDRESS - 0xFFC00000) >> MM_PAGE_SHIFT].Write = 1;
-
- // Map VGA memory
- //VideoMemoryBase = MmMapIoSpace(0xb8000, 4000, MmNonCached);
- //DbgPrint((DPRINT_WINDOWS, "VideoMemoryBase: 0x%X\n", VideoMemoryBase));
-
- Tss = (PKTSS)(KSEG0_BASE | (TssBasePage << MM_PAGE_SHIFT));
-
- // Fill the memory descriptor list and
- //PrepareMemoryDescriptorList();
- DbgPrint((DPRINT_WINDOWS, "Memory Descriptor List prepared, printing
PDE\n"));
- List_PaToVa(&LoaderBlock->MemoryDescriptorListHead);
-
- #if DEBUG
- {
- ULONG *PDE_Addr=(ULONG *)PDE;//0xC0300000;
- int j;
-
- DbgPrint((DPRINT_WINDOWS, "\nPDE\n"));
-
- for (i=0; i<128; i++)
- {
- DbgPrint((DPRINT_WINDOWS, "0x%04X | ", i*8));
-
- for (j=0; j<8; j++)
- {
- DbgPrint((DPRINT_WINDOWS, "0x%08X ", PDE_Addr[i*8+j]));
- }
-
- DbgPrint((DPRINT_WINDOWS, "\n"));
- }
- }
- #endif
-
-
- // Enable paging
- //BS->ExitBootServices(ImageHandle,MapKey);
-
- // Disable Interrupts
- Ke386DisableInterrupts();
-
- // Re-initalize EFLAGS
- Ke386EraseFlags();
-
- // Set the PDBR
- Ke386SetPageTableDirectory((ULONG_PTR)PDE);
-
- // Enable paging by modifying CR0
- Ke386SetCr0(Ke386GetCr0() | CR0_PG);
-
- // Set processor context
- WinLdrSetProcessorContext(GdtIdt, KIP0PCRADDRESS, KSEG0_BASE | (TssBasePage <<
MM_PAGE_SHIFT));
-
- // Zero KI_USER_SHARED_DATA page
- memset((PVOID)KI_USER_SHARED_DATA, 0, MM_PAGE_SIZE);
-
- return TRUE;
-}
-
-// Two special things this func does: it sorts descriptors,
-// and it merges free ones
-VOID
-WinLdrInsertDescriptor(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
- IN PMEMORY_ALLOCATION_DESCRIPTOR NewDescriptor)
-{
- PLIST_ENTRY ListHead = &LoaderBlock->MemoryDescriptorListHead;
- PLIST_ENTRY PreviousEntry, NextEntry;
- PMEMORY_ALLOCATION_DESCRIPTOR PreviousDescriptor = NULL, NextDescriptor = NULL;
-
- DbgPrint((DPRINT_WINDOWS, "BP=0x%X PC=0x%X %s\n", NewDescriptor->BasePage,
- NewDescriptor->PageCount, MemTypeDesc[NewDescriptor->MemoryType]));
-
- /* Find a place where to insert the new descriptor to */
- PreviousEntry = ListHead;
- NextEntry = ListHead->Flink;
- while (NextEntry != ListHead)
- {
- NextDescriptor = CONTAINING_RECORD(NextEntry,
- MEMORY_ALLOCATION_DESCRIPTOR,
- ListEntry);
- if (NewDescriptor->BasePage < NextDescriptor->BasePage)
- break;
-
- PreviousEntry = NextEntry;
- PreviousDescriptor = NextDescriptor;
- NextEntry = NextEntry->Flink;
- }
-
- /* Don't forget about merging free areas */
- if (NewDescriptor->MemoryType != LoaderFree)
- {
- /* Just insert, nothing to merge */
- InsertHeadList(PreviousEntry, &NewDescriptor->ListEntry);
- }
- else
- {
- /* Previous block also free? */
- if ((PreviousEntry != ListHead) && (PreviousDescriptor->MemoryType ==
LoaderFree) &&
- ((PreviousDescriptor->BasePage + PreviousDescriptor->PageCount) ==
- NewDescriptor->BasePage))
- {
- /* Just enlarge previous descriptor's PageCount */
- PreviousDescriptor->PageCount += NewDescriptor->PageCount;
- NewDescriptor = PreviousDescriptor;
- }
- else
- {
- /* Nope, just insert */
- InsertHeadList(PreviousEntry, &NewDescriptor->ListEntry);
- }
-
- /* Next block is free ?*/
- if ((NextEntry != ListHead) &&
- (NextDescriptor->MemoryType == LoaderFree) &&
- ((NewDescriptor->BasePage + NewDescriptor->PageCount) ==
NextDescriptor->BasePage))
- {
- /* Enlarge next descriptor's PageCount */
- NewDescriptor->PageCount += NextDescriptor->PageCount;
- RemoveEntryList(&NextDescriptor->ListEntry);
- }
- }
-
- return;
-}
-
-VOID
-WinLdrSetProcessorContext(PVOID GdtIdt, IN ULONG Pcr, IN ULONG Tss)
-{
- GDTIDT GdtDesc, IdtDesc, OldIdt;
- PKGDTENTRY pGdt;
- PKIDTENTRY pIdt;
- ULONG Ldt = 0;
- //ULONG i;
-
- DbgPrint((DPRINT_WINDOWS, "GDtIdt %p, Pcr %p, Tss 0x%08X\n",
- GdtIdt, Pcr, Tss));
-
- // Kernel expects the PCR to be zero-filled on startup
- // FIXME: Why zero it here when we can zero it right after allocation?
- RtlZeroMemory((PVOID)Pcr, MM_PAGE_SIZE); //FIXME: Why zero only 1 page when we allocate
2?
-
- // Get old values of GDT and IDT
- Ke386GetGlobalDescriptorTable(GdtDesc);
- Ke386GetInterruptDescriptorTable(IdtDesc);
-
- // Save old IDT
- OldIdt.Base = IdtDesc.Base;
- OldIdt.Limit = IdtDesc.Limit;
-
- // Prepare new IDT+GDT
- GdtDesc.Base = KSEG0_BASE | (ULONG_PTR)GdtIdt;
- GdtDesc.Limit = NUM_GDT * sizeof(KGDTENTRY) - 1;
- IdtDesc.Base = (ULONG)((PUCHAR)GdtDesc.Base + GdtDesc.Limit + 1);
- IdtDesc.Limit = NUM_IDT * sizeof(KIDTENTRY) - 1;
-
- // ========================
- // Fill all descriptors now
- // ========================
-
- pGdt = (PKGDTENTRY)GdtDesc.Base;
- pIdt = (PKIDTENTRY)IdtDesc.Base;
-
- //
- // Code selector (0x8)
- // Flat 4Gb
- //
- pGdt[1].LimitLow = 0xFFFF;
- pGdt[1].BaseLow = 0;
- pGdt[1].HighWord.Bytes.BaseMid = 0;
- pGdt[1].HighWord.Bytes.Flags1 = 0x9A;
- pGdt[1].HighWord.Bytes.Flags2 = 0xCF;
- pGdt[1].HighWord.Bytes.BaseHi = 0;
-
- //
- // Data selector (0x10)
- // Flat 4Gb
- //
- pGdt[2].LimitLow = 0xFFFF;
- pGdt[2].BaseLow = 0;
- pGdt[2].HighWord.Bytes.BaseMid = 0;
- pGdt[2].HighWord.Bytes.Flags1 = 0x92;
- pGdt[2].HighWord.Bytes.Flags2 = 0xCF;
- pGdt[2].HighWord.Bytes.BaseHi = 0;
-
- //
- // Selector (0x18)
- // Flat 2Gb
- //
- pGdt[3].LimitLow = 0xFFFF;
- pGdt[3].BaseLow = 0;
- pGdt[3].HighWord.Bytes.BaseMid = 0;
- pGdt[3].HighWord.Bytes.Flags1 = 0xFA;
- pGdt[3].HighWord.Bytes.Flags2 = 0xCF;
- pGdt[3].HighWord.Bytes.BaseHi = 0;
-
- //
- // Selector (0x20)
- // Flat 2Gb
- //
- pGdt[4].LimitLow = 0xFFFF;
- pGdt[4].BaseLow = 0;
- pGdt[4].HighWord.Bytes.BaseMid = 0;
- pGdt[4].HighWord.Bytes.Flags1 = 0xF2;
- pGdt[4].HighWord.Bytes.Flags2 = 0xCF;
- pGdt[4].HighWord.Bytes.BaseHi = 0;
-
- //
- // TSS Selector (0x28)
- //
- pGdt[5].LimitLow = 0x78-1; // 60 dwords
- pGdt[5].BaseLow = (USHORT)(Tss & 0xffff);
- pGdt[5].HighWord.Bytes.BaseMid = (UCHAR)((Tss >> 16) & 0xff);
- pGdt[5].HighWord.Bytes.Flags1 = 0x89;
- pGdt[5].HighWord.Bytes.Flags2 = 0x00;
- pGdt[5].HighWord.Bytes.BaseHi = (UCHAR)((Tss >> 24) & 0xff);
-
- //
- // PCR Selector (0x30)
- //
- pGdt[6].LimitLow = 0x01;
- pGdt[6].BaseLow = (USHORT)(Pcr & 0xffff);
- pGdt[6].HighWord.Bytes.BaseMid = (UCHAR)((Pcr >> 16) & 0xff);
- pGdt[6].HighWord.Bytes.Flags1 = 0x92;
- pGdt[6].HighWord.Bytes.Flags2 = 0xC0;
- pGdt[6].HighWord.Bytes.BaseHi = (UCHAR)((Pcr >> 24) & 0xff);
-
- //
- // Selector (0x38)
- //
- pGdt[7].LimitLow = 0xFFFF;
- pGdt[7].BaseLow = 0;
- pGdt[7].HighWord.Bytes.BaseMid = 0;
- pGdt[7].HighWord.Bytes.Flags1 = 0xF3;
- pGdt[7].HighWord.Bytes.Flags2 = 0x40;
- pGdt[7].HighWord.Bytes.BaseHi = 0;
-
- //
- // Some BIOS fuck (0x40)
- //
- pGdt[8].LimitLow = 0xFFFF;
- pGdt[8].BaseLow = 0x400;
- pGdt[8].HighWord.Bytes.BaseMid = 0;
- pGdt[8].HighWord.Bytes.Flags1 = 0xF2;
- pGdt[8].HighWord.Bytes.Flags2 = 0x0;
- pGdt[8].HighWord.Bytes.BaseHi = 0;
-
- //
- // Selector (0x48)
- //
- pGdt[9].LimitLow = 0;
- pGdt[9].BaseLow = 0;
- pGdt[9].HighWord.Bytes.BaseMid = 0;
- pGdt[9].HighWord.Bytes.Flags1 = 0;
- pGdt[9].HighWord.Bytes.Flags2 = 0;
- pGdt[9].HighWord.Bytes.BaseHi = 0;
-
- //
- // Selector (0x50)
- //
- pGdt[10].LimitLow = 0xFFFF; //FIXME: Not correct!
- pGdt[10].BaseLow = 0;
- pGdt[10].HighWord.Bytes.BaseMid = 0x2;
- pGdt[10].HighWord.Bytes.Flags1 = 0x89;
- pGdt[10].HighWord.Bytes.Flags2 = 0;
- pGdt[10].HighWord.Bytes.BaseHi = 0;
-
- //
- // Selector (0x58)
- //
- pGdt[11].LimitLow = 0xFFFF;
- pGdt[11].BaseLow = 0;
- pGdt[11].HighWord.Bytes.BaseMid = 0x2;
- pGdt[11].HighWord.Bytes.Flags1 = 0x9A;
- pGdt[11].HighWord.Bytes.Flags2 = 0;
- pGdt[11].HighWord.Bytes.BaseHi = 0;
-
- //
- // Selector (0x60)
- //
- pGdt[12].LimitLow = 0xFFFF;
- pGdt[12].BaseLow = 0; //FIXME: Maybe not correct, but noone cares
- pGdt[12].HighWord.Bytes.BaseMid = 0x2;
- pGdt[12].HighWord.Bytes.Flags1 = 0x92;
- pGdt[12].HighWord.Bytes.Flags2 = 0;
- pGdt[12].HighWord.Bytes.BaseHi = 0;
-
- //
- // Video buffer Selector (0x68)
- //
- pGdt[13].LimitLow = 0x3FFF;
- pGdt[13].BaseLow = 0x8000; //FIXME: I guess not correct for UGA
- pGdt[13].HighWord.Bytes.BaseMid = 0x0B;
- pGdt[13].HighWord.Bytes.Flags1 = 0x92;
- pGdt[13].HighWord.Bytes.Flags2 = 0;
- pGdt[13].HighWord.Bytes.BaseHi = 0;
-
- //
- // Points to GDT (0x70)
- //
- pGdt[14].LimitLow = NUM_GDT*sizeof(KGDTENTRY) - 1;
- pGdt[14].BaseLow = 0x7000;
- pGdt[14].HighWord.Bytes.BaseMid = 0xFF;
- pGdt[14].HighWord.Bytes.Flags1 = 0x92;
- pGdt[14].HighWord.Bytes.Flags2 = 0;
- pGdt[14].HighWord.Bytes.BaseHi = 0xFF;
-
- //
- // Some unused descriptors should go here
- // ...
-
- //
- // Fill IDT with Traps
- //
-#if 0
- pIdt[0].Offset = (i386DivideByZero | KSEG0_BASE) & 0xFFFF;
- pIdt[0].ExtendedOffset = 0x8; // Selector
- pIdt[0].Access = 0x8F00;
- pIdt[0].Selector = (i386DivideByZero | KSEG0_BASE) >> 16; // Extended Offset
-
- pIdt[1].Offset = (i386DebugException | KSEG0_BASE) & 0xFFFF;
- pIdt[1].ExtendedOffset = 0x8; // Selector
- pIdt[1].Access = 0x8F00;
- pIdt[1].Selector = (i386DebugException | KSEG0_BASE) >> 16; // Extended Offset
-
- pIdt[2].Offset = (i386NMIException | KSEG0_BASE) & 0xFFFF;
- pIdt[2].ExtendedOffset = 0x8; // Selector
- pIdt[2].Access = 0x8F00;
- pIdt[2].Selector = (i386NMIException | KSEG0_BASE) >> 16; // Extended Offset
-
- pIdt[3].Offset = (i386Breakpoint | KSEG0_BASE) & 0xFFFF;
- pIdt[3].ExtendedOffset = 0x8; // Selector
- pIdt[3].Access = 0x8F00;
- pIdt[3].Selector = (i386Breakpoint | KSEG0_BASE) >> 16; // Extended Offset
-
- pIdt[4].Offset = (i386Overflow | KSEG0_BASE) & 0xFFFF;
- pIdt[4].ExtendedOffset = 0x8; // Selector
- pIdt[4].Access = 0x8F00;
- pIdt[4].Selector = (i386Overflow | KSEG0_BASE) >> 16; // Extended Offset
-
- pIdt[5].Selector = (i386BoundException | KSEG0_BASE) >> 16; // Extended Offset
- pIdt[5].Offset = (i386BoundException | KSEG0_BASE) & 0xFFFF;
- pIdt[5].ExtendedOffset = 0x8; // Selector
- pIdt[5].Access = 0x8F00;
-
- pIdt[6].Selector = (i386InvalidOpcode | KSEG0_BASE) >> 16; // Extended Offset
- pIdt[6].Offset = (i386InvalidOpcode | KSEG0_BASE) & 0xFFFF;
- pIdt[6].ExtendedOffset = 0x8; // Selector
- pIdt[6].Access = 0x8F00;
-
- pIdt[7].Selector = (i386FPUNotAvailable | KSEG0_BASE) >> 16; // Extended Offset
- pIdt[7].Offset = (i386FPUNotAvailable | KSEG0_BASE) & 0xFFFF;
- pIdt[7].ExtendedOffset = 0x8; // Selector
- pIdt[7].Access = 0x8F00;
-
- pIdt[8].Selector = (i386DoubleFault | KSEG0_BASE) >> 16; // Extended Offset
- pIdt[8].Offset = (i386DoubleFault | KSEG0_BASE) & 0xFFFF;
- pIdt[8].ExtendedOffset = 0x8; // Selector
- pIdt[8].Access = 0x8F00;
-
- pIdt[9].Selector = (i386CoprocessorSegment | KSEG0_BASE) >> 16; // Extended
Offset
- pIdt[9].Offset = (i386CoprocessorSegment | KSEG0_BASE) & 0xFFFF;
- pIdt[9].ExtendedOffset = 0x8; // Selector
- pIdt[9].Access = 0x8F00;
-
- pIdt[10].Selector = (i386InvalidTSS | KSEG0_BASE) >> 16; // Extended Offset
- pIdt[10].Offset = (i386InvalidTSS | KSEG0_BASE) & 0xFFFF;
- pIdt[10].ExtendedOffset = 0x8; // Selector
- pIdt[10].Access = 0x8F00;
-
- pIdt[11].Selector = (i386SegmentNotPresent | KSEG0_BASE) >> 16; // Extended
Offset
- pIdt[11].Offset = (i386SegmentNotPresent | KSEG0_BASE) & 0xFFFF;
- pIdt[11].ExtendedOffset = 0x8; // Selector
- pIdt[11].Access = 0x8F00;
-
- pIdt[12].Selector = (i386StackException | KSEG0_BASE) >> 16; // Extended Offset
- pIdt[12].Offset = (i386StackException | KSEG0_BASE) & 0xFFFF;
- pIdt[12].ExtendedOffset = 0x8; // Selector
- pIdt[12].Access = 0x8F00;
-
- pIdt[13].Selector = (i386GeneralProtectionFault | KSEG0_BASE) >> 16; // Extended
Offset
- pIdt[13].Offset = (i386GeneralProtectionFault | KSEG0_BASE) & 0xFFFF;
- pIdt[13].ExtendedOffset = 0x8; // Selector
- pIdt[13].Access = 0x8F00;
-
- pIdt[14].Selector = (i386PageFault | KSEG0_BASE) >> 16; // Extended Offset
- pIdt[14].Offset = (i386PageFault | KSEG0_BASE) & 0xFFFF;
- pIdt[14].ExtendedOffset = 0x8; // Selector
- pIdt[14].Access = 0x8F00;
-
- pIdt[15].Selector = 0; // Extended Offset
- pIdt[15].Offset = 0;
- pIdt[15].ExtendedOffset = 0; // Selector
- pIdt[15].Access = 0;
-
- pIdt[16].Selector = (i386CoprocessorError | KSEG0_BASE) >> 16; // Extended Offset
- pIdt[16].Offset = (i386CoprocessorError | KSEG0_BASE) & 0xFFFF;
- pIdt[16].ExtendedOffset = 0x8; // Selector
- pIdt[16].Access = 0x8F00;
-
- pIdt[17].Selector = (i386AlignmentCheck | KSEG0_BASE) >> 16; // Extended Offset
- pIdt[17].Offset = (i386AlignmentCheck | KSEG0_BASE) & 0xFFFF;
- pIdt[17].ExtendedOffset = 0x8; // Selector
- pIdt[17].Access = 0x8F00;
-#endif
-
- /*for (i=0; i<16; i++)
- {
- //pIdt[i].Offset = ((ULONG_PTR)i386GeneralProtectionFault | KSEG0_BASE) & 0xFFFF;
- //pIdt[i].ExtendedOffset = 0x8; // Selector
- //pIdt[i].Access = 0x8F00;
- //pIdt[i].Selector = ((ULONG_PTR)i386GeneralProtectionFault | KSEG0_BASE) >> 16;
// Extended Offset
-
- pIdt[i].Offset = ((ULONG_PTR)i386GeneralProtectionFault | KSEG0_BASE) & 0xFFFF;
- pIdt[i].ExtendedOffset = ((ULONG_PTR)i386GeneralProtectionFault | KSEG0_BASE) >>
16; // Extended Offset
- pIdt[i].Access = 0x8F00;
- pIdt[i].Selector = 0x8;
- }*/
-
- // Copy the old IDT
- RtlCopyMemory(pIdt, (PVOID)OldIdt.Base, OldIdt.Limit);
-
-
- // Mask interrupts
- //asm("cli\n"); // they are already masked before enabling paged mode
-
- // Load GDT+IDT
- Ke386SetGlobalDescriptorTable(GdtDesc);
- Ke386SetInterruptDescriptorTable(IdtDesc);
-
- // Jump to proper CS and clear prefetch queue
- asm("ljmp $0x08, $mb1\n"
- "mb1:\n");
-
- // Set SS selector
- asm(".intel_syntax noprefix\n");
- asm("mov ax, 0x10\n"); // DataSelector=0x10
- asm("mov ss, ax\n");
- asm(".att_syntax\n");
-
- // Set DS and ES selectors
- Ke386SetDs(0x10);
- Ke386SetEs(0x10); // this is vital for rep stosd
-
- // LDT = not used ever, thus set to 0
- Ke386SetLocalDescriptorTable(Ldt);
-
- // Load TSR
- Ke386SetTr(0x28);
-
- // Clear GS
- asm(".intel_syntax noprefix\n");
- asm("push 0\n");
- asm("pop gs\n");
- asm(".att_syntax\n");
-
- // Set FS to PCR
- Ke386SetFs(0x30);
-
- // Real end of the function, just for information
- /* do not uncomment!
- pop edi;
- pop esi;
- pop ebx;
- mov esp, ebp;
- pop ebp;
- ret
- */
-}
+/*
+ * PROJECT: EFI Windows Loader
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: freeldr/winldr/wlmemory.c
+ * PURPOSE: Memory related routines
+ * PROGRAMMERS: Aleksey Bragin (aleksey(a)reactos.org)
+ */
+
+/* INCLUDES ***************************************************************/
+
+#include <freeldr.h>
+
+#include <ndk/asm.h>
+
+#define NDEBUG
+#include <debug.h>
+
+extern ULONG TotalNLSSize;
+
+// This is needed because headers define wrong one for ReactOS
+#undef KIP0PCRADDRESS
+#define KIP0PCRADDRESS 0xffdff000
+
+//
+// This is the zone which is used by the OS loader
+//
+#define LOADER_HIGH_ZONE ((16*1024*1024) >> MM_PAGE_SHIFT) //16Mb page
+
+#define HYPER_SPACE_ENTRY 0x300
+
+//TODO: Check if this is correct
+PCHAR MemTypeDesc[] = {
+ "ExceptionBlock ",
+ "SystemBlock ",
+ "Free ",
+ "Bad ",
+ "LoadedProgram ",
+ "FirmwareTemporary ",
+ "FirmwarePermanent ",
+ "OsloaderHeap ",
+ "OsloaderStack ",
+ "SystemCode ",
+ "HalCode ",
+ "BootDriver ",
+ "ConsoleInDriver ",
+ "ConsoleOutDriver ",
+ "StartupDpcStack ",
+ "StartupKernelStack",
+ "StartupPanicStack ",
+ "StartupPcrPage ",
+ "StartupPdrPage ",
+ "RegistryData ",
+ "MemoryData ",
+ "NlsData ",
+ "SpecialMemory ",
+ "BBTMemory ",
+ "Maximum "
+ };
+
+VOID
+WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock);
+
+
+VOID
+MempAddMemoryBlock(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
+ UINT64 BasePage,
+ UINT64 PageCount,
+ ULONG Type);
+VOID
+WinLdrInsertDescriptor(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
+ IN PMEMORY_ALLOCATION_DESCRIPTOR NewDescriptor);
+
+VOID
+WinLdrRemoveDescriptor(IN PMEMORY_ALLOCATION_DESCRIPTOR Descriptor);
+
+VOID
+WinLdrSetProcessorContext(PVOID GdtIdt, IN ULONG Pcr, IN ULONG Tss);
+
+// This is needed only for SetProcessorContext routine
+#pragma pack(2)
+ typedef struct
+ {
+ USHORT Limit;
+ ULONG Base;
+ } GDTIDT;
+#pragma pack(4)
+
+// this is needed for new IDT filling
+#if 0
+extern ULONG_PTR i386DivideByZero;
+extern ULONG_PTR i386DebugException;
+extern ULONG_PTR i386NMIException;
+extern ULONG_PTR i386Breakpoint;
+extern ULONG_PTR i386Overflow;
+extern ULONG_PTR i386BoundException;
+extern ULONG_PTR i386InvalidOpcode;
+extern ULONG_PTR i386FPUNotAvailable;
+extern ULONG_PTR i386DoubleFault;
+extern ULONG_PTR i386CoprocessorSegment;
+extern ULONG_PTR i386InvalidTSS;
+extern ULONG_PTR i386SegmentNotPresent;
+extern ULONG_PTR i386StackException;
+extern ULONG_PTR i386GeneralProtectionFault;
+extern ULONG_PTR i386PageFault; // exc 14
+extern ULONG_PTR i386CoprocessorError; // exc 16
+extern ULONG_PTR i386AlignmentCheck; // exc 17
+#endif
+
+/* GLOBALS ***************************************************************/
+
+PHARDWARE_PTE PDE;
+PHARDWARE_PTE HalPT;
+
+PUCHAR PhysicalPageTablesBuffer;
+PUCHAR KernelPageTablesBuffer;
+ULONG PhysicalPageTables;
+ULONG KernelPageTables;
+
+MEMORY_ALLOCATION_DESCRIPTOR Mad[1024];
+ULONG MadCount = 0;
+
+
+/* FUNCTIONS **************************************************************/
+
+BOOLEAN
+MempAllocatePageTables()
+{
+ ULONG NumPageTables, TotalSize;
+ PUCHAR Buffer;
+ // It's better to allocate PDE + PTEs contigiuos
+
+ // Max number of entries = MaxPageNum >> 10
+ // FIXME: This is a number to describe ALL physical memory
+ // and windows doesn't expect ALL memory mapped...
+ NumPageTables = (GetSystemMemorySize() >> MM_PAGE_SHIFT) >> 10;
+
+ DbgPrint((DPRINT_WINDOWS, "NumPageTables = %d\n", NumPageTables));
+
+ // Allocate memory block for all these things:
+ // PDE, HAL mapping page table, physical mapping, kernel mapping
+ TotalSize = (1+1+NumPageTables*2)*MM_PAGE_SIZE;
+ Buffer = MmAllocateMemory(TotalSize);
+
+ if (Buffer == NULL)
+ {
+ UiMessageBox("Impossible to allocate memory block for page tables!");
+ return FALSE;
+ }
+
+ // Zero all this memory block
+ RtlZeroMemory(Buffer, TotalSize);
+
+ // Set up pointers correctly now
+ PDE = (PHARDWARE_PTE)Buffer;
+
+ // Map the page directory at 0xC0000000 (maps itself)
+ PDE[HYPER_SPACE_ENTRY].PageFrameNumber = (ULONG)PDE >> MM_PAGE_SHIFT;
+ PDE[HYPER_SPACE_ENTRY].Valid = 1;
+ PDE[HYPER_SPACE_ENTRY].Write = 1;
+
+ // The last PDE slot is allocated for HAL's memory mapping (Virtual Addresses
0xFFC00000 - 0xFFFFFFFF)
+ HalPT = (PHARDWARE_PTE)&Buffer[MM_PAGE_SIZE*1];
+
+ // Map it
+ PDE[1023].PageFrameNumber = (ULONG)HalPT >> MM_PAGE_SHIFT;
+ PDE[1023].Valid = 1;
+ PDE[1023].Write = 1;
+
+ // Store pointers to the tables for easier access
+ PhysicalPageTablesBuffer = &Buffer[MM_PAGE_SIZE*2];
+ KernelPageTablesBuffer = PhysicalPageTablesBuffer + NumPageTables*MM_PAGE_SIZE;
+
+ // Zero counters of page tables used
+ PhysicalPageTables = 0;
+ KernelPageTables = 0;
+
+ return TRUE;
+}
+
+VOID
+MempAllocatePTE(ULONG Entry, PHARDWARE_PTE *PhysicalPT, PHARDWARE_PTE *KernelPT)
+{
+ //Print(L"Creating PDE Entry %X\n", Entry);
+
+ // Identity mapping
+ *PhysicalPT =
(PHARDWARE_PTE)&PhysicalPageTablesBuffer[PhysicalPageTables*MM_PAGE_SIZE];
+ PhysicalPageTables++;
+
+ PDE[Entry].PageFrameNumber = (ULONG)*PhysicalPT >> MM_PAGE_SHIFT;
+ PDE[Entry].Valid = 1;
+ PDE[Entry].Write = 1;
+
+ if (Entry+(KSEG0_BASE >> 22) > 1023)
+ {
+ DbgPrint((DPRINT_WINDOWS, "WARNING! Entry: %X > 1023\n", Entry+(KSEG0_BASE
>> 22)));
+ }
+
+ // Kernel-mode mapping
+ *KernelPT = (PHARDWARE_PTE)&KernelPageTablesBuffer[KernelPageTables*MM_PAGE_SIZE];
+ KernelPageTables++;
+
+ PDE[Entry+(KSEG0_BASE >> 22)].PageFrameNumber = ((ULONG)*KernelPT >>
MM_PAGE_SHIFT);
+ PDE[Entry+(KSEG0_BASE >> 22)].Valid = 1;
+ PDE[Entry+(KSEG0_BASE >> 22)].Write = 1;
+}
+
+BOOLEAN
+MempSetupPaging(IN ULONG StartPage,
+ IN ULONG NumberOfPages)
+{
+ PHARDWARE_PTE PhysicalPT;
+ PHARDWARE_PTE KernelPT;
+ ULONG Entry, Page;
+
+ //Print(L"MempSetupPaging: SP 0x%X, Number: 0x%X\n", StartPage,
NumberOfPages);
+
+ // HACK
+ if (StartPage+NumberOfPages >= 0x80000)
+ {
+ //
+ // We can't map this as it requires more than 1 PDE
+ // and in fact it's not possible at all ;)
+ //
+ //Print(L"skipping...\n");
+ return TRUE;
+ }
+
+ //
+ // Now actually set up the page tables for identity mapping
+ //
+ for (Page=StartPage; Page < StartPage+NumberOfPages; Page++)
+ {
+ Entry = Page >> 10;
+
+ if (((PULONG)PDE)[Entry] == 0)
+ {
+ MempAllocatePTE(Entry, &PhysicalPT, &KernelPT);
+ }
+ else
+ {
+ PhysicalPT = (PHARDWARE_PTE)(PDE[Entry].PageFrameNumber << MM_PAGE_SHIFT);
+ KernelPT = (PHARDWARE_PTE)(PDE[Entry+(KSEG0_BASE >> 22)].PageFrameNumber
<< MM_PAGE_SHIFT);
+ }
+
+ if (Page == 0)
+ {
+ PhysicalPT[Page & 0x3ff].PageFrameNumber = Page;
+ PhysicalPT[Page & 0x3ff].Valid = 0;
+ PhysicalPT[Page & 0x3ff].Write = 0;
+
+ KernelPT[Page & 0x3ff].PageFrameNumber = Page;
+ KernelPT[Page & 0x3ff].Valid = 0;
+ KernelPT[Page & 0x3ff].Write = 0;
+ }
+ else
+ {
+ PhysicalPT[Page & 0x3ff].PageFrameNumber = Page;
+ PhysicalPT[Page & 0x3ff].Valid = 1;
+ PhysicalPT[Page & 0x3ff].Write = 1;
+
+ KernelPT[Page & 0x3ff].PageFrameNumber = Page;
+ KernelPT[Page & 0x3ff].Valid = 1;
+ KernelPT[Page & 0x3ff].Write = 1;
+ }
+ }
+
+ return TRUE;
+}
+
+VOID
+MempAddMemoryBlock(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
+ UINT64 BasePage,
+ UINT64 PageCount,
+ ULONG Type)
+{
+ BOOLEAN Status;
+
+ //
+ // Check for some weird stuff at the top
+ //
+ if (BasePage + PageCount > 0xF0000)
+ {
+ //
+ // Just skip this, without even adding to MAD list
+ //
+ return;
+ }
+
+ //
+ // Base page and page count are always set
+ //
+ Mad[MadCount].BasePage = BasePage;
+ Mad[MadCount].PageCount = PageCount;
+
+ //
+ // Check if it's more than the allowed for OS loader
+ // if yes - don't map the pages, just add as FirmwareTemporary
+ //
+ if (BasePage + PageCount > LOADER_HIGH_ZONE && (Type != LoaderNlsData))
+ {
+ Mad[MadCount].MemoryType = LoaderFirmwareTemporary;
+
+ WinLdrInsertDescriptor(LoaderBlock, &Mad[MadCount]);
+ MadCount++;
+
+ Status = MempSetupPaging(BasePage, PageCount);
+ if (!Status)
+ {
+ DbgPrint((DPRINT_WINDOWS, "Error during WinLdrpSetupPaging\n"));
+ return;
+ }
+ return;
+ }
+
+ if (BasePage == 0xFFF && PageCount == 1)
+ {
+ Mad[MadCount].MemoryType = LoaderSpecialMemory;
+
+ WinLdrInsertDescriptor(LoaderBlock, &Mad[MadCount]);
+ MadCount++;
+
+ //
+ // Map it
+ //
+ Status = MempSetupPaging(BasePage, PageCount);
+ if (!Status)
+ {
+ DbgPrint((DPRINT_WINDOWS, "Error during MempSetupPaging\n"));
+ return;
+ }
+ }
+ else if (BasePage == 0 && PageCount == 1)
+ {
+ Mad[MadCount].MemoryType = LoaderFirmwarePermanent;
+
+ WinLdrInsertDescriptor(LoaderBlock, &Mad[MadCount]);
+ MadCount++;
+
+ //
+ // Map it
+ //
+ Status = MempSetupPaging(BasePage, PageCount);
+ if (!Status)
+ {
+ DbgPrint((DPRINT_WINDOWS, "Error during MempSetupPaging\n"));
+ return;
+ }
+ }
+ else
+ {
+ //
+ // Set memory type
+ //
+ Mad[MadCount].MemoryType = Type;
+
+ //
+ // Add descriptor
+ //
+ WinLdrInsertDescriptor(LoaderBlock, &Mad[MadCount]);
+ MadCount++;
+
+ //
+ // Map it
+ //
+ Status = MempSetupPaging(BasePage, PageCount);
+ if (!Status)
+ {
+ DbgPrint((DPRINT_WINDOWS, "Error during MempSetupPaging\n"));
+ return;
+ }
+ }
+}
+
+BOOLEAN
+WinLdrTurnOnPaging(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
+ ULONG PcrBasePage,
+ ULONG TssBasePage,
+ PVOID GdtIdt)
+{
+ ULONG i, PagesCount;
+ ULONG LastPageIndex, LastPageType, NtType;
+ PPAGE_LOOKUP_TABLE_ITEM MemoryMap;
+ ULONG NoEntries;
+ PKTSS Tss;
+ PVOID NlsBase =
VaToPa(((PNLS_DATA_BLOCK)VaToPa(LoaderBlock->NlsData))->AnsiCodePageData);
+ ULONG NlsBasePage = (ULONG_PTR)NlsBase >> PAGE_SHIFT;
+
+ //
+ // Creating a suitable memory map for the Windows can be tricky, so let's
+ // give a few advices:
+ // 1) One must not map the whole available memory pages to PDE!
+ // Map only what's needed - 16Mb, 24Mb, 32Mb max I think,
+ // thus occupying 4, 6 or 8 PDE entries for identical mapping,
+ // the same quantity for KSEG0_BASE mapping, one more entry for
+ // hyperspace and one more entry for HAL physical pages mapping.
+ // 2) Memory descriptors must map *the whole* physical memory
+ // showing any memory above 16/24/32 as FirmwareTemporary
+ //
+ // 3) Overall memory blocks count must not exceed 30
+ //
+
+ //
+ // During MmInitMachineDependent, the kernel zeroes PDE at the following address
+ // 0xC0300000 - 0xC03007FC
+ //
+ // Then it finds the best place for non-paged pool:
+ // StartPde C0300F70, EndPde C0300FF8, NumberOfPages C13, NextPhysPage 3AD
+ //
+
+ // Before we start mapping pages, create a block of memory, which will contain
+ // PDE and PTEs
+ if (MempAllocatePageTables() == FALSE)
+ return FALSE;
+
+ // Setup an entry for each descriptor
+ MemoryMap = MmGetMemoryMap(&NoEntries);
+ if (MemoryMap == NULL)
+ {
+ UiMessageBox("Can not retrieve the current memory map");
+ return FALSE;
+ }
+
+ DbgPrint((DPRINT_WINDOWS, "Got memory map with %d entries, NlsBasePage
0x%X\n",
+ NoEntries, NlsBasePage));
+
+ // Construct a good memory map from what we've got
+ PagesCount = 1;
+ LastPageIndex = 0;
+ LastPageType = MemoryMap[0].PageAllocated;
+ for(i=1;i<NoEntries;i++)
+ {
+ if (MemoryMap[i].PageAllocated == LastPageType &&
+ (i < NlsBasePage || i > NlsBasePage+TotalNLSSize) && (i != NoEntries-1)
)
+ {
+ PagesCount++;
+ }
+ else if (i == NlsBasePage)
+ {
+ // This is NLS data, map it accordingly
+ // It's VERY important for NT kernel - it calculates size of NLS
+ // tables based on NlsData memory type descriptors!
+
+ // Firstly map what we already have (if we have any)
+ // Convert mem types
+ if (LastPageType == 0)
+ NtType = LoaderFree;
+ else if (LastPageType != 0 && LastPageType != 1)
+ NtType = LoaderFirmwarePermanent;
+ else if (LastPageType == 1)
+ NtType = LoaderSystemCode;
+ else
+ NtType = LoaderFirmwarePermanent;
+
+ if (PagesCount > 0)
+ MempAddMemoryBlock(LoaderBlock, LastPageIndex, PagesCount, NtType);
+
+ // Then map nls data
+ MempAddMemoryBlock(LoaderBlock, NlsBasePage, TotalNLSSize, LoaderNlsData);
+
+ // skip them
+ i += TotalNLSSize;
+
+ // Reset our counter vars
+ LastPageIndex = i;
+ LastPageType = MemoryMap[i].PageAllocated;
+ PagesCount = 1;
+
+ continue;
+ }
+ else
+ {
+ // Add the resulting region
+
+ // Convert mem types
+ if (LastPageType == 0)
+ {
+ NtType = LoaderFree;
+ }
+ else if (LastPageType != 0 && LastPageType != 1)
+ {
+ NtType = LoaderFirmwarePermanent;
+ }
+ else if (LastPageType == 1)
+ {
+ NtType = LoaderSystemCode;
+ }
+ else
+ {
+ NtType = LoaderFirmwarePermanent;
+ }
+
+ MempAddMemoryBlock(LoaderBlock, LastPageIndex, PagesCount, NtType);
+
+ // Reset our counter vars
+ LastPageIndex = i;
+ LastPageType = MemoryMap[i].PageAllocated;
+ PagesCount = 1;
+ }
+ }
+
+ DbgPrint((DPRINT_WINDOWS, "MadCount: %d\n", MadCount));
+
+ WinLdrpDumpMemoryDescriptors(LoaderBlock); //FIXME: Delete!
+
+ // Map our loader image, so we can continue running
+ /*Status = MempSetupPaging(OsLoaderBase >> MM_PAGE_SHIFT, OsLoaderSize >>
MM_PAGE_SHIFT);
+ if (!Status)
+ {
+ UiMessageBox("Error during MempSetupPaging");
+ return;
+ }*/
+
+ //VideoDisplayString(L"Hello from VGA, going into the kernel\n");
+ DbgPrint((DPRINT_WINDOWS, "HalPT: 0x%X\n", HalPT));
+
+ // Page Tables have been setup, make special handling for PCR and TSS
+ // (which is done in BlSetupFotNt in usual ntldr)
+ HalPT[(KI_USER_SHARED_DATA - 0xFFC00000) >> MM_PAGE_SHIFT].PageFrameNumber =
PcrBasePage+1;
+ HalPT[(KI_USER_SHARED_DATA - 0xFFC00000) >> MM_PAGE_SHIFT].Valid = 1;
+ HalPT[(KI_USER_SHARED_DATA - 0xFFC00000) >> MM_PAGE_SHIFT].Write = 1;
+
+ HalPT[(KIP0PCRADDRESS - 0xFFC00000) >> MM_PAGE_SHIFT].PageFrameNumber =
PcrBasePage;
+ HalPT[(KIP0PCRADDRESS - 0xFFC00000) >> MM_PAGE_SHIFT].Valid = 1;
+ HalPT[(KIP0PCRADDRESS - 0xFFC00000) >> MM_PAGE_SHIFT].Write = 1;
+
+ // Map VGA memory
+ //VideoMemoryBase = MmMapIoSpace(0xb8000, 4000, MmNonCached);
+ //DbgPrint((DPRINT_WINDOWS, "VideoMemoryBase: 0x%X\n", VideoMemoryBase));
+
+ Tss = (PKTSS)(KSEG0_BASE | (TssBasePage << MM_PAGE_SHIFT));
+
+ // Fill the memory descriptor list and
+ //PrepareMemoryDescriptorList();
+ DbgPrint((DPRINT_WINDOWS, "Memory Descriptor List prepared, printing
PDE\n"));
+ List_PaToVa(&LoaderBlock->MemoryDescriptorListHead);
+
+ #if DEBUG
+ {
+ ULONG *PDE_Addr=(ULONG *)PDE;//0xC0300000;
+ int j;
+
+ DbgPrint((DPRINT_WINDOWS, "\nPDE\n"));
+
+ for (i=0; i<128; i++)
+ {
+ DbgPrint((DPRINT_WINDOWS, "0x%04X | ", i*8));
+
+ for (j=0; j<8; j++)
+ {
+ DbgPrint((DPRINT_WINDOWS, "0x%08X ", PDE_Addr[i*8+j]));
+ }
+
+ DbgPrint((DPRINT_WINDOWS, "\n"));
+ }
+ }
+ #endif
+
+
+ // Enable paging
+ //BS->ExitBootServices(ImageHandle,MapKey);
+
+ // Disable Interrupts
+ Ke386DisableInterrupts();
+
+ // Re-initalize EFLAGS
+ Ke386EraseFlags();
+
+ // Set the PDBR
+ Ke386SetPageTableDirectory((ULONG_PTR)PDE);
+
+ // Enable paging by modifying CR0
+ Ke386SetCr0(Ke386GetCr0() | CR0_PG);
+
+ // Set processor context
+ WinLdrSetProcessorContext(GdtIdt, KIP0PCRADDRESS, KSEG0_BASE | (TssBasePage <<
MM_PAGE_SHIFT));
+
+ // Zero KI_USER_SHARED_DATA page
+ memset((PVOID)KI_USER_SHARED_DATA, 0, MM_PAGE_SIZE);
+
+ return TRUE;
+}
+
+// Two special things this func does: it sorts descriptors,
+// and it merges free ones
+VOID
+WinLdrInsertDescriptor(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
+ IN PMEMORY_ALLOCATION_DESCRIPTOR NewDescriptor)
+{
+ PLIST_ENTRY ListHead = &LoaderBlock->MemoryDescriptorListHead;
+ PLIST_ENTRY PreviousEntry, NextEntry;
+ PMEMORY_ALLOCATION_DESCRIPTOR PreviousDescriptor = NULL, NextDescriptor = NULL;
+
+ DbgPrint((DPRINT_WINDOWS, "BP=0x%X PC=0x%X %s\n", NewDescriptor->BasePage,
+ NewDescriptor->PageCount, MemTypeDesc[NewDescriptor->MemoryType]));
+
+ /* Find a place where to insert the new descriptor to */
+ PreviousEntry = ListHead;
+ NextEntry = ListHead->Flink;
+ while (NextEntry != ListHead)
+ {
+ NextDescriptor = CONTAINING_RECORD(NextEntry,
+ MEMORY_ALLOCATION_DESCRIPTOR,
+ ListEntry);
+ if (NewDescriptor->BasePage < NextDescriptor->BasePage)
+ break;
+
+ PreviousEntry = NextEntry;
+ PreviousDescriptor = NextDescriptor;
+ NextEntry = NextEntry->Flink;
+ }
+
+ /* Don't forget about merging free areas */
+ if (NewDescriptor->MemoryType != LoaderFree)
+ {
+ /* Just insert, nothing to merge */
+ InsertHeadList(PreviousEntry, &NewDescriptor->ListEntry);
+ }
+ else
+ {
+ /* Previous block also free? */
+ if ((PreviousEntry != ListHead) && (PreviousDescriptor->MemoryType ==
LoaderFree) &&
+ ((PreviousDescriptor->BasePage + PreviousDescriptor->PageCount) ==
+ NewDescriptor->BasePage))
+ {
+ /* Just enlarge previous descriptor's PageCount */
+ PreviousDescriptor->PageCount += NewDescriptor->PageCount;
+ NewDescriptor = PreviousDescriptor;
+ }
+ else
+ {
+ /* Nope, just insert */
+ InsertHeadList(PreviousEntry, &NewDescriptor->ListEntry);
+ }
+
+ /* Next block is free ?*/
+ if ((NextEntry != ListHead) &&
+ (NextDescriptor->MemoryType == LoaderFree) &&
+ ((NewDescriptor->BasePage + NewDescriptor->PageCount) ==
NextDescriptor->BasePage))
+ {
+ /* Enlarge next descriptor's PageCount */
+ NewDescriptor->PageCount += NextDescriptor->PageCount;
+ RemoveEntryList(&NextDescriptor->ListEntry);
+ }
+ }
+
+ return;
+}
+
+VOID
+WinLdrSetProcessorContext(PVOID GdtIdt, IN ULONG Pcr, IN ULONG Tss)
+{
+ GDTIDT GdtDesc, IdtDesc, OldIdt;
+ PKGDTENTRY pGdt;
+ PKIDTENTRY pIdt;
+ ULONG Ldt = 0;
+ //ULONG i;
+
+ DbgPrint((DPRINT_WINDOWS, "GDtIdt %p, Pcr %p, Tss 0x%08X\n",
+ GdtIdt, Pcr, Tss));
+
+ // Kernel expects the PCR to be zero-filled on startup
+ // FIXME: Why zero it here when we can zero it right after allocation?
+ RtlZeroMemory((PVOID)Pcr, MM_PAGE_SIZE); //FIXME: Why zero only 1 page when we allocate
2?
+
+ // Get old values of GDT and IDT
+ Ke386GetGlobalDescriptorTable(GdtDesc);
+ Ke386GetInterruptDescriptorTable(IdtDesc);
+
+ // Save old IDT
+ OldIdt.Base = IdtDesc.Base;
+ OldIdt.Limit = IdtDesc.Limit;
+
+ // Prepare new IDT+GDT
+ GdtDesc.Base = KSEG0_BASE | (ULONG_PTR)GdtIdt;
+ GdtDesc.Limit = NUM_GDT * sizeof(KGDTENTRY) - 1;
+ IdtDesc.Base = (ULONG)((PUCHAR)GdtDesc.Base + GdtDesc.Limit + 1);
+ IdtDesc.Limit = NUM_IDT * sizeof(KIDTENTRY) - 1;
+
+ // ========================
+ // Fill all descriptors now
+ // ========================
+
+ pGdt = (PKGDTENTRY)GdtDesc.Base;
+ pIdt = (PKIDTENTRY)IdtDesc.Base;
+
+ //
+ // Code selector (0x8)
+ // Flat 4Gb
+ //
+ pGdt[1].LimitLow = 0xFFFF;
+ pGdt[1].BaseLow = 0;
+ pGdt[1].HighWord.Bytes.BaseMid = 0;
+ pGdt[1].HighWord.Bytes.Flags1 = 0x9A;
+ pGdt[1].HighWord.Bytes.Flags2 = 0xCF;
+ pGdt[1].HighWord.Bytes.BaseHi = 0;
+
+ //
+ // Data selector (0x10)
+ // Flat 4Gb
+ //
+ pGdt[2].LimitLow = 0xFFFF;
+ pGdt[2].BaseLow = 0;
+ pGdt[2].HighWord.Bytes.BaseMid = 0;
+ pGdt[2].HighWord.Bytes.Flags1 = 0x92;
+ pGdt[2].HighWord.Bytes.Flags2 = 0xCF;
+ pGdt[2].HighWord.Bytes.BaseHi = 0;
+
+ //
+ // Selector (0x18)
+ // Flat 2Gb
+ //
+ pGdt[3].LimitLow = 0xFFFF;
+ pGdt[3].BaseLow = 0;
+ pGdt[3].HighWord.Bytes.BaseMid = 0;
+ pGdt[3].HighWord.Bytes.Flags1 = 0xFA;
+ pGdt[3].HighWord.Bytes.Flags2 = 0xCF;
+ pGdt[3].HighWord.Bytes.BaseHi = 0;
+
+ //
+ // Selector (0x20)
+ // Flat 2Gb
+ //
+ pGdt[4].LimitLow = 0xFFFF;
+ pGdt[4].BaseLow = 0;
+ pGdt[4].HighWord.Bytes.BaseMid = 0;
+ pGdt[4].HighWord.Bytes.Flags1 = 0xF2;
+ pGdt[4].HighWord.Bytes.Flags2 = 0xCF;
+ pGdt[4].HighWord.Bytes.BaseHi = 0;
+
+ //
+ // TSS Selector (0x28)
+ //
+ pGdt[5].LimitLow = 0x78-1; // 60 dwords
+ pGdt[5].BaseLow = (USHORT)(Tss & 0xffff);
+ pGdt[5].HighWord.Bytes.BaseMid = (UCHAR)((Tss >> 16) & 0xff);
+ pGdt[5].HighWord.Bytes.Flags1 = 0x89;
+ pGdt[5].HighWord.Bytes.Flags2 = 0x00;
+ pGdt[5].HighWord.Bytes.BaseHi = (UCHAR)((Tss >> 24) & 0xff);
+
+ //
+ // PCR Selector (0x30)
+ //
+ pGdt[6].LimitLow = 0x01;
+ pGdt[6].BaseLow = (USHORT)(Pcr & 0xffff);
+ pGdt[6].HighWord.Bytes.BaseMid = (UCHAR)((Pcr >> 16) & 0xff);
+ pGdt[6].HighWord.Bytes.Flags1 = 0x92;
+ pGdt[6].HighWord.Bytes.Flags2 = 0xC0;
+ pGdt[6].HighWord.Bytes.BaseHi = (UCHAR)((Pcr >> 24) & 0xff);
+
+ //
+ // Selector (0x38)
+ //
+ pGdt[7].LimitLow = 0xFFFF;
+ pGdt[7].BaseLow = 0;
+ pGdt[7].HighWord.Bytes.BaseMid = 0;
+ pGdt[7].HighWord.Bytes.Flags1 = 0xF3;
+ pGdt[7].HighWord.Bytes.Flags2 = 0x40;
+ pGdt[7].HighWord.Bytes.BaseHi = 0;
+
+ //
+ // Some BIOS fuck (0x40)
+ //
+ pGdt[8].LimitLow = 0xFFFF;
+ pGdt[8].BaseLow = 0x400;
+ pGdt[8].HighWord.Bytes.BaseMid = 0;
+ pGdt[8].HighWord.Bytes.Flags1 = 0xF2;
+ pGdt[8].HighWord.Bytes.Flags2 = 0x0;
+ pGdt[8].HighWord.Bytes.BaseHi = 0;
+
+ //
+ // Selector (0x48)
+ //
+ pGdt[9].LimitLow = 0;
+ pGdt[9].BaseLow = 0;
+ pGdt[9].HighWord.Bytes.BaseMid = 0;
+ pGdt[9].HighWord.Bytes.Flags1 = 0;
+ pGdt[9].HighWord.Bytes.Flags2 = 0;
+ pGdt[9].HighWord.Bytes.BaseHi = 0;
+
+ //
+ // Selector (0x50)
+ //
+ pGdt[10].LimitLow = 0xFFFF; //FIXME: Not correct!
+ pGdt[10].BaseLow = 0;
+ pGdt[10].HighWord.Bytes.BaseMid = 0x2;
+ pGdt[10].HighWord.Bytes.Flags1 = 0x89;
+ pGdt[10].HighWord.Bytes.Flags2 = 0;
+ pGdt[10].HighWord.Bytes.BaseHi = 0;
+
+ //
+ // Selector (0x58)
+ //
+ pGdt[11].LimitLow = 0xFFFF;
+ pGdt[11].BaseLow = 0;
+ pGdt[11].HighWord.Bytes.BaseMid = 0x2;
+ pGdt[11].HighWord.Bytes.Flags1 = 0x9A;
+ pGdt[11].HighWord.Bytes.Flags2 = 0;
+ pGdt[11].HighWord.Bytes.BaseHi = 0;
+
+ //
+ // Selector (0x60)
+ //
+ pGdt[12].LimitLow = 0xFFFF;
+ pGdt[12].BaseLow = 0; //FIXME: Maybe not correct, but noone cares
+ pGdt[12].HighWord.Bytes.BaseMid = 0x2;
+ pGdt[12].HighWord.Bytes.Flags1 = 0x92;
+ pGdt[12].HighWord.Bytes.Flags2 = 0;
+ pGdt[12].HighWord.Bytes.BaseHi = 0;
+
+ //
+ // Video buffer Selector (0x68)
+ //
+ pGdt[13].LimitLow = 0x3FFF;
+ pGdt[13].BaseLow = 0x8000; //FIXME: I guess not correct for UGA
+ pGdt[13].HighWord.Bytes.BaseMid = 0x0B;
+ pGdt[13].HighWord.Bytes.Flags1 = 0x92;
+ pGdt[13].HighWord.Bytes.Flags2 = 0;
+ pGdt[13].HighWord.Bytes.BaseHi = 0;
+
+ //
+ // Points to GDT (0x70)
+ //
+ pGdt[14].LimitLow = NUM_GDT*sizeof(KGDTENTRY) - 1;
+ pGdt[14].BaseLow = 0x7000;
+ pGdt[14].HighWord.Bytes.BaseMid = 0xFF;
+ pGdt[14].HighWord.Bytes.Flags1 = 0x92;
+ pGdt[14].HighWord.Bytes.Flags2 = 0;
+ pGdt[14].HighWord.Bytes.BaseHi = 0xFF;
+
+ //
+ // Some unused descriptors should go here
+ // ...
+
+ //
+ // Fill IDT with Traps
+ //
+#if 0
+ pIdt[0].Offset = (i386DivideByZero | KSEG0_BASE) & 0xFFFF;
+ pIdt[0].ExtendedOffset = 0x8; // Selector
+ pIdt[0].Access = 0x8F00;
+ pIdt[0].Selector = (i386DivideByZero | KSEG0_BASE) >> 16; // Extended Offset
+
+ pIdt[1].Offset = (i386DebugException | KSEG0_BASE) & 0xFFFF;
+ pIdt[1].ExtendedOffset = 0x8; // Selector
+ pIdt[1].Access = 0x8F00;
+ pIdt[1].Selector = (i386DebugException | KSEG0_BASE) >> 16; // Extended Offset
+
+ pIdt[2].Offset = (i386NMIException | KSEG0_BASE) & 0xFFFF;
+ pIdt[2].ExtendedOffset = 0x8; // Selector
+ pIdt[2].Access = 0x8F00;
+ pIdt[2].Selector = (i386NMIException | KSEG0_BASE) >> 16; // Extended Offset
+
+ pIdt[3].Offset = (i386Breakpoint | KSEG0_BASE) & 0xFFFF;
+ pIdt[3].ExtendedOffset = 0x8; // Selector
+ pIdt[3].Access = 0x8F00;
+ pIdt[3].Selector = (i386Breakpoint | KSEG0_BASE) >> 16; // Extended Offset
+
+ pIdt[4].Offset = (i386Overflow | KSEG0_BASE) & 0xFFFF;
+ pIdt[4].ExtendedOffset = 0x8; // Selector
+ pIdt[4].Access = 0x8F00;
+ pIdt[4].Selector = (i386Overflow | KSEG0_BASE) >> 16; // Extended Offset
+
+ pIdt[5].Selector = (i386BoundException | KSEG0_BASE) >> 16; // Extended Offset
+ pIdt[5].Offset = (i386BoundException | KSEG0_BASE) & 0xFFFF;
+ pIdt[5].ExtendedOffset = 0x8; // Selector
+ pIdt[5].Access = 0x8F00;
+
+ pIdt[6].Selector = (i386InvalidOpcode | KSEG0_BASE) >> 16; // Extended Offset
+ pIdt[6].Offset = (i386InvalidOpcode | KSEG0_BASE) & 0xFFFF;
+ pIdt[6].ExtendedOffset = 0x8; // Selector
+ pIdt[6].Access = 0x8F00;
+
+ pIdt[7].Selector = (i386FPUNotAvailable | KSEG0_BASE) >> 16; // Extended Offset
+ pIdt[7].Offset = (i386FPUNotAvailable | KSEG0_BASE) & 0xFFFF;
+ pIdt[7].ExtendedOffset = 0x8; // Selector
+ pIdt[7].Access = 0x8F00;
+
+ pIdt[8].Selector = (i386DoubleFault | KSEG0_BASE) >> 16; // Extended Offset
+ pIdt[8].Offset = (i386DoubleFault | KSEG0_BASE) & 0xFFFF;
+ pIdt[8].ExtendedOffset = 0x8; // Selector
+ pIdt[8].Access = 0x8F00;
+
+ pIdt[9].Selector = (i386CoprocessorSegment | KSEG0_BASE) >> 16; // Extended
Offset
+ pIdt[9].Offset = (i386CoprocessorSegment | KSEG0_BASE) & 0xFFFF;
+ pIdt[9].ExtendedOffset = 0x8; // Selector
+ pIdt[9].Access = 0x8F00;
+
+ pIdt[10].Selector = (i386InvalidTSS | KSEG0_BASE) >> 16; // Extended Offset
+ pIdt[10].Offset = (i386InvalidTSS | KSEG0_BASE) & 0xFFFF;
+ pIdt[10].ExtendedOffset = 0x8; // Selector
+ pIdt[10].Access = 0x8F00;
+
+ pIdt[11].Selector = (i386SegmentNotPresent | KSEG0_BASE) >> 16; // Extended
Offset
+ pIdt[11].Offset = (i386SegmentNotPresent | KSEG0_BASE) & 0xFFFF;
+ pIdt[11].ExtendedOffset = 0x8; // Selector
+ pIdt[11].Access = 0x8F00;
+
+ pIdt[12].Selector = (i386StackException | KSEG0_BASE) >> 16; // Extended Offset
+ pIdt[12].Offset = (i386StackException | KSEG0_BASE) & 0xFFFF;
+ pIdt[12].ExtendedOffset = 0x8; // Selector
+ pIdt[12].Access = 0x8F00;
+
+ pIdt[13].Selector = (i386GeneralProtectionFault | KSEG0_BASE) >> 16; // Extended
Offset
+ pIdt[13].Offset = (i386GeneralProtectionFault | KSEG0_BASE) & 0xFFFF;
+ pIdt[13].ExtendedOffset = 0x8; // Selector
+ pIdt[13].Access = 0x8F00;
+
+ pIdt[14].Selector = (i386PageFault | KSEG0_BASE) >> 16; // Extended Offset
+ pIdt[14].Offset = (i386PageFault | KSEG0_BASE) & 0xFFFF;
+ pIdt[14].ExtendedOffset = 0x8; // Selector
+ pIdt[14].Access = 0x8F00;
+
+ pIdt[15].Selector = 0; // Extended Offset
+ pIdt[15].Offset = 0;
+ pIdt[15].ExtendedOffset = 0; // Selector
+ pIdt[15].Access = 0;
+
+ pIdt[16].Selector = (i386CoprocessorError | KSEG0_BASE) >> 16; // Extended Offset
+ pIdt[16].Offset = (i386CoprocessorError | KSEG0_BASE) & 0xFFFF;
+ pIdt[16].ExtendedOffset = 0x8; // Selector
+ pIdt[16].Access = 0x8F00;
+
+ pIdt[17].Selector = (i386AlignmentCheck | KSEG0_BASE) >> 16; // Extended Offset
+ pIdt[17].Offset = (i386AlignmentCheck | KSEG0_BASE) & 0xFFFF;
+ pIdt[17].ExtendedOffset = 0x8; // Selector
+ pIdt[17].Access = 0x8F00;
+#endif
+
+ /*for (i=0; i<16; i++)
+ {
+ //pIdt[i].Offset = ((ULONG_PTR)i386GeneralProtectionFault | KSEG0_BASE) & 0xFFFF;
+ //pIdt[i].ExtendedOffset = 0x8; // Selector
+ //pIdt[i].Access = 0x8F00;
+ //pIdt[i].Selector = ((ULONG_PTR)i386GeneralProtectionFault | KSEG0_BASE) >> 16;
// Extended Offset
+
+ pIdt[i].Offset = ((ULONG_PTR)i386GeneralProtectionFault | KSEG0_BASE) & 0xFFFF;
+ pIdt[i].ExtendedOffset = ((ULONG_PTR)i386GeneralProtectionFault | KSEG0_BASE) >>
16; // Extended Offset
+ pIdt[i].Access = 0x8F00;
+ pIdt[i].Selector = 0x8;
+ }*/
+
+ // Copy the old IDT
+ RtlCopyMemory(pIdt, (PVOID)OldIdt.Base, OldIdt.Limit);
+
+
+ // Mask interrupts
+ //asm("cli\n"); // they are already masked before enabling paged mode
+
+ // Load GDT+IDT
+ Ke386SetGlobalDescriptorTable(GdtDesc);
+ Ke386SetInterruptDescriptorTable(IdtDesc);
+
+ // Jump to proper CS and clear prefetch queue
+ asm("ljmp $0x08, $mb1\n"
+ "mb1:\n");
+
+ // Set SS selector
+ asm(".intel_syntax noprefix\n");
+ asm("mov ax, 0x10\n"); // DataSelector=0x10
+ asm("mov ss, ax\n");
+ asm(".att_syntax\n");
+
+ // Set DS and ES selectors
+ Ke386SetDs(0x10);
+ Ke386SetEs(0x10); // this is vital for rep stosd
+
+ // LDT = not used ever, thus set to 0
+ Ke386SetLocalDescriptorTable(Ldt);
+
+ // Load TSR
+ Ke386SetTr(0x28);
+
+ // Clear GS
+ asm(".intel_syntax noprefix\n");
+ asm("push 0\n");
+ asm("pop gs\n");
+ asm(".att_syntax\n");
+
+ // Set FS to PCR
+ Ke386SetFs(0x30);
+
+ // Real end of the function, just for information
+ /* do not uncomment!
+ pop edi;
+ pop esi;
+ pop ebx;
+ mov esp, ebp;
+ pop ebp;
+ ret
+ */
+}
Propchange: trunk/reactos/boot/freeldr/freeldr/windows/wlmemory.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/boot/freeldr/freeldr/windows/wlregistry.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/windo…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/windows/wlregistry.c (original)
+++ trunk/reactos/boot/freeldr/freeldr/windows/wlregistry.c Tue Oct 10 19:20:03 2006
@@ -12,6 +12,9 @@
#define NDEBUG
#include <debug.h>
+
+// The only global var here, used to mark mem pages as NLS in WinLdrTurnOnPaging()
+ULONG TotalNLSSize = 0;
BOOLEAN WinLdrGetNLSNames(LPSTR AnsiName,
LPSTR OemName,
@@ -327,6 +330,9 @@
MM_SIZE_TO_PAGES(OemFileSize) +
MM_SIZE_TO_PAGES(LanguageFileSize);
+ /* Store it for later marking the pages as NlsData type */
+ TotalNLSSize = TotalSize;
+
NlsDataBase = (ULONG_PTR)MmAllocateMemory(TotalSize*MM_PAGE_SIZE);
if (NlsDataBase == 0)