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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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));