Fix a couple of problems with FreeLDR portability.
[reactos.git] / reactos / boot / freeldr / freeldr / arch / i386 / loader.c
index 2756755..f5a0959 100644 (file)
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-
+#define _NTSYSTEM_
 #include <freeldr.h>
 
 #define NDEBUG
 #include <debug.h>
-
-/* Base Addres of Kernel in Physical Memory */
-#define KERNEL_BASE_PHYS 0x200000
-
-/* Bits to shift to convert a Virtual Address into an Offset in the Page Table */
-#define PFN_SHIFT 12
-
-/* Bits to shift to convert a Virtual Address into an Offset in the Page Directory */
-#define PDE_SHIFT 22
-#define PDE_SHIFT_PAE 18
-
-
-/* Converts a Relative Address read from the Kernel into a Physical Address */
-#define RaToPa(p) \
-    (ULONG_PTR)((ULONG_PTR)p + KERNEL_BASE_PHYS)
-
-/* Converts a Physical Address Pointer into a Page Frame Number */
-#define PaPtrToPfn(p) \
-    (((ULONG_PTR)&p) >> PFN_SHIFT)
-
-/* Converts a Physical Address into a Page Frame Number */
-#define PaToPfn(p) \
-    ((p) >> PFN_SHIFT)
-
-#define STARTUP_BASE                0xC0000000
-#define HYPERSPACE_BASE             0xC0400000
-#define HYPERSPACE_PAE_BASE         0xC0800000
-#define APIC_BASE                   0xFEC00000
-#define KPCR_BASE                   0xFF000000
-
-#define LowMemPageTableIndex        0
-#define StartupPageTableIndex       (STARTUP_BASE >> 22)
-#define HyperspacePageTableIndex    (HYPERSPACE_BASE >> 22)
-#define KpcrPageTableIndex          (KPCR_BASE >> 22)
-#define ApicPageTableIndex          (APIC_BASE >> 22)
-
-#define LowMemPageTableIndexPae     0
-#define StartupPageTableIndexPae    (STARTUP_BASE >> 21)
-#define HyperspacePageTableIndexPae (HYPERSPACE_PAE_BASE >> 21)
-#define KpcrPageTableIndexPae       (KPCR_BASE >> 21)
-#define ApicPageTableIndexPae       (APIC_BASE >> 21)
-
-
-#define KernelEntryPoint            (KernelEntry - KERNEL_BASE_PHYS) + KernelBase
-
-/* Load Address of Next Module */
-ULONG_PTR NextModuleBase = 0;
-
-/* Currently Opened Module */
-PLOADER_MODULE CurrentModule = NULL;
-
-/* Unrelocated Kernel Base in Virtual Memory */
-ULONG_PTR KernelBase;
-
-/* Whether PAE is to be used or not */
-BOOLEAN PaeModeEnabled;
-
-/* Kernel Entrypoint in Physical Memory */
-ULONG_PTR KernelEntry;
-
-typedef struct _HARDWARE_PTE_X64 {
-    ULONG Valid             : 1;
-    ULONG Write             : 1;
-    ULONG Owner             : 1;
-    ULONG WriteThrough      : 1;
-    ULONG CacheDisable      : 1;
-    ULONG Accessed          : 1;
-    ULONG Dirty             : 1;
-    ULONG LargePage         : 1;
-    ULONG Global            : 1;
-    ULONG CopyOnWrite       : 1;
-    ULONG Prototype         : 1;
-    ULONG reserved          : 1;
-    ULONG PageFrameNumber   : 20;
-    ULONG reserved2         : 31;
-    ULONG NoExecute         : 1;
-} HARDWARE_PTE_X64, *PHARDWARE_PTE_X64;
-
-typedef struct _PAGE_DIRECTORY_X86 {
-    HARDWARE_PTE Pde[1024];
-} PAGE_DIRECTORY_X86, *PPAGE_DIRECTORY_X86;
-
-typedef struct _PAGE_DIRECTORY_X64 {
-    HARDWARE_PTE_X64 Pde[2048];
-} PAGE_DIRECTORY_X64, *PPAGE_DIRECTORY_X64;
-
-typedef struct _PAGE_DIRECTORY_TABLE_X64 {
-    HARDWARE_PTE_X64 Pde[4];
-} PAGE_DIRECTORY_TABLE_X64, *PPAGE_DIRECTORY_TABLE_X64;
+#undef DbgPrint
 
 /* Page Directory and Tables for non-PAE Systems */
 extern PAGE_DIRECTORY_X86 startup_pagedirectory;
 extern PAGE_DIRECTORY_X86 lowmem_pagetable;
 extern PAGE_DIRECTORY_X86 kernel_pagetable;
-extern ULONG_PTR hyperspace_pagetable;
-extern ULONG_PTR _pae_pagedirtable;
+extern PAGE_DIRECTORY_X86 hyperspace_pagetable;
 extern PAGE_DIRECTORY_X86 apic_pagetable;
 extern PAGE_DIRECTORY_X86 kpcr_pagetable;
-
-/* Page Directory and Tables for PAE Systems */
-extern PAGE_DIRECTORY_TABLE_X64 startup_pagedirectorytable_pae;
-extern PAGE_DIRECTORY_X64 startup_pagedirectory_pae;
-extern PAGE_DIRECTORY_X64 lowmem_pagetable_pae;
-extern PAGE_DIRECTORY_X64 kernel_pagetable_pae;
-extern ULONG_PTR hyperspace_pagetable_pae;
-extern ULONG_PTR pagedirtable_pae;
-extern PAGE_DIRECTORY_X64 apic_pagetable_pae;
-extern PAGE_DIRECTORY_X64 kpcr_pagetable_pae;
-
+extern PAGE_DIRECTORY_X86 kuser_pagetable;
+extern ULONG_PTR KernelBase;
+extern ROS_KERNEL_ENTRY_POINT KernelEntryPoint;
 /* FUNCTIONS *****************************************************************/
 
 /*++
@@ -159,9 +62,6 @@ FrLdrStartup(ULONG Magic)
     /* Re-initalize EFLAGS */
     Ke386EraseFlags();
 
-    /* Get the PAE Mode */
-    FrLdrGetPaeMode();
-
     /* Initialize the page directory */
     FrLdrSetupPageDirectory();
 
@@ -191,129 +91,15 @@ FASTCALL
 FrLdrSetupPae(ULONG Magic)
 {
     ULONG_PTR PageDirectoryBaseAddress = (ULONG_PTR)&startup_pagedirectory;
-    ASMCODE PagedJump;
-
-    if (PaeModeEnabled)
-    {
-        PageDirectoryBaseAddress = (ULONG_PTR)&startup_pagedirectorytable_pae;
-
-        /* Enable PAE */
-        Ke386SetCr4(Ke386GetCr4() | X86_CR4_PAE);
-    }
 
     /* Set the PDBR */
-    Ke386SetCr3(PageDirectoryBaseAddress);
+    __writecr3(PageDirectoryBaseAddress);
 
     /* Enable Paging and Write Protect*/
-    Ke386SetCr0(Ke386GetCr0() | X86_CR0_PG | X86_CR0_WP);
+    __writecr0(__readcr0() | X86_CR0_PG | X86_CR0_WP);
 
     /* Jump to Kernel */
-    PagedJump = (ASMCODE)(PVOID)(KernelEntryPoint);
-    PagedJump(Magic, &LoaderBlock);
-}
-
-/*++
- * FrLdrGetKernelBase
- * INTERNAL
- *
- *     Gets the Kernel Base to use.
- *
- * Params:
- *
- * Returns:
- *     None.
- *
- * Remarks:
- *     Sets both the FreeLdr internal variable as well as the one which
- *     will be used by the Kernel.
- *
- *--*/
-static VOID
-FASTCALL
-FrLdrGetKernelBase(VOID)
-{
-    PCHAR p;
-
-    /* Set KernelBase */
-    LoaderBlock.KernelBase = KernelBase;
-
-    /* Read Command Line */
-    p = (PCHAR)LoaderBlock.CommandLine;
-    while ((p = strchr(p, '/')) != NULL) {
-
-        /* Find "/3GB" */
-        if (!_strnicmp(p + 1, "3GB", 3)) {
-
-            /* Make sure there's nothing following it */
-            if (p[4] == ' ' || p[4] == 0) {
-
-                /* Use 3GB */
-                KernelBase = 0xE0000000;
-                LoaderBlock.KernelBase = 0xC0000000;
-            }
-        }
-
-        p++;
-    }
-}
-
-/*++
- * FrLdrGetPaeMode
- * INTERNAL
- *
- *     Determines whether PAE mode should be enabled or not.
- *
- * Params:
- *     None.
- *
- * Returns:
- *     None.
- *
- * Remarks:
- *     None.
- *
- *--*/
-VOID
-FASTCALL
-FrLdrGetPaeMode(VOID)
-{
-    BOOLEAN PaeModeSupported;
-
-    PaeModeSupported = FALSE;
-    PaeModeEnabled = FALSE;
-
-    if (CpuidSupported() & 1)
-    {
-       ULONG eax, ebx, ecx, FeatureBits;
-       GetCpuid(1, &eax, &ebx, &ecx, &FeatureBits);
-       if (FeatureBits & X86_FEATURE_PAE)
-       {
-          PaeModeSupported = TRUE;
-       }
-    }
-
-    if (PaeModeSupported)
-    {
-       PCHAR p;
-
-       /* Read Command Line */
-       p = (PCHAR)LoaderBlock.CommandLine;
-       while ((p = strchr(p, '/')) != NULL) {
-
-          p++;
-          /* Find "PAE" */
-          if (!_strnicmp(p, "PAE", 3)) {
-
-              /* Make sure there's nothing following it */
-              if (p[3] == ' ' || p[3] == 0) {
-
-                  /* Use Pae */
-                  PaeModeEnabled = TRUE;
-                  break;
-              }
-          }
-       }
-    }
+    (*KernelEntryPoint)(Magic, &LoaderBlock);
 }
 
 /*++
@@ -338,481 +124,83 @@ FASTCALL
 FrLdrSetupPageDirectory(VOID)
 {
     PPAGE_DIRECTORY_X86 PageDir;
-    PPAGE_DIRECTORY_TABLE_X64 PageDirTablePae;
-    PPAGE_DIRECTORY_X64 PageDirPae;
     ULONG KernelPageTableIndex;
     ULONG i;
 
-    if (PaeModeEnabled) {
-
-        /* Get the Kernel Table Index */
-        KernelPageTableIndex = (KernelBase >> 21);
-
-        /* Get the Startup Page Directory Table */
-        PageDirTablePae = (PPAGE_DIRECTORY_TABLE_X64)&startup_pagedirectorytable_pae;
-
-        /* Get the Startup Page Directory */
-        PageDirPae = (PPAGE_DIRECTORY_X64)&startup_pagedirectory_pae;
-
-        /* Set the Startup page directory table */
-        for (i = 0; i < 4; i++)
-        {
-            PageDirTablePae->Pde[i].Valid = 1;
-            PageDirTablePae->Pde[i].PageFrameNumber = PaPtrToPfn(startup_pagedirectory_pae) + i;
-        }
-
-        /* Set up the Low Memory PDE */
-        for (i = 0; i < 2; i++)
-        {
-            PageDirPae->Pde[LowMemPageTableIndexPae + i].Valid = 1;
-            PageDirPae->Pde[LowMemPageTableIndexPae + i].Write = 1;
-            PageDirPae->Pde[LowMemPageTableIndexPae + i].PageFrameNumber = PaPtrToPfn(lowmem_pagetable_pae) + i;
-        }
-
-        /* Set up the Kernel PDEs */
-        for (i = 0; i < 3; i++)
-        {
-            PageDirPae->Pde[KernelPageTableIndex + i].Valid = 1;
-            PageDirPae->Pde[KernelPageTableIndex + i].Write = 1;
-            PageDirPae->Pde[KernelPageTableIndex + i].PageFrameNumber = PaPtrToPfn(kernel_pagetable_pae) + i;
-        }
-
-        /* Set up the Startup PDE */
-        for (i = 0; i < 4; i++)
-        {
-            PageDirPae->Pde[StartupPageTableIndexPae + i].Valid = 1;
-            PageDirPae->Pde[StartupPageTableIndexPae + i].Write = 1;
-            PageDirPae->Pde[StartupPageTableIndexPae + i].PageFrameNumber = PaPtrToPfn(startup_pagedirectory_pae) + i;
-        }
-
-        /* Set up the Hyperspace PDE */
-        for (i = 0; i < 2; i++)
-        {
-            PageDirPae->Pde[HyperspacePageTableIndexPae + i].Valid = 1;
-            PageDirPae->Pde[HyperspacePageTableIndexPae + i].Write = 1;
-            PageDirPae->Pde[HyperspacePageTableIndexPae + i].PageFrameNumber = PaPtrToPfn(hyperspace_pagetable_pae) + i;
-        }
-
-        /* Set up the Apic PDE */
-        for (i = 0; i < 2; i++)
-        {
-            PageDirPae->Pde[ApicPageTableIndexPae + i].Valid = 1;
-            PageDirPae->Pde[ApicPageTableIndexPae + i].Write = 1;
-            PageDirPae->Pde[ApicPageTableIndexPae + i].PageFrameNumber = PaPtrToPfn(apic_pagetable_pae) + i;
-        }
-
-        /* Set up the KPCR PDE */
-        PageDirPae->Pde[KpcrPageTableIndexPae].Valid = 1;
-        PageDirPae->Pde[KpcrPageTableIndexPae].Write = 1;
-        PageDirPae->Pde[KpcrPageTableIndexPae].PageFrameNumber = PaPtrToPfn(kpcr_pagetable_pae);
-
-        /* Set up Low Memory PTEs */
-        PageDirPae = (PPAGE_DIRECTORY_X64)&lowmem_pagetable_pae;
-        for (i=0; i<1024; i++) {
-
-            PageDirPae->Pde[i].Valid = 1;
-            PageDirPae->Pde[i].Write = 1;
-            PageDirPae->Pde[i].Owner = 1;
-            PageDirPae->Pde[i].PageFrameNumber = i;
-        }
-
-        /* Set up Kernel PTEs */
-        PageDirPae = (PPAGE_DIRECTORY_X64)&kernel_pagetable_pae;
-        for (i=0; i<1536; i++) {
-
-            PageDirPae->Pde[i].Valid = 1;
-            PageDirPae->Pde[i].Write = 1;
-            PageDirPae->Pde[i].PageFrameNumber = PaToPfn(KERNEL_BASE_PHYS) + i;
-        }
-
-        /* Set up APIC PTEs */
-        PageDirPae = (PPAGE_DIRECTORY_X64)&apic_pagetable_pae;
-        PageDirPae->Pde[0].Valid = 1;
-        PageDirPae->Pde[0].Write = 1;
-        PageDirPae->Pde[0].CacheDisable = 1;
-        PageDirPae->Pde[0].WriteThrough = 1;
-        PageDirPae->Pde[0].PageFrameNumber = PaToPfn(APIC_BASE);
-        PageDirPae->Pde[0x200].Valid = 1;
-        PageDirPae->Pde[0x200].Write = 1;
-        PageDirPae->Pde[0x200].CacheDisable = 1;
-        PageDirPae->Pde[0x200].WriteThrough = 1;
-        PageDirPae->Pde[0x200].PageFrameNumber = PaToPfn(APIC_BASE + KERNEL_BASE_PHYS);
-
-        /* Set up KPCR PTEs */
-        PageDirPae = (PPAGE_DIRECTORY_X64)&kpcr_pagetable_pae;
-        PageDirPae->Pde[0].Valid = 1;
-        PageDirPae->Pde[0].Write = 1;
-        PageDirPae->Pde[0].PageFrameNumber = 1;
-
-    } else {
-
-        /* Get the Kernel Table Index */
-        KernelPageTableIndex = KernelBase >> PDE_SHIFT;
-
-        /* Get the Startup Page Directory */
-        PageDir = (PPAGE_DIRECTORY_X86)&startup_pagedirectory;
-
-        /* Set up the Low Memory PDE */
-        PageDir->Pde[LowMemPageTableIndex].Valid = 1;
-        PageDir->Pde[LowMemPageTableIndex].Write = 1;
-        PageDir->Pde[LowMemPageTableIndex].PageFrameNumber = PaPtrToPfn(lowmem_pagetable);
-
-        /* Set up the Kernel PDEs */
-        PageDir->Pde[KernelPageTableIndex].Valid = 1;
-        PageDir->Pde[KernelPageTableIndex].Write = 1;
-        PageDir->Pde[KernelPageTableIndex].PageFrameNumber = PaPtrToPfn(kernel_pagetable);
-        PageDir->Pde[KernelPageTableIndex + 1].Valid = 1;
-        PageDir->Pde[KernelPageTableIndex + 1].Write = 1;
-        PageDir->Pde[KernelPageTableIndex + 1].PageFrameNumber = PaPtrToPfn(kernel_pagetable + 4096);
-
-        /* Set up the Startup PDE */
-        PageDir->Pde[StartupPageTableIndex].Valid = 1;
-        PageDir->Pde[StartupPageTableIndex].Write = 1;
-        PageDir->Pde[StartupPageTableIndex].PageFrameNumber = PaPtrToPfn(startup_pagedirectory);
-
-        /* Set up the Hyperspace PDE */
-        PageDir->Pde[HyperspacePageTableIndex].Valid = 1;
-        PageDir->Pde[HyperspacePageTableIndex].Write = 1;
-        PageDir->Pde[HyperspacePageTableIndex].PageFrameNumber = PaPtrToPfn(hyperspace_pagetable);
-
-        /* Set up the Apic PDE */
-        PageDir->Pde[ApicPageTableIndex].Valid = 1;
-        PageDir->Pde[ApicPageTableIndex].Write = 1;
-        PageDir->Pde[ApicPageTableIndex].PageFrameNumber = PaPtrToPfn(apic_pagetable);
-
-        /* Set up the KPCR PDE */
-        PageDir->Pde[KpcrPageTableIndex].Valid = 1;
-        PageDir->Pde[KpcrPageTableIndex].Write = 1;
-        PageDir->Pde[KpcrPageTableIndex].PageFrameNumber = PaPtrToPfn(kpcr_pagetable);
-
-        /* Set up Low Memory PTEs */
-        PageDir = (PPAGE_DIRECTORY_X86)&lowmem_pagetable;
-        for (i=0; i<1024; i++) {
-
-            PageDir->Pde[i].Valid = 1;
-            PageDir->Pde[i].Write = 1;
-            PageDir->Pde[i].Owner = 1;
-            PageDir->Pde[i].PageFrameNumber = PaToPfn(i * PAGE_SIZE);
-        }
-
-        /* Set up Kernel PTEs */
-        PageDir = (PPAGE_DIRECTORY_X86)&kernel_pagetable;
-        for (i=0; i<1536; i++) {
-
-            PageDir->Pde[i].Valid = 1;
-            PageDir->Pde[i].Write = 1;
-            PageDir->Pde[i].PageFrameNumber = PaToPfn(KERNEL_BASE_PHYS + i * PAGE_SIZE);
-        }
-
-        /* Set up APIC PTEs */
-        PageDir = (PPAGE_DIRECTORY_X86)&apic_pagetable;
-        PageDir->Pde[0].Valid = 1;
-        PageDir->Pde[0].Write = 1;
-        PageDir->Pde[0].CacheDisable = 1;
-        PageDir->Pde[0].WriteThrough = 1;
-        PageDir->Pde[0].PageFrameNumber = PaToPfn(APIC_BASE);
-        PageDir->Pde[0x200].Valid = 1;
-        PageDir->Pde[0x200].Write = 1;
-        PageDir->Pde[0x200].CacheDisable = 1;
-        PageDir->Pde[0x200].WriteThrough = 1;
-        PageDir->Pde[0x200].PageFrameNumber = PaToPfn(APIC_BASE + KERNEL_BASE_PHYS);
-
-        /* Set up KPCR PTEs */
-        PageDir = (PPAGE_DIRECTORY_X86)&kpcr_pagetable;
-        PageDir->Pde[0].Valid = 1;
-        PageDir->Pde[0].Write = 1;
-        PageDir->Pde[0].PageFrameNumber = 1;
-    }
-    return;
-}
-
-/*++
- * FrLdrMapKernel
- * INTERNAL
- *
- *     Maps the Kernel into memory, does PE Section Mapping, initalizes the
- *     uninitialized data sections, and relocates the image.
- *
- * Params:
- *     KernelImage - FILE Structure representing the ntoskrnl image file.
- *
- * Returns:
- *     TRUE if the Kernel was mapped.
- *
- * Remarks:
- *     None.
- *
- *--*/
-BOOLEAN
-NTAPI
-FrLdrMapKernel(FILE *KernelImage)
-{
-    PIMAGE_DOS_HEADER ImageHeader;
-    PIMAGE_NT_HEADERS NtHeader;
-    PIMAGE_SECTION_HEADER Section;
-    ULONG SectionCount;
-    ULONG ImageSize;
-    ULONG_PTR SourceSection;
-    ULONG_PTR TargetSection;
-    ULONG SectionSize;
-    INT i;
-    PIMAGE_DATA_DIRECTORY RelocationDDir;
-    PIMAGE_BASE_RELOCATION RelocationDir, RelocationEnd;
-    ULONG Count;
-    ULONG_PTR Address, MaxAddress;
-    PUSHORT TypeOffset;
-    ULONG_PTR Delta;
-    PUSHORT ShortPtr;
-    PULONG LongPtr;
-
-    /* Allocate 1024 bytes for PE Header */
-    ImageHeader = (PIMAGE_DOS_HEADER)MmAllocateMemory(1024);
-
-    /* Make sure it was succesful */
-    if (ImageHeader == NULL) {
-
-        return FALSE;
-    }
-
-    /* Load the first 1024 bytes of the kernel image so we can read the PE header */
-    if (!FsReadFile(KernelImage, 1024, NULL, ImageHeader)) {
-
-        /* Fail if we couldn't read */
-        MmFreeMemory(ImageHeader);
-        return FALSE;
-    }
-
-    /* Now read the MZ header to get the offset to the PE Header */
-    NtHeader = (PIMAGE_NT_HEADERS)((PCHAR)ImageHeader + ImageHeader->e_lfanew);
-
-    /* Get Kernel Base */
-    KernelBase = NtHeader->OptionalHeader.ImageBase;
-    FrLdrGetKernelBase();
-
-    /* Save Entrypoint */
-    KernelEntry = RaToPa(NtHeader->OptionalHeader.AddressOfEntryPoint);
-
-    /* Save the Image Size */
-    ImageSize = NtHeader->OptionalHeader.SizeOfImage;
-
-    /* Free the Header */
-    MmFreeMemory(ImageHeader);
-
-    /* Set the file pointer to zero */
-    FsSetFilePointer(KernelImage, 0);
-
-    /* Load the file image */
-    FsReadFile(KernelImage, ImageSize, NULL, (PVOID)KERNEL_BASE_PHYS);
-
-    /* Reload the NT Header */
-    NtHeader = (PIMAGE_NT_HEADERS)((PCHAR)KERNEL_BASE_PHYS + ImageHeader->e_lfanew);
-
-    /* Load the first section */
-    Section = IMAGE_FIRST_SECTION(NtHeader);
-    SectionCount = NtHeader->FileHeader.NumberOfSections - 1;
-
-    /* Now go to the last section */
-    Section += SectionCount;
-
-    /* Walk each section backwards */
-    for (i=(INT)SectionCount; i >= 0; i--, Section--) {
-
-        /* Get the disk location and the memory location, and the size */
-        SourceSection = RaToPa(Section->PointerToRawData);
-        TargetSection = RaToPa(Section->VirtualAddress);
-        SectionSize = Section->SizeOfRawData;
-
-        /* If the section is already mapped correctly, go to the next */
-        if (SourceSection == TargetSection) continue;
-
-        /* Load it into memory */
-        memmove((PVOID)TargetSection, (PVOID)SourceSection, SectionSize);
-
-        /* Check for unitilizated data */
-        if (Section->SizeOfRawData < Section->Misc.VirtualSize) {
-
-            /* Zero it out */
-            memset((PVOID)RaToPa(Section->VirtualAddress + Section->SizeOfRawData),
-                   0,
-                   Section->Misc.VirtualSize - Section->SizeOfRawData);
-        }
-    }
-
-    /* Get the Relocation Data Directory */
-    RelocationDDir = &NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
-
-    /* Get the Relocation Section Start and End*/
-    RelocationDir = (PIMAGE_BASE_RELOCATION)(KERNEL_BASE_PHYS + RelocationDDir->VirtualAddress);
-    RelocationEnd = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDDir->Size);
-
-    /* Calculate Difference between Real Base and Compiled Base*/
-    Delta = KernelBase - NtHeader->OptionalHeader.ImageBase;
-
-    /* Determine how far we shoudl relocate */
-    MaxAddress = KERNEL_BASE_PHYS + ImageSize;
-
-    /* Relocate until we've processed all the blocks */
-    while (RelocationDir < RelocationEnd && RelocationDir->SizeOfBlock > 0) {
-
-        /* See how many Relocation Blocks we have */
-        Count = (RelocationDir->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT);
-
-        /* Calculate the Address of this Directory */
-        Address = KERNEL_BASE_PHYS + RelocationDir->VirtualAddress;
-
-        /* Calculate the Offset of the Type */
-        TypeOffset = (PUSHORT)(RelocationDir + 1);
-
-        for (i = 0; i < (INT)Count; i++) {
-
-            ShortPtr = (PUSHORT)(Address + (*TypeOffset & 0xFFF));
-
-            switch (*TypeOffset >> 12) {
-
-                case IMAGE_REL_BASED_ABSOLUTE:
-                    break;
-
-                case IMAGE_REL_BASED_HIGH:
-                    *ShortPtr += HIWORD(Delta);
-                    break;
-
-                case IMAGE_REL_BASED_LOW:
-                    *ShortPtr += LOWORD(Delta);
-                    break;
-
-                case IMAGE_REL_BASED_HIGHLOW:
-                    LongPtr = (PULONG)ShortPtr;
-                    *LongPtr += Delta;
-                    break;
-            }
-
-            TypeOffset++;
-        }
-
-        /* Move to the next Relocation Table */
-        RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDir->SizeOfBlock);
+    /* Get the Kernel Table Index */
+    KernelPageTableIndex = KernelBase >> PDE_SHIFT;
+
+    /* Get the Startup Page Directory */
+    PageDir = (PPAGE_DIRECTORY_X86)&startup_pagedirectory;
+
+    /* Set up the Low Memory PDE */
+    PageDir->Pde[LowMemPageTableIndex].Valid = 1;
+    PageDir->Pde[LowMemPageTableIndex].Write = 1;
+    PageDir->Pde[LowMemPageTableIndex].PageFrameNumber = PaPtrToPfn(lowmem_pagetable);
+
+    /* Set up the Kernel PDEs */
+    PageDir->Pde[KernelPageTableIndex].Valid = 1;
+    PageDir->Pde[KernelPageTableIndex].Write = 1;
+    PageDir->Pde[KernelPageTableIndex].PageFrameNumber = PaPtrToPfn(kernel_pagetable);
+    PageDir->Pde[KernelPageTableIndex + 1].Valid = 1;
+    PageDir->Pde[KernelPageTableIndex + 1].Write = 1;
+    PageDir->Pde[KernelPageTableIndex + 1].PageFrameNumber = PaPtrToPfn(kernel_pagetable + 4096);
+
+    /* Set up the Startup PDE */
+    PageDir->Pde[StartupPageTableIndex].Valid = 1;
+    PageDir->Pde[StartupPageTableIndex].Write = 1;
+    PageDir->Pde[StartupPageTableIndex].PageFrameNumber = PaPtrToPfn(startup_pagedirectory);
+
+    /* Set up the Hyperspace PDE */
+    PageDir->Pde[HyperspacePageTableIndex].Valid = 1;
+    PageDir->Pde[HyperspacePageTableIndex].Write = 1;
+    PageDir->Pde[HyperspacePageTableIndex].PageFrameNumber = PaPtrToPfn(hyperspace_pagetable);
+
+    /* Set up the HAL PDE */
+    PageDir->Pde[HalPageTableIndex].Valid = 1;
+    PageDir->Pde[HalPageTableIndex].Write = 1;
+    PageDir->Pde[HalPageTableIndex].PageFrameNumber = PaPtrToPfn(apic_pagetable);
+
+    /* Set up Low Memory PTEs */
+    PageDir = (PPAGE_DIRECTORY_X86)&lowmem_pagetable;
+    for (i=0; i<1024; i++)
+    {
+        PageDir->Pde[i].Valid = 1;
+        PageDir->Pde[i].Write = 1;
+        PageDir->Pde[i].Owner = 1;
+        PageDir->Pde[i].PageFrameNumber = PaToPfn(i * PAGE_SIZE);
     }
 
-    /* Fill out Module Data Structure */
-    reactos_modules[0].ModStart = KernelBase;
-    reactos_modules[0].ModEnd = KernelBase + ImageSize;
-    strcpy(reactos_module_strings[0], "ntoskrnl.exe");
-    reactos_modules[0].String = (ULONG_PTR)reactos_module_strings[0];
-    LoaderBlock.ModsCount++;
-
-    /* Increase the next Load Base */
-    NextModuleBase = ROUND_UP(KERNEL_BASE_PHYS + ImageSize, PAGE_SIZE);
-
-    /* Return Success */
-    return TRUE;
-}
-
-ULONG_PTR
-NTAPI
-FrLdrLoadModule(FILE *ModuleImage,
-                LPCSTR ModuleName,
-                PULONG ModuleSize)
-{
-    ULONG LocalModuleSize;
-    PLOADER_MODULE ModuleData;
-    LPSTR NameBuffer;
-    LPSTR TempName;
-
-    /* Get current module data structure and module name string array */
-    ModuleData = &reactos_modules[LoaderBlock.ModsCount];
-
-    /* Get only the Module Name */
-    do {
-
-        TempName = strchr(ModuleName, '\\');
-
-        if(TempName) {
-            ModuleName = TempName + 1;
-        }
-
-    } while(TempName);
-    NameBuffer = reactos_module_strings[LoaderBlock.ModsCount];
-
-    /* Get Module Size */
-    LocalModuleSize = FsGetFileSize(ModuleImage);
-
-    /* Fill out Module Data Structure */
-    ModuleData->ModStart = NextModuleBase;
-    ModuleData->ModEnd = NextModuleBase + LocalModuleSize;
-
-    /* Save name */
-    strcpy(NameBuffer, ModuleName);
-    ModuleData->String = (ULONG_PTR)NameBuffer;
-
-    /* Load the file image */
-    FsReadFile(ModuleImage, LocalModuleSize, NULL, (PVOID)NextModuleBase);
-
-    /* Move to next memory block and increase Module Count */
-    NextModuleBase = ROUND_UP(ModuleData->ModEnd, PAGE_SIZE);
-    LoaderBlock.ModsCount++;
-
-    /* Return Module Size if required */
-    if (ModuleSize != NULL) {
-        *ModuleSize = LocalModuleSize;
+    /* Set up Kernel PTEs */
+    PageDir = (PPAGE_DIRECTORY_X86)&kernel_pagetable;
+    for (i=0; i<1536; i++)
+    {
+        PageDir->Pde[i].Valid = 1;
+        PageDir->Pde[i].Write = 1;
+        PageDir->Pde[i].PageFrameNumber = PaToPfn(KERNEL_BASE_PHYS + i * PAGE_SIZE);
     }
 
-    return(ModuleData->ModStart);
-}
-
-ULONG_PTR
-NTAPI
-FrLdrCreateModule(LPCSTR ModuleName)
-{
-    PLOADER_MODULE ModuleData;
-    LPSTR NameBuffer;
-
-    /* Get current module data structure and module name string array */
-    ModuleData = &reactos_modules[LoaderBlock.ModsCount];
-    NameBuffer = reactos_module_strings[LoaderBlock.ModsCount];
-
-    /* Set up the structure */
-    ModuleData->ModStart = NextModuleBase;
-    ModuleData->ModEnd = -1;
-
-    /* Copy the name */
-    strcpy(NameBuffer, ModuleName);
-    ModuleData->String = (ULONG_PTR)NameBuffer;
-
-    /* Set the current Module */
-    CurrentModule = ModuleData;
-
-    /* Return Module Base Address */
-    return(ModuleData->ModStart);
+    /* Setup APIC Base */
+    PageDir = (PPAGE_DIRECTORY_X86)&apic_pagetable;
+    PageDir->Pde[0].Valid = 1;
+    PageDir->Pde[0].Write = 1;
+    PageDir->Pde[0].CacheDisable = 1;
+    PageDir->Pde[0].WriteThrough = 1;
+    PageDir->Pde[0].PageFrameNumber = PaToPfn(HAL_BASE);
+    PageDir->Pde[0x200].Valid = 1;
+    PageDir->Pde[0x200].Write = 1;
+    PageDir->Pde[0x200].CacheDisable = 1;
+    PageDir->Pde[0x200].WriteThrough = 1;
+    PageDir->Pde[0x200].PageFrameNumber = PaToPfn(HAL_BASE + KERNEL_BASE_PHYS);
+
+    /* Setup KUSER_SHARED_DATA Base */
+    PageDir->Pde[0x1F0].Valid = 1;
+    PageDir->Pde[0x1F0].Write = 1;
+    PageDir->Pde[0x1F0].PageFrameNumber = 2;
+
+    /* Setup KPCR Base*/
+    PageDir->Pde[0x1FF].Valid = 1;
+    PageDir->Pde[0x1FF].Write = 1;
+    PageDir->Pde[0x1FF].PageFrameNumber = 1;
 }
 
-BOOLEAN
-NTAPI
-FrLdrCloseModule(ULONG_PTR ModuleBase,
-                 ULONG ModuleSize)
-{
-    PLOADER_MODULE ModuleData = CurrentModule;
-
-    /* Make sure a module is opened */
-    if (ModuleData) {
-
-        /* Make sure this is the right module and that it hasn't been closed */
-        if ((ModuleBase == ModuleData->ModStart) && (ModuleData->ModEnd == (ULONG_PTR)-1)) {
-
-            /* Close the Module */
-            ModuleData->ModEnd = ModuleData->ModStart + ModuleSize;
-
-            /* Set the next Module Base and increase the number of modules */
-            NextModuleBase = ROUND_UP(ModuleData->ModEnd, PAGE_SIZE);
-            LoaderBlock.ModsCount++;
-
-            /* Close the currently opened module */
-            CurrentModule = NULL;
-
-            /* Success */
-            return(TRUE);
-        }
-    }
-
-    /* Failure path */
-    return(FALSE);
-}