[FREELDR] Implement loading of rosload as 2nd stage loader

This commit is contained in:
Timo Kreuzer 2024-10-06 08:23:55 +03:00
parent adacd51a30
commit e56911f66b
6 changed files with 84 additions and 73 deletions

View file

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

View file

@ -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 */

View file

@ -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

View file

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

View file

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

View file

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