https://git.reactos.org/?p=reactos.git;a=commitdiff;h=e56911f66bf933d12d1bc247f041dc99ca8c7078
commit e56911f66bf933d12d1bc247f041dc99ca8c7078 Author: Timo Kreuzer <timo.kreu...@reactos.org> AuthorDate: Sun Oct 6 08:23:55 2024 +0300 Commit: Timo Kreuzer <timo.kreu...@reactos.org> CommitDate: Tue Feb 4 16:45:48 2025 +0200 [FREELDR] Implement loading of rosload as 2nd stage loader --- boot/freeldr/freeldr/CMakeLists.txt | 20 ++---------- boot/freeldr/freeldr/freeldr.c | 64 ++++++++++++++++++++++++++++++++++++- boot/freeldr/freeldr/freeldr.spec | 48 +--------------------------- boot/freeldr/freeldr/lib/peloader.c | 5 ++- boot/freeldr/freeldr/pcat.cmake | 6 ++-- boot/freeldr/freeldr/uefi.cmake | 14 ++++++-- 6 files changed, 84 insertions(+), 73 deletions(-) diff --git a/boot/freeldr/freeldr/CMakeLists.txt b/boot/freeldr/freeldr/CMakeLists.txt index ef1426cff19..ffbdaffa178 100644 --- a/boot/freeldr/freeldr/CMakeLists.txt +++ b/boot/freeldr/freeldr/CMakeLists.txt @@ -58,11 +58,6 @@ list(APPEND FREELDR_BOOTLIB_SOURCE list(APPEND FREELDR_BOOTMGR_SOURCE include/freeldr.h - custom.c - # linuxboot.c - miscboot.c - options.c - oslist.c settings.c ui/directui.c # ui/gui.c @@ -88,10 +83,7 @@ if(ARCH STREQUAL "i386") # arch/i386/linux.S list(APPEND FREELDR_ARC_SOURCE - arch/i386/i386bug.c - arch/i386/halstub.c - arch/i386/ntoskrnl.c - disk/scsiport.c) + arch/i386/i386bug.c) list(APPEND FREELDR_NTLDR_SOURCE ntldr/arch/i386/winldr.c @@ -118,17 +110,11 @@ else() endif() list(APPEND FREELDR_BASE_SOURCE - bootmgr.c # This file is compiled with custom definitions freeldr.c - ntldr/setupldr.c ## Strangely enough this file is needed in GCC builds - ## even if ${FREELDR_NTLDR_SOURCE} is not added, - ## otherwise we get linking errors with Rtl**Bitmap** APIs. - ## Do not happen on MSVC builds however... - ntldr/inffile.c - ntldr/ntldropts.c + ntldr/ntldropts.c # Should be in rosload, but is currently needed by machpc.c, etc. lib/rtl/libsupp.c) -if(ARCH STREQUAL "i386") +if(ARCH STREQUAL "i386" OR ARCH STREQUAL "amd64") # Must be included together with disk/scsiport.c list(APPEND FREELDR_BASE_SOURCE ${CMAKE_CURRENT_BINARY_DIR}/freeldr.def) diff --git a/boot/freeldr/freeldr/freeldr.c b/boot/freeldr/freeldr/freeldr.c index e1c58709bda..e39cf7e84aa 100644 --- a/boot/freeldr/freeldr/freeldr.c +++ b/boot/freeldr/freeldr/freeldr.c @@ -30,6 +30,64 @@ CCHAR FrLdrBootPath[MAX_PATH] = ""; /* FUNCTIONS ******************************************************************/ +static +BOOLEAN +LoadRosload( + _In_ PCSTR RosloadPath, + _Out_ PVOID* ImageBase, + _Out_ PLDR_DATA_TABLE_ENTRY* DataTableEntry) +{ + CHAR FullPath[MAX_PATH]; + BOOLEAN Success; + + /* Create full rosload.exe path */ + RtlStringCbPrintfA(FullPath, + sizeof(FullPath), + "%s\\%s", + FrLdrBootPath, + RosloadPath); + + TRACE("Loading second stage loader '%s'\n", FullPath); + + /* Load rosload.exe as a bootloader image. The base name is "scsiport.sys", + because it exports ScsiPort* functions for ntbootdd.sys */ + Success = PeLdrLoadBootImage(FullPath, + "scsiport.sys", + ImageBase, + DataTableEntry); + if (!Success) + { + WARN("Failed to load second stage loader '%s'\n", FullPath); + return FALSE; + } + + return TRUE; +} + +static +ULONG +LaunchSecondStageLoader(VOID) +{ + PLDR_DATA_TABLE_ENTRY RosloadDTE; + PVOID ImageBase; + LONG (*EntryPoint)(VOID); + + /* Load the second stage loader */ + if (!LoadRosload("rosload.exe", &ImageBase, &RosloadDTE)) + { + /* Try in loader directory */ + if (!LoadRosload("loader\\rosload.exe", &ImageBase, &RosloadDTE)) + { + return ENOENT; + } + } + + /* Call the entrypoint */ + printf("Launching rosload.exe...\n"); + EntryPoint = VaToPa(RosloadDTE->EntryPoint); + return (*EntryPoint)(); +} + VOID __cdecl BootMain(IN PCCH CmdLine) { /* Load the default settings from the command-line */ @@ -77,7 +135,11 @@ VOID __cdecl BootMain(IN PCCH CmdLine) goto Quit; } - RunLoader(); + /* Launch second stage loader */ + if (LaunchSecondStageLoader() != ESUCCESS) + { + UiMessageBoxCritical("Unable to load second stage loader."); + } Quit: /* If we reach this point, something went wrong before, therefore reboot */ diff --git a/boot/freeldr/freeldr/freeldr.spec b/boot/freeldr/freeldr/freeldr.spec index 2ea08b1927c..6d7b5f9d788 100644 --- a/boot/freeldr/freeldr/freeldr.spec +++ b/boot/freeldr/freeldr/freeldr.spec @@ -1,50 +1,3 @@ -@ stdcall RtlAssert(ptr ptr long ptr) -@ varargs -arch=i386 ScsiDebugPrint(long str) -@ stdcall -arch=i386 ScsiPortCompleteRequest(ptr long long long long) -@ stdcall -arch=i386 ScsiPortConvertPhysicalAddressToUlong(long long) -@ stdcall -arch=i386 ScsiPortConvertUlongToPhysicalAddress(long) -#@ stdcall -arch=x86_64 ScsiPortConvertUlongToPhysicalAddress(long) -@ stdcall -arch=i386 ScsiPortFlushDma(ptr) -@ stdcall -arch=i386 ScsiPortFreeDeviceBase(ptr ptr) -@ stdcall -arch=i386 ScsiPortGetBusData(ptr long long long ptr long) -@ stdcall -arch=i386 ScsiPortGetDeviceBase(ptr long long long long long long) -@ stdcall -arch=i386 ScsiPortGetLogicalUnit(ptr long long long) -@ stdcall -arch=i386 ScsiPortGetPhysicalAddress(ptr ptr ptr long) -@ stdcall -arch=i386 ScsiPortGetSrb(ptr long long long long) -@ stdcall -arch=i386 ScsiPortGetUncachedExtension(ptr ptr long) -@ stdcall -arch=i386 ScsiPortGetVirtualAddress(ptr long long) -@ stdcall -arch=i386 ScsiPortInitialize(ptr ptr ptr ptr) -@ stdcall -arch=i386 ScsiPortIoMapTransfer(ptr ptr long long) -@ stdcall -arch=i386 ScsiPortLogError(ptr ptr long long long long long) -@ stdcall -arch=i386 ScsiPortMoveMemory(ptr ptr long) -@ cdecl -arch=i386 ScsiPortNotification() -@ stdcall -arch=i386 ScsiPortReadPortBufferUchar(ptr ptr long) -@ stdcall -arch=i386 ScsiPortReadPortBufferUshort(ptr ptr long) -@ stdcall -arch=i386 ScsiPortReadPortBufferUlong(ptr ptr long) -@ stdcall -arch=i386 ScsiPortReadPortUchar(ptr) -@ stdcall -arch=i386 ScsiPortReadPortUshort(ptr) -@ stdcall -arch=i386 ScsiPortReadPortUlong(ptr) -@ stdcall -arch=i386 ScsiPortReadRegisterBufferUchar(ptr ptr long) -@ stdcall -arch=i386 ScsiPortReadRegisterBufferUshort(ptr ptr long) -@ stdcall -arch=i386 ScsiPortReadRegisterBufferUlong(ptr ptr long) -@ stdcall -arch=i386 ScsiPortReadRegisterUchar(ptr) -@ stdcall -arch=i386 ScsiPortReadRegisterUshort(ptr) -@ stdcall -arch=i386 ScsiPortReadRegisterUlong(ptr) -@ stdcall -arch=i386 ScsiPortSetBusDataByOffset(ptr long long long ptr long long) -@ stdcall -arch=i386 ScsiPortStallExecution(long) -@ stdcall -arch=i386 ScsiPortValidateRange(ptr long long long long long long) -@ stdcall -arch=i386 ScsiPortWritePortBufferUchar(ptr ptr long) -@ stdcall -arch=i386 ScsiPortWritePortBufferUshort(ptr ptr long) -@ stdcall -arch=i386 ScsiPortWritePortBufferUlong(ptr ptr long) -@ stdcall -arch=i386 ScsiPortWritePortUchar(ptr long) -@ stdcall -arch=i386 ScsiPortWritePortUshort(ptr long) -@ stdcall -arch=i386 ScsiPortWritePortUlong(ptr long) -@ stdcall -arch=i386 ScsiPortWriteRegisterBufferUchar(ptr ptr long) -@ stdcall -arch=i386 ScsiPortWriteRegisterBufferUshort(ptr ptr long) -@ stdcall -arch=i386 ScsiPortWriteRegisterBufferUlong(ptr ptr long) -@ stdcall -arch=i386 ScsiPortWriteRegisterUchar(ptr long) -@ stdcall -arch=i386 ScsiPortWriteRegisterUshort(ptr long) -@ stdcall -arch=i386 ScsiPortWriteRegisterUlong(ptr long) # ARC @ cdecl ArcClose() @@ -164,6 +117,7 @@ @ cdecl RamDiskInitialize() @ cdecl Reboot() @ cdecl Relocator16Boot() +@ stdcall RtlAssert(ptr ptr long ptr) @ cdecl StallExecutionProcessor() # Additional stuff for scsiport diff --git a/boot/freeldr/freeldr/lib/peloader.c b/boot/freeldr/freeldr/lib/peloader.c index 750e18547ff..5015704a521 100644 --- a/boot/freeldr/freeldr/lib/peloader.c +++ b/boot/freeldr/freeldr/lib/peloader.c @@ -528,10 +528,9 @@ PeLdrInitializeModuleList(VOID) InitializeListHead(&FrLdrModuleList); - /* Allocate a data table entry for freeldr.sys. - The base name is scsiport.sys for imports from ntbootdd.sys */ + /* Allocate a data table entry for freeldr.sys */ if (!PeLdrAllocateDataTableEntry(&FrLdrModuleList, - "scsiport.sys", + "freeldr.sys", "freeldr.sys", &__ImageBase, &FreeldrDTE)) diff --git a/boot/freeldr/freeldr/pcat.cmake b/boot/freeldr/freeldr/pcat.cmake index 02c85cf7110..78121be46f8 100644 --- a/boot/freeldr/freeldr/pcat.cmake +++ b/boot/freeldr/freeldr/pcat.cmake @@ -155,7 +155,7 @@ add_library(freeldr_common ${PCATLDR_ARC_SOURCE} ${FREELDR_BOOTLIB_SOURCE} ${PCATLDR_BOOTMGR_SOURCE} - ${FREELDR_NTLDR_SOURCE}) +) if(MSVC AND CMAKE_C_COMPILER_ID STREQUAL "Clang") # We need to reduce the binary size @@ -170,7 +170,7 @@ set(PCH_SOURCE ${PCATLDR_ARC_SOURCE} ${FREELDR_BOOTLIB_SOURCE} ${PCATLDR_BOOTMGR_SOURCE} - ${FREELDR_NTLDR_SOURCE}) +) add_pch(freeldr_common include/freeldr.h PCH_SOURCE) add_dependencies(freeldr_common bugcodes asm xdk) @@ -221,7 +221,7 @@ if(ARCH STREQUAL "i386") target_link_libraries(freeldr_pe mini_hal) endif() -target_link_libraries(freeldr_pe freeldr_common cportlib blcmlib blrtl libcntpr) +target_link_libraries(freeldr_pe freeldr_common cportlib libcntpr blrtl) # dynamic analysis switches if(STACK_PROTECTOR) diff --git a/boot/freeldr/freeldr/uefi.cmake b/boot/freeldr/freeldr/uefi.cmake index a3bc6a7e2e0..97a9a82c102 100644 --- a/boot/freeldr/freeldr/uefi.cmake +++ b/boot/freeldr/freeldr/uefi.cmake @@ -43,13 +43,20 @@ else() #TBD endif() +list(APPEND UEFILDR_BOOTMGR_SOURCE + ${FREELDR_BOOTMGR_SOURCE} + custom.c + options.c + oslist.c +) + add_asm_files(uefifreeldr_common_asm ${FREELDR_COMMON_ASM_SOURCE} ${UEFILDR_COMMON_ASM_SOURCE}) add_library(uefifreeldr_common ${uefifreeldr_common_asm} ${UEFILDR_ARC_SOURCE} ${FREELDR_BOOTLIB_SOURCE} - ${FREELDR_BOOTMGR_SOURCE} + ${UEFILDR_BOOTMGR_SOURCE} ${FREELDR_NTLDR_SOURCE}) target_compile_definitions(uefifreeldr_common PRIVATE UEFIBOOT) @@ -62,7 +69,7 @@ endif() set(PCH_SOURCE ${UEFILDR_ARC_SOURCE} ${FREELDR_BOOTLIB_SOURCE} - ${FREELDR_BOOTMGR_SOURCE} + ${UEFILDR_BOOTMGR_SOURCE} ${FREELDR_NTLDR_SOURCE}) add_pch(uefifreeldr_common include/arch/uefi/uefildr.h PCH_SOURCE) @@ -79,6 +86,9 @@ spec2def(uefildr.exe freeldr.spec) list(APPEND UEFILDR_BASE_SOURCE include/arch/uefi/uefildr.h arch/uefi/uefildr.c + bootmgr.c + ntldr/setupldr.c + ntldr/inffile.c ${FREELDR_BASE_SOURCE}) if(ARCH STREQUAL "i386")