I reworked the pagetable code a little. Now the first tables are static .bss tables...
authorTimo Kreuzer <timo.kreuzer@reactos.org>
Tue, 29 Jul 2008 19:09:56 +0000 (19:09 +0000)
committerTimo Kreuzer <timo.kreuzer@reactos.org>
Tue, 29 Jul 2008 19:09:56 +0000 (19:09 +0000)
svn path=/branches/ros-amd64-bringup/; revision=34937

reactos/boot/freeldr/freeldr/arch/amd64/arch.S
reactos/boot/freeldr/freeldr/arch/amd64/loader.c
reactos/boot/freeldr/freeldr/arch/amd64/mb.S
reactos/boot/freeldr/freeldr/include/arch/amd64/amd64.h
reactos/boot/freeldr/freeldr/include/reactos.h
reactos/boot/freeldr/freeldr/mm/meminit.c
reactos/boot/freeldr/freeldr/reactos/setupldr.c

index 5ddc4eb..a0c9b74 100644 (file)
@@ -99,22 +99,27 @@ x86_16_BuildPageTables:
        pusha
        push es
 
-       mov ax, PML4_SEG
+       /* Get segment of pml4 */
+       mov eax, offset _pml4_startup
+       shr eax, 4
        mov es, ax
        cld
        xor di, di
 
        /* One entry in the PML4 pointing to PDP */
-       mov eax, (PDP_PAGENUM << 12) | 0x00f
+       mov eax, offset _pdp_startup
+       or eax, 0x00f
        stosd
+       /* clear rest */
        xor eax, eax
        mov cx, 0x03ff
        rep stosd
 
        /* One entry in the PDP pointing to PD */
-       mov eax, (PD_PAGENUM << 12) | 0x00f
+       mov eax, offset _pd_startup
+       or eax, 0x00f
        stosd
-
+       /* clear rest */
        xor eax, eax
        mov ecx, 0x03ff
        rep stosd
@@ -159,7 +164,7 @@ x86_16_SwitchToLong:
        mov eax, 0x00a0                 // Set PAE and PGE: 10100000b
        mov cr4, eax
 
-       mov edx, PML4_ADDRESS   // Point cr3 at PML4
+       mov edx, offset _pml4_startup // Point cr3 at PML4
        mov cr3, edx
 
        mov ecx, 0xC0000080             // Specify EFER MSR
index adb50e9..9e62923 100644 (file)
 
 #define NDEBUG
 #include <debug.h>
-#undef DbgPrint
+//#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 PAGE_DIRECTORY_X86 hyperspace_pagetable;
-extern PAGE_DIRECTORY_X86 apic_pagetable;
-extern PAGE_DIRECTORY_X86 kpcr_pagetable;
-extern PAGE_DIRECTORY_X86 kuser_pagetable;
+extern ULONG_PTR NextModuleBase;
 extern ULONG_PTR KernelBase;
 extern ROS_KERNEL_ENTRY_POINT KernelEntryPoint;
+
+PPAGE_DIRECTORY_AMD64 pPML4;
+
 /* FUNCTIONS *****************************************************************/
 
 /*++
@@ -56,57 +53,94 @@ VOID
 NTAPI
 FrLdrStartup(ULONG Magic)
 {
-    ASSERT(FALSE);
-#if 0
     /* Disable Interrupts */
     _disable();
 
     /* Re-initalize EFLAGS */
-    Ke386EraseFlags();
+    KeAmd64EraseFlags();
 
     /* Initialize the page directory */
     FrLdrSetupPageDirectory();
 
-    /* Initialize Paging, Write-Protection and Load NTOSKRNL */
-    FrLdrSetupPae(Magic);
-#endif
+    /* Set the new PML4 */
+    __writecr3((ULONGLONG)pPML4);
+
+DbgPrint((DPRINT_WARNING, "Jumping to kernel @ %p.\n", KernelEntryPoint));
+
+    /* Jump to Kernel */
+    (*KernelEntryPoint)(Magic, &LoaderBlock);
+
 }
 
-/*++
- * FrLdrSetupPae
- * INTERNAL
- *
- *     Configures PAE on a MP System, and sets the PDBR if it's supported, or if
- *     the system is UP.
- *
- * Params:
- *     Magic - Multiboot Magic
- *
- * Returns:
- *     None.
- *
- * Remarks:
- *     None.
- *
- *--*/
-VOID
-FASTCALL
-FrLdrSetupPae(ULONG Magic)
+PPAGE_DIRECTORY_AMD64
+FrLdrGetOrCreatePageDir(PPAGE_DIRECTORY_AMD64 pDir, ULONG Index)
 {
-#if 0
-    ULONG_PTR PageDirectoryBaseAddress = (ULONG_PTR)&startup_pagedirectory;
+       PPAGE_DIRECTORY_AMD64 pSubDir;
+
+       if (!pDir)
+               return NULL;
+
+       if (!pDir->Pde[Index].Valid)
+       {
+               pSubDir = MmAllocateMemoryWithType(PAGE_SIZE, LoaderSpecialMemory);
+               if (!pSubDir)
+                       return NULL;
+               RtlZeroMemory(pSubDir, PAGE_SIZE);
+               pDir->Pde[Index].PageFrameNumber = (ULONGLONG)pSubDir / PAGE_SIZE;
+               pDir->Pde[Index].Valid = 1;
+               pDir->Pde[Index].Write = 1;
+       }
+       else
+       {
+               pSubDir = (PPAGE_DIRECTORY_AMD64)((ULONGLONG)(pDir->Pde[Index].PageFrameNumber) * PAGE_SIZE);
+       }
+       return pSubDir;
+}
 
-    /* Set the PDBR */
-    __writecr3(PageDirectoryBaseAddress);
+BOOLEAN
+FrLdrMapSinglePage(ULONGLONG VirtualAddress, ULONGLONG PhysicalAddress)
+{
+       PPAGE_DIRECTORY_AMD64 pDir3, pDir2, pDir1;
+       ULONG Index;
 
-    /* Enable Paging and Write Protect*/
-    __writecr0(__readcr0() | X86_CR0_PG | X86_CR0_WP);
+       pDir3 = FrLdrGetOrCreatePageDir(pPML4, VAtoIndex4(VirtualAddress));
+       pDir2 = FrLdrGetOrCreatePageDir(pDir3, VAtoIndex3(VirtualAddress));
+       pDir1 = FrLdrGetOrCreatePageDir(pDir2, VAtoIndex2(VirtualAddress));
 
-    /* Jump to Kernel */
-    (*KernelEntryPoint)(Magic, &LoaderBlock);
-#endif
+       if (!pDir1)
+               return FALSE;
+
+       Index = VAtoIndex1(VirtualAddress);
+       if (pDir1->Pde[Index].Valid)
+       {
+               return FALSE;
+       }
+
+       pDir1->Pde[Index].Valid = 1;
+       pDir1->Pde[Index].Write = 1;
+       pDir1->Pde[Index].PageFrameNumber = PhysicalAddress / PAGE_SIZE;
+
+       return TRUE;
+}
+
+ULONG
+FrLdrMapRangeOfPages(ULONGLONG VirtualAddress, ULONGLONG PhysicalAddress, ULONG cPages)
+{
+       ULONG i;
+
+       for (i = 0; i < cPages; i++)
+       {
+               if (!FrLdrMapSinglePage(VirtualAddress, PhysicalAddress))
+               {
+                       return i;
+               }
+               VirtualAddress += PAGE_SIZE;
+               PhysicalAddress += PAGE_SIZE;
+       }
+       return i;
 }
 
+
 /*++
  * FrLdrSetupPageDirectory
  * INTERNAL
@@ -128,89 +162,38 @@ VOID
 FASTCALL
 FrLdrSetupPageDirectory(VOID)
 {
-#if 0
-    PPAGE_DIRECTORY_X86 PageDir;
-    ULONG KernelPageTableIndex;
-    ULONG i;
-
-    /* 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);
-    }
-
-    /* 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);
-    }
-
-    /* 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;
-
-    /* Zero shared data */
-    RtlZeroMemory((PVOID)(2 << MM_PAGE_SHIFT), PAGE_SIZE);
-#endif
+       ULONG KernelPages;
+
+       /* Allocate a Page for the PML4 */
+       pPML4 = MmAllocateMemoryWithType(4096, LoaderSpecialMemory);
+
+       ASSERT(pPML4);
+
+       /* The page tables are located at 0xfffff68000000000 
+        * We create a recursive self mapping through all 4 levels at 
+        * virtual address 0xfffff6fb7dbedf68 */
+       pPML4->Pde[VAtoIndex4(PML4_BASE)].Valid = 1;
+       pPML4->Pde[VAtoIndex4(PML4_BASE)].Write = 1;
+       pPML4->Pde[VAtoIndex4(PML4_BASE)].PageFrameNumber = PtrToPfn(PML4_BASE);
+
+       ASSERT(VAtoIndex4(PML4_BASE) == 0x1ed);
+       ASSERT(VAtoIndex3(PML4_BASE) == 0x1ed);
+       ASSERT(VAtoIndex2(PML4_BASE) == 0x1ed);
+       ASSERT(VAtoIndex1(PML4_BASE) == 0x1ed);
+
+       /* Setup low memory pages */
+       if (FrLdrMapRangeOfPages(0, 0, 1024) < 1024)
+       {
+               DbgPrint((DPRINT_WARNING, "Could not map low memory pages.\n"));
+       }
+
+       /* Setup kernel pages */
+       KernelPages = (ROUND_TO_PAGES(NextModuleBase - KERNEL_BASE_PHYS) / PAGE_SIZE);
+       DbgPrint((DPRINT_WARNING, "Trying to map %d pages for kernel.\n", KernelPages));
+       if (FrLdrMapRangeOfPages(KernelBase, KERNEL_BASE_PHYS, KernelPages) != KernelPages)
+       {
+               DbgPrint((DPRINT_WARNING, "Could not map %d kernel pages.\n", KernelPages));
+       }
+
 }
 
index d87e457..bdb4f51 100644 (file)
         * Here we assume the kernel is loaded at 1mb
         * This boots the kernel
         */
-       .code32
+       .code64
     .globl _PageDirectoryStart
     
-    .globl _startup_pagedirectory
-    .globl _lowmem_pagetable
-    .globl _kernel_pagetable
-    .globl _hyperspace_pagetable
-    .globl _apic_pagetable
-    .globl _kpcr_pagetable
-    .globl _kuser_pagetable
+    .globl _pml4_startup
+    .globl _pdp_startup
+    .globl _pd_startup
 
     .globl _PageDirectoryEnd
 
@@ -55,25 +51,13 @@ EXTERN(_reactos_memory_map)
 
 .bss
 _PageDirectoryStart:
-_startup_pagedirectory:
+_pml4_startup:
        .fill 4096, 1, 0
 
-_lowmem_pagetable:
+_pdp_startup:
        .fill 4096, 1, 0
 
-_kernel_pagetable:
-       .fill 2*4096, 1, 0
-
-_hyperspace_pagetable:
-       .fill 4096, 1, 0
-       
-_apic_pagetable:
+_pd_startup:
        .fill 4096, 1, 0
 
-_kpcr_pagetable:
-       .fill 4096, 1, 0   
-
-_kuser_pagetable:
-       .fill 4096, 1, 0   
-
 _PageDirectoryEnd:
index e450901..9aa4028 100644 (file)
 
 #define STACK64ADDR    0x74000 /* The 64-bit stack top will be at 0x74000 */
 
+/* Long mode selectors */
 #define LMODE_CS       0x08
 #define LMODE_DS       0x10
 
-/* Where we put out initial page tables */
-#define PML4_PAGENUM 60 // Put it high enough so it doesn't interfere with freeldr
+#define VA_MASK 0x0000FFFFFFFFFFFFUL
+#define PML4_SHIFT (12+9+9+9)
+#define PDP_SHIFT (12+9+9)
+#define PD_SHIFT (12+9)
+#define PT_SHIFT 12
 
-#define PAGESIZE 4096
-#define PDP_PAGENUM (PML4_PAGENUM + 1)
-#define PD_PAGENUM (PDP_PAGENUM + 1)
-#define PML4_ADDRESS (PML4_PAGENUM * PAGESIZE)
-#define PDP_ADDRESS (PDP_PAGENUM * PAGESIZE)
-#define PML4_SEG (PML4_ADDRESS / 16)
-#define PML4_PAGES 3
-#define PAGETABLE_SIZE PML4_PAGES * PAGESIZE
+#define PtrToPfn(p) \
+    ((((ULONGLONG)p) >> PT_SHIFT) & 0xffffffffffULL)
 
-#if 0
-#ifndef ASM
-typedef struct
-{
-       unsigned long long      rax;
-       unsigned long long      rbx;
-       unsigned long long      rcx;
-       unsigned long long      rdx;
-
-       unsigned long long      rsi;
-       unsigned long long      rdi;
+#define VAtoIndex4(va) (((va) >> PML4_SHIFT) & 0x1FF)
+#define VAtoIndex3(va) (((va) >> PDP_SHIFT) & 0x1FF)
+#define VAtoIndex2(va) (((va) >> PD_SHIFT) & 0x1FF)
+#define VAtoIndex1(va) (((va) >> PT_SHIFT) & 0x1FF)
 
-       unsigned long long      r8;
-       unsigned long long      r9;
-       unsigned long long      r10;
-       unsigned long long      r11;
-       unsigned long long      r12;
-       unsigned long long      r13;
-       unsigned long long      r14;
-       unsigned long long      r15;
+#define PAGETABLE_BASE              0xfffff68000000000ULL
+#define PML4_BASE                   0xfffff6fb7dbedf68ULL
+#define HYPERSPACE_BASE             0xfffff70000000000ULL
+#define HAL_BASE                    0xffffffff80000000ULL
+#define APIC_BASE                   0xffffffffff000000ULL // FIXME
 
-       unsigned short  ds;
-       unsigned short  es;
-       unsigned short  fs;
-       unsigned short  gs;
+#define NUM_PAGES_KERNEL 
 
-       unsigned long long      rflags;
+#ifndef ASM
+typedef struct _PAGE_DIRECTORY_AMD64
+{
+    HARDWARE_PTE Pde[512];
+} PAGE_DIRECTORY_AMD64, *PPAGE_DIRECTORY_AMD64;
 
-} QWORDREGS;
-#endif /* ! ASM */
 #endif
 
 #endif /* __AMD64_AMD64_H_ */
index 837b11c..d38a3cb 100644 (file)
@@ -23,6 +23,8 @@
 /* Base Addres of Kernel in Physical Memory */
 #define KERNEL_BASE_PHYS 0x800000
 
+#if !defined(_M_AMD64)
+
 /* Bits to shift to convert a Virtual Address into an Offset in the Page Table */
 #define PFN_SHIFT 12
 
@@ -53,6 +55,8 @@ typedef struct _PAGE_DIRECTORY_X86
     HARDWARE_PTE Pde[1024];
 } PAGE_DIRECTORY_X86, *PPAGE_DIRECTORY_X86;
 
+#endif
+
 ///////////////////////////////////////////////////////////////////////////////////////
 //
 // ReactOS Loading Functions
index 0b41dd7..2efab39 100644 (file)
@@ -106,9 +106,6 @@ BOOLEAN MmInitializeMemoryManager(VOID)
        MmMarkPagesInLookupTable(PageLookupTableAddress, 0x90, 0x10, LoaderOsloaderHeap); // Disk read buffer for int 13h. DISKREADBUFFER
        MmMarkPagesInLookupTable(PageLookupTableAddress, 0xA0, 0x60, LoaderFirmwarePermanent); // ROM / Video
        MmMarkPagesInLookupTable(PageLookupTableAddress, 0xFFF, 1, LoaderSpecialMemory); // unusable memory
-#if defined (_M_AMD64)
-       MmMarkPagesInLookupTable(PageLookupTableAddress, PML4_PAGENUM, PML4_PAGES, LoaderSpecialMemory); // the page table
-#endif
 #elif __arm__
        MmMarkPagesInLookupTable(PageLookupTableAddress, 0x00, 1, LoaderFirmwarePermanent); // arm exception handlers
        MmMarkPagesInLookupTable(PageLookupTableAddress, 0x01, 7, LoaderFirmwareTemporary); // arm board block + freeldr stack + cmdline
index f36ddde..f2163f2 100644 (file)
@@ -406,7 +406,10 @@ VOID RunLoader(VOID)
 
   /* Load ext2.sys (could be loaded by the setup prog!) */
   if (!LoadDriver(SourcePath, "ext2.sys"))
-    return;
+  {
+      DbgPrint((DPRINT_WARNING, "Could not load ext2\n"));
+//    return;
+  }
 
     /* Load additional files specified in txtsetup.inf */
     if (InfFindFirstLine(InfHandle,
@@ -423,7 +426,10 @@ VOID RunLoader(VOID)
                 if (strcmp(Media, "x") == 0)
                 {
                     if (!LoadDriver(SourcePath, DriverName))
+                    {
+                        DbgPrint((DPRINT_WARNING, "could not load %s, %s\n", SourcePath, DriverName));
                         return;
+                    }
                 }
             }
         } while (InfFindNextLine(&InfContext, &InfContext));