[ros-diffs] [fireball] 24483: - 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

fireball at svn.reactos.org fireball at svn.reactos.org
Tue Oct 10 17:20:06 CEST 2006


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/windows/wlmemory.c?rev=24483&r1=24482&r2=24483&view=diff
==============================================================================
--- 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 at 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 at 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/windows/wlregistry.c?rev=24483&r1=24482&r2=24483&view=diff
==============================================================================
--- 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)




More information about the Ros-diffs mailing list