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")

Reply via email to