From dd6c1c884311599543416b6d55bb1d420923bdf6 Mon Sep 17 00:00:00 2001 From: Mark Harmstone Date: Mon, 9 Sep 2019 19:45:42 +0100 Subject: [PATCH] [FREELDR] Allow Freeloader to boot Vista revamp of PR #1905 (#6479) [FREELDR] Add "WindowsVista" boot type [FREELDR] Set GDT correctly for Vista [FREELDR] Map first page of memory, this is an observed behavior, and also increases stability boot Checked windows 2003 SP2 ntoskrnl with freeloader. [SDK] Don't assert on big keys in bootloader Co-authored-by: Justin Miller --- boot/freeldr/freeldr/bootmgr.c | 1 + .../freeldr/freeldr/ntldr/arch/amd64/winldr.c | 3 ++- boot/freeldr/freeldr/ntldr/arch/arm/winldr.c | 3 ++- boot/freeldr/freeldr/ntldr/arch/i386/winldr.c | 27 +++++++++++-------- boot/freeldr/freeldr/ntldr/winldr.c | 15 ++++++++++- boot/freeldr/freeldr/ntldr/winldr.h | 4 ++- boot/freeldr/freeldr/ntldr/wlmemory.c | 11 ++++---- sdk/lib/cmlib/cmlib.h | 4 +++ 8 files changed, 47 insertions(+), 21 deletions(-) diff --git a/boot/freeldr/freeldr/bootmgr.c b/boot/freeldr/freeldr/bootmgr.c index 1f22c3182db..b0dc77ee324 100644 --- a/boot/freeldr/freeldr/bootmgr.c +++ b/boot/freeldr/freeldr/bootmgr.c @@ -69,6 +69,7 @@ OSLoadingMethods[] = #endif {"Windows" , EditCustomBootNTOS , LoadAndBootWindows}, {"Windows2003" , EditCustomBootNTOS , LoadAndBootWindows}, + {"WindowsVista", EditCustomBootNTOS , LoadAndBootWindows}, }; /* FUNCTIONS ******************************************************************/ diff --git a/boot/freeldr/freeldr/ntldr/arch/amd64/winldr.c b/boot/freeldr/freeldr/ntldr/arch/amd64/winldr.c index 19359798fa9..a5fc5a0fc53 100644 --- a/boot/freeldr/freeldr/ntldr/arch/amd64/winldr.c +++ b/boot/freeldr/freeldr/ntldr/arch/amd64/winldr.c @@ -346,7 +346,8 @@ Amd64SetupIdt(PVOID IdtBase) } VOID -WinLdrSetProcessorContext(void) +WinLdrSetProcessorContext( + _In_ USHORT OperatingSystemVersion) { TRACE("WinLdrSetProcessorContext\n"); diff --git a/boot/freeldr/freeldr/ntldr/arch/arm/winldr.c b/boot/freeldr/freeldr/ntldr/arch/arm/winldr.c index 0bb69147e37..4cce3a60351 100644 --- a/boot/freeldr/freeldr/ntldr/arch/arm/winldr.c +++ b/boot/freeldr/freeldr/ntldr/arch/arm/winldr.c @@ -249,7 +249,8 @@ MempAllocatePageTables(VOID) } VOID -WinLdrSetProcessorContext(VOID) +WinLdrSetProcessorContext( + _In_ USHORT OperatingSystemVersion) { ARM_CONTROL_REGISTER ControlRegister; ARM_TTB_REGISTER TtbRegister; diff --git a/boot/freeldr/freeldr/ntldr/arch/i386/winldr.c b/boot/freeldr/freeldr/ntldr/arch/i386/winldr.c index 852fb7b12f3..0999baf60d0 100644 --- a/boot/freeldr/freeldr/ntldr/arch/i386/winldr.c +++ b/boot/freeldr/freeldr/ntldr/arch/i386/winldr.c @@ -245,7 +245,7 @@ MempSetupPaging(IN PFN_NUMBER StartPage, } PhysicalPT[Page & 0x3ff].PageFrameNumber = Page; - PhysicalPT[Page & 0x3ff].Valid = (Page != 0); + PhysicalPT[Page & 0x3ff].Valid = 1; PhysicalPT[Page & 0x3ff].Write = (Page != 0); if (KernelMapping) @@ -429,7 +429,8 @@ void WinLdrSetupMachineDependent(PLOADER_PARAMETER_BLOCK LoaderBlock) VOID -WinLdrSetProcessorContext(void) +WinLdrSetProcessorContext( + _In_ USHORT OperatingSystemVersion) { GDTIDT GdtDesc, IdtDesc, OldIdt; PKGDTENTRY pGdt; @@ -526,15 +527,19 @@ WinLdrSetProcessorContext(void) * Longhorn/Vista reports LimitLow == 0x0fff == MM_PAGE_SIZE - 1, whereas * Windows 7+ uses larger sizes there (not aligned on a page boundary). */ -#if 1 - /* Server 2003 way */ - KiSetGdtEntryEx(KiGetGdtEntry(pGdt, KGDT_R0_PCR), (ULONG32)Pcr, 0x1, - TYPE_DATA, DPL_SYSTEM, TRUE, 2); -#else - /* Vista+ way */ - KiSetGdtEntry(KiGetGdtEntry(pGdt, KGDT_R0_PCR), (ULONG32)Pcr, MM_PAGE_SIZE - 1, - TYPE_DATA, DPL_SYSTEM, 2); -#endif + if (OperatingSystemVersion < _WIN32_WINNT_VISTA) + { + /* Server 2003 way */ + KiSetGdtEntryEx(KiGetGdtEntry(pGdt, KGDT_R0_PCR), (ULONG32)Pcr, 0x1, + TYPE_DATA, DPL_SYSTEM, TRUE, 2); + } + else + { + /* Vista+ way */ + KiSetGdtEntry(KiGetGdtEntry(pGdt, KGDT_R0_PCR), (ULONG32)Pcr, MM_PAGE_SIZE - 1, + TYPE_DATA, DPL_SYSTEM, 2); + } + // DumpGDTEntry(GdtDesc.Base, KGDT_R0_PCR); /* KGDT_R3_TEB (0x38) Thread Environment Block Selector (Ring 3) */ diff --git a/boot/freeldr/freeldr/ntldr/winldr.c b/boot/freeldr/freeldr/ntldr/winldr.c index 7e02fcfd419..4b4d46204ae 100644 --- a/boot/freeldr/freeldr/ntldr/winldr.c +++ b/boot/freeldr/freeldr/ntldr/winldr.c @@ -255,6 +255,15 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock, // FIXME: Extension->AcpiTableSize; } + if (VersionToBoot >= _WIN32_WINNT_VISTA) + { + Extension->BootViaWinload = 1; + Extension->LoaderPerformanceData = PaToVa(&WinLdrSystemBlock->LoaderPerformanceData); + + InitializeListHead(&Extension->BootApplicationPersistentData); + List_PaToVa(&Extension->BootApplicationPersistentData); + } + #ifdef _M_IX86 /* Set headless block pointer */ if (WinLdrTerminalConnected) @@ -999,6 +1008,10 @@ LoadAndBootWindows( { OperatingSystemVersion = _WIN32_WINNT_NT4; } + else if (_stricmp(ArgValue, "WindowsVista") == 0) + { + OperatingSystemVersion = _WIN32_WINNT_VISTA; + } else { ERR("Unknown 'BootType' value '%s', aborting!\n", ArgValue); @@ -1245,7 +1258,7 @@ LoadAndBootWindowsCommon( WinLdrSetupMemoryLayout(LoaderBlock); /* Set processor context */ - WinLdrSetProcessorContext(); + WinLdrSetProcessorContext(OperatingSystemVersion); /* Save final value of LoaderPagesSpanned */ LoaderBlock->Extension->LoaderPagesSpanned = LoaderPagesSpanned; diff --git a/boot/freeldr/freeldr/ntldr/winldr.h b/boot/freeldr/freeldr/ntldr/winldr.h index 20a20ba7cce..b18c8f4f78a 100644 --- a/boot/freeldr/freeldr/ntldr/winldr.h +++ b/boot/freeldr/freeldr/ntldr/winldr.h @@ -58,6 +58,7 @@ typedef struct _LOADER_SYSTEM_BLOCK CHAR NtBootPathName[MAX_PATH+1]; CHAR NtHalPathName[MAX_PATH+1]; ARC_DISK_INFORMATION ArcDiskInformation; + LOADER_PERFORMANCE_DATA LoaderPerformanceData; } LOADER_SYSTEM_BLOCK, *PLOADER_SYSTEM_BLOCK; extern PLOADER_SYSTEM_BLOCK WinLdrSystemBlock; @@ -164,7 +165,8 @@ VOID WinLdrSetupMachineDependent(PLOADER_PARAMETER_BLOCK LoaderBlock); VOID -WinLdrSetProcessorContext(VOID); +WinLdrSetProcessorContext( + _In_ USHORT OperatingSystemVersion); // arch/xxx/winldr.c BOOLEAN diff --git a/boot/freeldr/freeldr/ntldr/wlmemory.c b/boot/freeldr/freeldr/ntldr/wlmemory.c index 3d29c241a0f..f784e1b2ef5 100644 --- a/boot/freeldr/freeldr/ntldr/wlmemory.c +++ b/boot/freeldr/freeldr/ntldr/wlmemory.c @@ -185,7 +185,7 @@ WinLdrSetupMemoryLayout(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock) PPAGE_LOOKUP_TABLE_ITEM MemoryMap; ULONG LastPageType; //PKTSS Tss; - //BOOLEAN Status; + BOOLEAN Status; /* Cleanup heap */ FrLdrHeapCleanupAll(); @@ -229,15 +229,14 @@ WinLdrSetupMemoryLayout(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock) MemoryMapSizeInPages = (NoEntries * sizeof(PAGE_LOOKUP_TABLE_ITEM) + MM_PAGE_SIZE - 1) / MM_PAGE_SIZE; TRACE("Got memory map with %d entries\n", NoEntries); -#if 0 - // Always contiguously map low 1Mb of memory - Status = MempSetupPaging(0, 0x100, FALSE); + + // Always map first page of memory + Status = MempSetupPaging(0, 1, FALSE); if (!Status) { - ERR("Error during MempSetupPaging of low 1Mb\n"); + ERR("Error during MempSetupPaging of first page\n"); return FALSE; } -#endif /* Before creating the map, we need to map pages to kernel mode */ LastPageIndex = 1; diff --git a/sdk/lib/cmlib/cmlib.h b/sdk/lib/cmlib/cmlib.h index aee69f58460..7fcb6c6e1f5 100644 --- a/sdk/lib/cmlib/cmlib.h +++ b/sdk/lib/cmlib/cmlib.h @@ -379,8 +379,12 @@ extern ULONG CmlibTraceLevel; // // Hack since big keys are not yet supported // +#ifdef _BLDR_ +#define ASSERT_VALUE_BIG(h, s) DbgPrint("Big keys aren't supported!\n"); +#else #define ASSERT_VALUE_BIG(h, s) \ ASSERTMSG("Big keys not supported!\n", !CmpIsKeyValueBig(h, s)); +#endif // // Returns whether or not this is a small valued key