https://git.reactos.org/?p=reactos.git;a=commitdiff;h=e56911f66bf933d12d1bc…
commit e56911f66bf933d12d1bc247f041dc99ca8c7078
Author: Timo Kreuzer <timo.kreuzer(a)reactos.org>
AuthorDate: Sun Oct 6 08:23:55 2024 +0300
Commit: Timo Kreuzer <timo.kreuzer(a)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")