mov ss, ax
/* checkPoint Charlie - where it all began... */
- mov si, offset _CheckPoint0
+ mov si, offset CheckPoint0
call writestr
-
+
/* Setup a real mode stack */
mov sp, stack16
/* Zero BootDrive and BootPartition */
xor eax, eax
- mov _BootDrive, eax
- mov _BootPartition, eax
+ mov BootDrive, eax
+ mov BootPartition, eax
/* Store the boot drive */
- mov _BootDrive, dl
+ mov BootDrive, dl
/* Store the boot partition */
- mov _BootPartition, dh
+ mov BootPartition, dh
/* Load the GDT */
lgdt gdtptr
call x86_16_EnableA20
/* checkPoint Charlie - where it all began... */
- mov si, offset _CheckPoint1
+ mov si, offset CheckPoint1
call writestr
call x86_16_BuildPageTables
/* checkPoint Charlie - where it all began... */
- mov si, offset _CheckPoint2
+ mov si, offset CheckPoint2
call writestr
/* Check if CPU supports CPUID */
/* X64 Processor */
/* checkPoint Charlie - where it all began... */
- mov si, offset _CheckPoint3
+ mov si, offset CheckPoint3
call writestr
- jmp _switch64
+ jmp switch64
NO_X64_SUPPORT_DETECTED:
- mov si, offset _NotAnX64Processor // Loading message
+ mov si, offset NotAnX64Processor // Loading message
call writestr
- jmp _fail
+ jmp fail
NO_CPUID_SUPPORT_DETECTED:
- mov si, offset _NoCPUIDSupport // Loading message
- call writestr
+ mov si, offset NoCPUIDSupport // Loading message
+ call writestr
-_fail:
- jmp _fail
+fail:
+ jmp fail
nop
nop
-_switch64:
+switch64:
call x86_16_SwitchToLong
.code64
/* GO! */
xor rcx, rcx
- call _BootMain
+ call BootMain
/* Checkpoint */
// mov ax, LMODE_DS
push es
/* Get segment of pml4 */
- mov eax, offset _pml4_startup
+ 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, offset _pdp_startup
+ mov eax, offset pdp_startup
or eax, 0x00f
stosd
/* clear rest */
rep stosd
/* One entry in the PDP pointing to PD */
- mov eax, offset _pd_startup
+ mov eax, offset pd_startup
or eax, 0x00f
stosd
/* clear rest */
mov eax, 0x00a0 // Set PAE and PGE: 10100000b
mov cr4, eax
- mov edx, offset _pml4_startup // Point cr3 at PML4
+ mov edx, offset pml4_startup // Point cr3 at PML4
mov cr3, edx
mov ecx, 0xC0000080 // Specify EFER MSR
.long gdt /* Base Address */
-.global _BootDrive
-_BootDrive:
+.global BootDrive
+BootDrive:
.long 0
-.global _BootPartition
-_BootPartition:
+.global BootPartition
+BootPartition:
.long 0
-.global _NotAnX64Processor
-_NotAnX64Processor:
+.global NotAnX64Processor
+NotAnX64Processor:
.ascii "FreeLoader: No x64-compatible CPU detected! Exiting..."
.byte 0x0d, 0x0a, 0
-.global _NoCPUIDSupport
-_NoCPUIDSupport:
+.global NoCPUIDSupport
+NoCPUIDSupport:
.ascii "FreeLoader: No CPUID instruction support detected! Exiting..."
.byte 0x0d, 0x0a, 0
/////////////////////////// Checkpoint messages ///////////////////////////////
-.global _CheckPoint0
-_CheckPoint0:
+.global CheckPoint0
+CheckPoint0:
.ascii "Starting FreeLoader..."
.byte 0x0d, 0x0a, 0
-.global _CheckPoint1
-_CheckPoint1:
+.global CheckPoint1
+CheckPoint1:
.ascii "FreeLoader[16-bit]: building page tables..."
.byte 0x0d, 0x0a, 0
-.global _CheckPoint2
-_CheckPoint2:
+.global CheckPoint2
+CheckPoint2:
.ascii "FreeLoader[16-bit]: checking CPU for x64 long mode..."
.byte 0x0d, 0x0a, 0
-.global _CheckPoint3
-_CheckPoint3:
+.global CheckPoint3
+CheckPoint3:
.ascii "FreeLoader: Switching to x64 long mode..."
.byte 0x0d, 0x0a, 0
/* Already done */
}
-void
-DumpLoaderBlock()
-{
- DbgPrint("LoaderBlock @ %p.\n", &LoaderBlock);
- DbgPrint("Flags = 0x%x.\n", LoaderBlock.Flags);
- DbgPrint("MemLower = 0x%p.\n", (PVOID)LoaderBlock.MemLower);
- DbgPrint("MemHigher = 0x%p.\n", (PVOID)LoaderBlock.MemHigher);
- DbgPrint("BootDevice = 0x%x.\n", LoaderBlock.BootDevice);
- DbgPrint("CommandLine = %s.\n", LoaderBlock.CommandLine);
- DbgPrint("ModsCount = 0x%x.\n", LoaderBlock.ModsCount);
- DbgPrint("ModsAddr = 0x%p.\n", LoaderBlock.ModsAddr);
- DbgPrint("Syms = 0x%s.\n", LoaderBlock.Syms);
- DbgPrint("MmapLength = 0x%x.\n", LoaderBlock.MmapLength);
- DbgPrint("MmapAddr = 0x%p.\n", (PVOID)LoaderBlock.MmapAddr);
- DbgPrint("RdLength = 0x%x.\n", LoaderBlock.RdLength);
- DbgPrint("RdAddr = 0x%p.\n", (PVOID)LoaderBlock.RdAddr);
- DbgPrint("DrivesCount = 0x%x.\n", LoaderBlock.DrivesCount);
- DbgPrint("DrivesAddr = 0x%p.\n", (PVOID)LoaderBlock.DrivesAddr);
- DbgPrint("ConfigTable = 0x%x.\n", LoaderBlock.ConfigTable);
- DbgPrint("BootLoaderName = 0x%x.\n", LoaderBlock.BootLoaderName);
- DbgPrint("PageDirectoryStart = 0x%p.\n", (PVOID)LoaderBlock.PageDirectoryStart);
- DbgPrint("PageDirectoryEnd = 0x%p.\n", (PVOID)LoaderBlock.PageDirectoryEnd);
- DbgPrint("KernelBase = 0x%p.\n", (PVOID)LoaderBlock.KernelBase);
- DbgPrint("ArchExtra = 0x%p.\n", (PVOID)LoaderBlock.ArchExtra);
-
-}
-
/*++
* FrLdrStartup
* INTERNAL
NTAPI
FrLdrStartup(ULONG Magic)
{
- /* Disable Interrupts */
- _disable();
-
- /* Re-initalize EFLAGS */
- __writeeflags(0);
-
- /* Initialize the page directory */
- FrLdrSetupPageDirectory();
-
- /* Set the new PML4 */
- __writecr3((ULONGLONG)pPML4);
-
- FrLdrSetupGdtIdt();
-
- LoaderBlock.FrLdrDbgPrint = DbgPrint;
-
-// DumpLoaderBlock();
-
- DbgPrint("Jumping to kernel @ %p.\n", KernelEntryPoint);
-
- /* Jump to Kernel */
- (*KernelEntryPoint)(Magic, &LoaderBlock);
-
-}
-
-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 = PtrToPfn(pSubDir);
- 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, VAtoPXI(VirtualAddress));
- pDir2 = FrLdrGetOrCreatePageDir(pDir3, VAtoPPI(VirtualAddress));
- pDir1 = FrLdrGetOrCreatePageDir(pDir2, VAtoPDI(VirtualAddress));
-
- if (!pDir1)
- return FALSE;
-
- Index = VAtoPTI(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;
+ DbgPrint("ReactOS loader is unsupported! Halting.\n", KernelEntryPoint);
+ for(;;);
}
-
-/*++
- * FrLdrSetupPageDirectory
- * INTERNAL
- *
- * Sets up the ReactOS Startup Page Directory.
- *
- * Params:
- * None.
- *
- * Returns:
- * None.
- *--*/
-VOID
-FASTCALL
-FrLdrSetupPageDirectory(VOID)
-{
- ULONG KernelPages;
- PVOID UserSharedData;
-
- /* Allocate a Page for the PML4 */
- pPML4 = MmAllocateMemoryWithType(PAGE_SIZE, 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[VAtoPXI(PXE_BASE)].Valid = 1;
- pPML4->Pde[VAtoPXI(PXE_BASE)].Write = 1;
- pPML4->Pde[VAtoPXI(PXE_BASE)].PageFrameNumber = PtrToPfn(pPML4);
-
- /* Setup low memory pages */
- if (FrLdrMapRangeOfPages(0, 0, 1024) < 1024)
- {
- DbgPrint("Could not map low memory pages.\n");
- }
-
- /* Setup kernel pages */
- KernelPages = (ROUND_TO_PAGES(NextModuleBase - KERNEL_BASE_PHYS) / PAGE_SIZE);
- if (FrLdrMapRangeOfPages(KernelBase, KERNEL_BASE_PHYS, KernelPages) != KernelPages)
- {
- DbgPrint("Could not map %d kernel pages.\n", KernelPages);
- }
-
- /* Setup a page for the idt */
- pIdt = MmAllocateMemoryWithType(PAGE_SIZE, LoaderSpecialMemory);
- IdtBase = KernelBase + KernelPages * PAGE_SIZE;
- if (!FrLdrMapSinglePage(IdtBase, (ULONGLONG)pIdt))
- {
- DbgPrint("Could not map idt page.\n", KernelPages);
- }
-
- /* Setup a page for the gdt & tss */
- pGdt = MmAllocateMemoryWithType(PAGE_SIZE, LoaderSpecialMemory);
- GdtBase = IdtBase + PAGE_SIZE;
- TssBase = GdtBase + 20 * sizeof(ULONG64); // FIXME: don't hardcode
- if (!FrLdrMapSinglePage(GdtBase, (ULONGLONG)pGdt))
- {
- DbgPrint("Could not map gdt page.\n", KernelPages);
- }
-
- /* Setup KUSER_SHARED_DATA page */
- UserSharedData = MmAllocateMemoryWithType(PAGE_SIZE, LoaderSpecialMemory);
- if (!FrLdrMapSinglePage(KI_USER_SHARED_DATA, (ULONG64)UserSharedData))
- {
- DbgPrint("Could not map KUSER_SHARED_DATA page.\n", KernelPages);
- }
-
- /* Map APIC page */
- if (!FrLdrMapSinglePage(APIC_BASE, APIC_PHYS_BASE))
- {
- DbgPrint("Could not map APIC page.\n");
- }
-
-}
-
-VOID
-FrLdrSetupGdtIdt()
-{
- PKGDTENTRY64 Entry;
- KDESCRIPTOR Desc;
-
- RtlZeroMemory(pGdt, PAGE_SIZE);
-
- /* Setup KGDT_64_R0_CODE */
- Entry = KiGetGdtEntry(pGdt, KGDT_64_R0_CODE);
- *(PULONG64)Entry = 0x00209b0000000000ULL;
-
- /* Setup KGDT_64_R0_SS */
- Entry = KiGetGdtEntry(pGdt, KGDT_64_R0_SS);
- *(PULONG64)Entry = 0x00cf93000000ffffULL;
-
- /* Setup KGDT_64_DATA */
- Entry = KiGetGdtEntry(pGdt, KGDT_64_DATA);
- *(PULONG64)Entry = 0x00cff3000000ffffULL;
-
- /* Setup KGDT_64_R3_CODE */
- Entry = KiGetGdtEntry(pGdt, KGDT_64_R3_CODE);
- *(PULONG64)Entry = 0x0020fb0000000000ULL;
-
- /* Setup KGDT_32_R3_TEB */
- Entry = KiGetGdtEntry(pGdt, KGDT_32_R3_TEB);
- *(PULONG64)Entry = 0xff40f3fd50003c00ULL;
-
- /* Setup TSS entry */
- Entry = KiGetGdtEntry(pGdt, KGDT_TSS);
- KiInitGdtEntry(Entry, TssBase, sizeof(KTSS), I386_TSS, 0);
-
- /* Setup the gdt descriptor */
- Desc.Limit = 12 * sizeof(ULONG64) - 1;
- Desc.Base = (PVOID)GdtBase;
-
- /* Set the new Gdt */
- __lgdt(&Desc.Limit);
- DbgPrint("Gdtr.Base = %p\n", Desc.Base);
-
- /* Setup the idt descriptor */
- Desc.Limit = 12 * sizeof(ULONG64) - 1;
- Desc.Base = (PVOID)IdtBase;
-
- /* Set the new Idt */
- __lidt(&Desc.Limit);
- DbgPrint("Idtr.Base = %p\n", Desc.Base);
-
-}
PKGDTENTRY64 Entry;
KDESCRIPTOR GdtDesc;
- /* Setup KGDT_64_R0_CODE */
- Entry = KiGetGdtEntry(GdtBase, KGDT_64_R0_CODE);
+ /* Setup KGDT64_NULL */
+ Entry = KiGetGdtEntry(GdtBase, KGDT64_NULL);
+ *(PULONG64)Entry = 0x0000000000000000ULL;
+
+ /* Setup KGDT64_R0_CODE */
+ Entry = KiGetGdtEntry(GdtBase, KGDT64_R0_CODE);
*(PULONG64)Entry = 0x00209b0000000000ULL;
- /* Setup KGDT_64_R0_SS */
- Entry = KiGetGdtEntry(GdtBase, KGDT_64_R0_SS);
+ /* Setup KGDT64_R0_DATA */
+ Entry = KiGetGdtEntry(GdtBase, KGDT64_R0_DATA);
*(PULONG64)Entry = 0x00cf93000000ffffULL;
- /* Setup KGDT_64_DATA */
- Entry = KiGetGdtEntry(GdtBase, KGDT_64_DATA);
+ /* Setup KGDT64_R3_CMCODE */
+ Entry = KiGetGdtEntry(GdtBase, KGDT64_R3_CMCODE);
+ *(PULONG64)Entry = 0x00cffb000000ffffULL;
+
+ /* Setup KGDT64_R3_DATA */
+ Entry = KiGetGdtEntry(GdtBase, KGDT64_R3_DATA);
*(PULONG64)Entry = 0x00cff3000000ffffULL;
- /* Setup KGDT_64_R3_CODE */
- Entry = KiGetGdtEntry(GdtBase, KGDT_64_R3_CODE);
+ /* Setup KGDT64_R3_CODE */
+ Entry = KiGetGdtEntry(GdtBase, KGDT64_R3_CODE);
*(PULONG64)Entry = 0x0020fb0000000000ULL;
- /* Setup KGDT_32_R3_TEB */
- Entry = KiGetGdtEntry(GdtBase, KGDT_32_R3_TEB);
+ /* Setup KGDT64_R3_CMTEB */
+ Entry = KiGetGdtEntry(GdtBase, KGDT64_R3_CMTEB);
*(PULONG64)Entry = 0xff40f3fd50003c00ULL;
/* Setup TSS entry */
- Entry = KiGetGdtEntry(GdtBase, KGDT_TSS);
+ Entry = KiGetGdtEntry(GdtBase, KGDT64_SYS_TSS);
KiInitGdtEntry(Entry, TssBase, sizeof(KTSS), I386_TSS, 0);
/* Setup GDT descriptor */
/* LDT is unused */
// __lldt(0);
- /* Load selectors for DS/ES/FS/GS/SS */
- Ke386SetDs(KGDT_64_DATA | RPL_MASK); // 0x2b
- Ke386SetEs(KGDT_64_DATA | RPL_MASK); // 0x2b
- Ke386SetFs(KGDT_32_R3_TEB | RPL_MASK); // 0x53
- Ke386SetGs(KGDT_64_DATA | RPL_MASK); // 0x2b
- Ke386SetSs(KGDT_64_R0_SS); // 0x18
-
/* Load TSR */
- __ltr(KGDT_TSS);
+ __ltr(KGDT64_SYS_TSS);
DPRINTM(DPRINT_WINDOWS, "leave WinLdrSetProcessorContext\n");
}