Author: tkreuzer Date: Tue Jul 29 14:09:56 2008 New Revision: 34937
URL: http://svn.reactos.org/svn/reactos?rev=34937&view=rev Log: I reworked the pagetable code a little. Now the first tables are static .bss tables. Later before switching to the kernel, we create a proper 4 level page table. Here we allocate the needed pages. Remove obsolete meminit hack. Add a few useful debug prints to setupldr and comment out return, when ext2 wasn't loaded. We now reach the point where we jump to ntoskrnl, but ntoskrnl is in a bad shape ;-)
Modified: branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/arch/amd64/arch.S branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/arch/amd64/loader.c branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/arch/amd64/mb.S branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/include/arch/amd64/amd64.h branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/include/reactos.h branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/mm/meminit.c branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/reactos/setupldr.c
Modified: branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/arch/amd64/arch.S URL: http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/boot/f... ============================================================================== --- branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/arch/amd64/arch.S [iso-8859-1] (original) +++ branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/arch/amd64/arch.S [iso-8859-1] Tue Jul 29 14:09:56 2008 @@ -99,22 +99,27 @@ 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 @@ 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
Modified: branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/arch/amd64/loader.c URL: http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/boot/f... ============================================================================== --- branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/arch/amd64/loader.c [iso-8859-1] (original) +++ branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/arch/amd64/loader.c [iso-8859-1] Tue Jul 29 14:09:56 2008 @@ -22,18 +22,15 @@
#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,56 +53,93 @@ 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);
-/*++ - * 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) -{ -#if 0 - ULONG_PTR PageDirectoryBaseAddress = (ULONG_PTR)&startup_pagedirectory; - - /* Set the PDBR */ - __writecr3(PageDirectoryBaseAddress); - - /* Enable Paging and Write Protect*/ - __writecr0(__readcr0() | X86_CR0_PG | X86_CR0_WP); +DbgPrint((DPRINT_WARNING, "Jumping to kernel @ %p.\n", KernelEntryPoint));
/* Jump to Kernel */ (*KernelEntryPoint)(Magic, &LoaderBlock); -#endif + } + +PPAGE_DIRECTORY_AMD64 +FrLdrGetOrCreatePageDir(PPAGE_DIRECTORY_AMD64 pDir, ULONG Index) +{ + 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; +} + +BOOLEAN +FrLdrMapSinglePage(ULONGLONG VirtualAddress, ULONGLONG PhysicalAddress) +{ + PPAGE_DIRECTORY_AMD64 pDir3, pDir2, pDir1; + ULONG Index; + + pDir3 = FrLdrGetOrCreatePageDir(pPML4, VAtoIndex4(VirtualAddress)); + pDir2 = FrLdrGetOrCreatePageDir(pDir3, VAtoIndex3(VirtualAddress)); + pDir1 = FrLdrGetOrCreatePageDir(pDir2, VAtoIndex2(VirtualAddress)); + + 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 @@ -128,89 +162,38 @@ FASTCALL FrLdrSetupPageDirectory(VOID) { -#if 0 - PPAGE_DIRECTORY_X86 PageDir; - ULONG KernelPageTableIndex; - ULONG i; + ULONG KernelPages;
- /* Get the Kernel Table Index */ - KernelPageTableIndex = KernelBase >> PDE_SHIFT; + /* Allocate a Page for the PML4 */ + pPML4 = MmAllocateMemoryWithType(4096, LoaderSpecialMemory);
- /* Get the Startup Page Directory */ - PageDir = (PPAGE_DIRECTORY_X86)&startup_pagedirectory; + ASSERT(pPML4);
- /* Set up the Low Memory PDE */ - PageDir->Pde[LowMemPageTableIndex].Valid = 1; - PageDir->Pde[LowMemPageTableIndex].Write = 1; - PageDir->Pde[LowMemPageTableIndex].PageFrameNumber = PaPtrToPfn(lowmem_pagetable); + /* 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);
- /* 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); + ASSERT(VAtoIndex4(PML4_BASE) == 0x1ed); + ASSERT(VAtoIndex3(PML4_BASE) == 0x1ed); + ASSERT(VAtoIndex2(PML4_BASE) == 0x1ed); + ASSERT(VAtoIndex1(PML4_BASE) == 0x1ed);
- /* Set up the Startup PDE */ - PageDir->Pde[StartupPageTableIndex].Valid = 1; - PageDir->Pde[StartupPageTableIndex].Write = 1; - PageDir->Pde[StartupPageTableIndex].PageFrameNumber = PaPtrToPfn(startup_pagedirectory); + /* Setup low memory pages */ + if (FrLdrMapRangeOfPages(0, 0, 1024) < 1024) + { + DbgPrint((DPRINT_WARNING, "Could not map low memory pages.\n")); + }
- /* Set up the Hyperspace PDE */ - PageDir->Pde[HyperspacePageTableIndex].Valid = 1; - PageDir->Pde[HyperspacePageTableIndex].Write = 1; - PageDir->Pde[HyperspacePageTableIndex].PageFrameNumber = PaPtrToPfn(hyperspace_pagetable); + /* 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)); + }
- /* 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 }
Modified: branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/arch/amd64/mb.S URL: http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/boot/f... ============================================================================== --- branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/arch/amd64/mb.S [iso-8859-1] (original) +++ branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/arch/amd64/mb.S [iso-8859-1] Tue Jul 29 14:09:56 2008 @@ -28,16 +28,12 @@ * 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 @@
.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:
Modified: branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/include/arch/amd64/amd64.h URL: http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/boot/f... ============================================================================== --- branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/include/arch/amd64/amd64.h [iso-8859-1] (original) +++ branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/include/arch/amd64/amd64.h [iso-8859-1] Tue Jul 29 14:09:56 2008 @@ -23,51 +23,38 @@
#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 +#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) + +#define PAGETABLE_BASE 0xfffff68000000000ULL +#define PML4_BASE 0xfffff6fb7dbedf68ULL +#define HYPERSPACE_BASE 0xfffff70000000000ULL +#define HAL_BASE 0xffffffff80000000ULL +#define APIC_BASE 0xffffffffff000000ULL // FIXME + +#define NUM_PAGES_KERNEL + #ifndef ASM -typedef struct +typedef struct _PAGE_DIRECTORY_AMD64 { - unsigned long long rax; - unsigned long long rbx; - unsigned long long rcx; - unsigned long long rdx; + HARDWARE_PTE Pde[512]; +} PAGE_DIRECTORY_AMD64, *PPAGE_DIRECTORY_AMD64;
- unsigned long long rsi; - unsigned long long rdi; - - 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; - - unsigned short ds; - unsigned short es; - unsigned short fs; - unsigned short gs; - - unsigned long long rflags; - -} QWORDREGS; -#endif /* ! ASM */ #endif
#endif /* __AMD64_AMD64_H_ */
Modified: branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/include/reactos.h URL: http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/boot/f... ============================================================================== --- branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/include/reactos.h [iso-8859-1] (original) +++ branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/include/reactos.h [iso-8859-1] Tue Jul 29 14:09:56 2008 @@ -22,6 +22,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 @@ -52,6 +54,8 @@ { HARDWARE_PTE Pde[1024]; } PAGE_DIRECTORY_X86, *PPAGE_DIRECTORY_X86; + +#endif
/////////////////////////////////////////////////////////////////////////////////////// //
Modified: branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/mm/meminit.c URL: http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/boot/f... ============================================================================== --- branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/mm/meminit.c [iso-8859-1] (original) +++ branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/mm/meminit.c [iso-8859-1] Tue Jul 29 14:09:56 2008 @@ -106,9 +106,6 @@ 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
Modified: branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/reactos/setupldr.c URL: http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/boot/f... ============================================================================== --- branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/reactos/setupldr.c [iso-8859-1] (original) +++ branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/reactos/setupldr.c [iso-8859-1] Tue Jul 29 14:09:56 2008 @@ -406,7 +406,10 @@
/* 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 @@ 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));