XTLDR Rewrite #7
@ -168,6 +168,15 @@ typedef struct _XTBL_LOADER_PROTOCOL
|
|||||||
} Util;
|
} Util;
|
||||||
} XTBL_LOADER_PROTOCOL, *PXTBL_LOADER_PROTOCOL;
|
} XTBL_LOADER_PROTOCOL, *PXTBL_LOADER_PROTOCOL;
|
||||||
|
|
||||||
|
/* XTLDR Module information data */
|
||||||
|
typedef struct _XTBL_MODULE_INFO
|
||||||
|
{
|
||||||
|
LIST_ENTRY Flink;
|
||||||
|
PWCHAR ModuleName;
|
||||||
|
PWCHAR ModuleDescription;
|
||||||
|
WCHAR Dependencies[1024];
|
||||||
|
} XTBL_MODULE_INFO, *PXTBL_MODULE_INFO;
|
||||||
|
|
||||||
/* XTLDR Status data */
|
/* XTLDR Status data */
|
||||||
typedef struct _XTBL_STATUS
|
typedef struct _XTBL_STATUS
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
# XT Boot Manager
|
# XT Boot Manager
|
||||||
PROJECT(XTLDR)
|
PROJECT(XTLDR)
|
||||||
|
|
||||||
|
# Build XTLDR modules
|
||||||
|
add_subdirectory(modules)
|
||||||
|
|
||||||
# Specify include directories
|
# Specify include directories
|
||||||
include_directories(
|
include_directories(
|
||||||
${EXECTOS_SOURCE_DIR}/sdk/xtdk
|
${EXECTOS_SOURCE_DIR}/sdk/xtdk
|
||||||
|
@ -143,8 +143,9 @@ BlpInitializeEfiBootLoader()
|
|||||||
/* Print XTLDR version */
|
/* Print XTLDR version */
|
||||||
BlConsolePrint(L"XTLDR boot loader v%s\n", XTOS_VERSION);
|
BlConsolePrint(L"XTLDR boot loader v%s\n", XTOS_VERSION);
|
||||||
|
|
||||||
/* Initialize XTLDR configuration list */
|
/* Initialize XTLDR configuration and loaded modules lists */
|
||||||
RtlInitializeListHead(&BlpConfig);
|
RtlInitializeListHead(&BlpConfig);
|
||||||
|
RtlInitializeListHead(&BlpLoadedModules);
|
||||||
|
|
||||||
/* Check if debug is enabled */
|
/* Check if debug is enabled */
|
||||||
if(DEBUG)
|
if(DEBUG)
|
||||||
|
@ -18,6 +18,9 @@ LIST_ENTRY BlpConfigSections;
|
|||||||
/* XT Boot Loader hex table */
|
/* XT Boot Loader hex table */
|
||||||
STATIC PUINT16 BlpHexTable = L"0123456789ABCDEF";
|
STATIC PUINT16 BlpHexTable = L"0123456789ABCDEF";
|
||||||
|
|
||||||
|
/* XT Boot Loader loaded modules list */
|
||||||
|
LIST_ENTRY BlpLoadedModules;
|
||||||
|
|
||||||
/* XT Boot Loader menu list */
|
/* XT Boot Loader menu list */
|
||||||
PLIST_ENTRY BlpMenuList = NULL;
|
PLIST_ENTRY BlpMenuList = NULL;
|
||||||
|
|
||||||
|
@ -21,6 +21,9 @@ EXTERN LIST_ENTRY BlpConfigSections;
|
|||||||
/* XT Boot Loader hex table */
|
/* XT Boot Loader hex table */
|
||||||
EXTERN PUINT16 BlpHexTable;
|
EXTERN PUINT16 BlpHexTable;
|
||||||
|
|
||||||
|
/* XT Boot Loader loaded modules list */
|
||||||
|
EXTERN LIST_ENTRY BlpLoadedModules;
|
||||||
|
|
||||||
/* XT Boot Loader menu list */
|
/* XT Boot Loader menu list */
|
||||||
EXTERN PLIST_ENTRY BlpMenuList;
|
EXTERN PLIST_ENTRY BlpMenuList;
|
||||||
|
|
||||||
|
2
xtldr2/modules/CMakeLists.txt
Normal file
2
xtldr2/modules/CMakeLists.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
add_subdirectory(dummy)
|
||||||
|
add_subdirectory(dummy2)
|
26
xtldr2/modules/dummy/CMakeLists.txt
Normal file
26
xtldr2/modules/dummy/CMakeLists.txt
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# XT Boot Loader
|
||||||
|
PROJECT(XTLDR_DUMMY)
|
||||||
|
|
||||||
|
# Specify include directories
|
||||||
|
include_directories(
|
||||||
|
${EXECTOS_SOURCE_DIR}/sdk/xtdk
|
||||||
|
${XTLDR_SOURCE_DIR}/includes
|
||||||
|
${XTLDR_DUMMY_SOURCE_DIR}/includes)
|
||||||
|
|
||||||
|
# Specify list of source code files
|
||||||
|
list(APPEND XTLDR_DUMMY_SOURCE
|
||||||
|
${XTLDR_DUMMY_SOURCE_DIR}/dummy.c)
|
||||||
|
|
||||||
|
# Link bootloader executable
|
||||||
|
add_executable(dummy ${XTLDR_DUMMY_SOURCE})
|
||||||
|
|
||||||
|
# Add linker libraries
|
||||||
|
target_link_libraries(dummy libxtldr libxtos)
|
||||||
|
|
||||||
|
# Set proper binary name and install target
|
||||||
|
set_target_properties(dummy PROPERTIES SUFFIX .efi)
|
||||||
|
set_install_target(dummy efi/boot/xtldr/modules)
|
||||||
|
|
||||||
|
# Set module entrypoint and subsystem
|
||||||
|
set_entrypoint(dummy "XtLdrModuleMain")
|
||||||
|
set_subsystem(dummy efi_boot_service_driver)
|
36
xtldr2/modules/dummy/dummy.c
Normal file
36
xtldr2/modules/dummy/dummy.c
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
* PROJECT: ExectOS
|
||||||
|
* COPYRIGHT: See COPYING.md in the top level directory
|
||||||
|
* FILE: xtldr/modules/dummy/dummy.c
|
||||||
|
* DESCRIPTION: Dummy XTLDR module
|
||||||
|
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <xtblapi.h>
|
||||||
|
|
||||||
|
#define XTBL_MODDEP SEGMENT(".moddeps") CONST WCHAR XtBlpDeps[][8]
|
||||||
|
#define XTBL_MODINFO SEGMENT(".modinfo") CONST WCHAR XtBlpInfo[]
|
||||||
|
|
||||||
|
XTBL_MODDEP = {L"dummy2", L"dummy2"};
|
||||||
|
XTBL_MODINFO = L"Dummy XTLDR module";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This routine is the entry point of the XT EFI boot loader module.
|
||||||
|
*
|
||||||
|
* @param ImageHandle
|
||||||
|
* Firmware-allocated handle that identifies the image.
|
||||||
|
*
|
||||||
|
* @param SystemTable
|
||||||
|
* Provides the EFI system table.
|
||||||
|
*
|
||||||
|
* @return This routine returns status code.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTCDECL
|
||||||
|
EFI_STATUS
|
||||||
|
XtLdrModuleMain(IN EFI_HANDLE ImageHandle,
|
||||||
|
IN PEFI_SYSTEM_TABLE SystemTable)
|
||||||
|
{
|
||||||
|
return STATUS_EFI_SUCCESS;
|
||||||
|
}
|
26
xtldr2/modules/dummy2/CMakeLists.txt
Normal file
26
xtldr2/modules/dummy2/CMakeLists.txt
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# XT Boot Loader
|
||||||
|
PROJECT(XTLDR_DUMMY2)
|
||||||
|
|
||||||
|
# Specify include directories
|
||||||
|
include_directories(
|
||||||
|
${EXECTOS_SOURCE_DIR}/sdk/xtdk
|
||||||
|
${XTLDR_SOURCE_DIR}/includes
|
||||||
|
${XTLDR_DUMMY2_SOURCE_DIR}/includes)
|
||||||
|
|
||||||
|
# Specify list of source code files
|
||||||
|
list(APPEND XTLDR_DUMMY2_SOURCE
|
||||||
|
${XTLDR_DUMMY2_SOURCE_DIR}/dummy2.c)
|
||||||
|
|
||||||
|
# Link bootloader executable
|
||||||
|
add_executable(dummy2 ${XTLDR_DUMMY2_SOURCE})
|
||||||
|
|
||||||
|
# Add linker libraries
|
||||||
|
target_link_libraries(dummy2 libxtldr libxtos)
|
||||||
|
|
||||||
|
# Set proper binary name and install target
|
||||||
|
set_target_properties(dummy2 PROPERTIES SUFFIX .efi)
|
||||||
|
set_install_target(dummy2 efi/boot/xtldr/modules)
|
||||||
|
|
||||||
|
# Set module entrypoint and subsystem
|
||||||
|
set_entrypoint(dummy2 "XtLdrModuleMain")
|
||||||
|
set_subsystem(dummy2 efi_boot_service_driver)
|
34
xtldr2/modules/dummy2/dummy2.c
Normal file
34
xtldr2/modules/dummy2/dummy2.c
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/**
|
||||||
|
* PROJECT: ExectOS
|
||||||
|
* COPYRIGHT: See COPYING.md in the top level directory
|
||||||
|
* FILE: xtldr/modules/dummy/dummy.c
|
||||||
|
* DESCRIPTION: Dummy XTLDR module
|
||||||
|
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <xtblapi.h>
|
||||||
|
|
||||||
|
#define XTBL_MODDEP SEGMENT(".moddeps") CONST WCHAR XtBlpDeps[][8]
|
||||||
|
|
||||||
|
//XTBL_MODDEP = {L""};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This routine is the entry point of the XT EFI boot loader module.
|
||||||
|
*
|
||||||
|
* @param ImageHandle
|
||||||
|
* Firmware-allocated handle that identifies the image.
|
||||||
|
*
|
||||||
|
* @param SystemTable
|
||||||
|
* Provides the EFI system table.
|
||||||
|
*
|
||||||
|
* @return This routine returns status code.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTCDECL
|
||||||
|
EFI_STATUS
|
||||||
|
XtLdrModuleMain(IN EFI_HANDLE ImageHandle,
|
||||||
|
IN PEFI_SYSTEM_TABLE SystemTable)
|
||||||
|
{
|
||||||
|
return STATUS_EFI_SUCCESS;
|
||||||
|
}
|
@ -963,6 +963,9 @@ BlDisplayInputDialog(IN PWCHAR Caption,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
XTCDECL
|
||||||
|
EFI_STATUS
|
||||||
|
BlInvokeBootProtocol(IN PLIST_ENTRY Options);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -1075,10 +1078,17 @@ BlDisplayBootMenu()
|
|||||||
BlSetConsoleAttributes(Handle.DialogColor | Handle.TextColor);
|
BlSetConsoleAttributes(Handle.DialogColor | Handle.TextColor);
|
||||||
BlClearConsoleLine(Handle.PosY + Handle.Height + 4);
|
BlClearConsoleLine(Handle.PosY + Handle.Height + 4);
|
||||||
BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4);
|
BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4);
|
||||||
BlConsolePrint(L"Booting '%S' now...", MenuEntries[HighligtedEntryId].EntryName);
|
BlConsolePrint(L"Booting '%S' now...\n", MenuEntries[HighligtedEntryId].EntryName);
|
||||||
|
|
||||||
/* Boot the highlighted (chosen) OS */
|
/* Boot the highlighted (chosen) OS */
|
||||||
BlDisplayInfoDialog(L"XTLDR", L"Booting highlighted OS ...");
|
Status = BlInvokeBootProtocol(MenuEntries[HighligtedEntryId].Options);
|
||||||
|
if(Status != STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to boot OS */
|
||||||
|
BlDebugPrint(L"Failed to boot OS '%S' with status code: 0x%lx!\n",
|
||||||
|
MenuEntries[HighligtedEntryId].EntryName, Status);
|
||||||
|
BlDisplayErrorDialog(L"XTLDR", L"Failed to startup the selected Operating System.");
|
||||||
|
}
|
||||||
|
|
||||||
/* Break from boot menu event loop to redraw whole boot menu */
|
/* Break from boot menu event loop to redraw whole boot menu */
|
||||||
break;
|
break;
|
||||||
@ -1178,13 +1188,20 @@ BlDisplayBootMenu()
|
|||||||
BlSetConsoleAttributes(Handle.DialogColor | Handle.TextColor);
|
BlSetConsoleAttributes(Handle.DialogColor | Handle.TextColor);
|
||||||
BlClearConsoleLine(Handle.PosY + Handle.Height + 4);
|
BlClearConsoleLine(Handle.PosY + Handle.Height + 4);
|
||||||
BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4);
|
BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4);
|
||||||
BlConsolePrint(L"Booting '%S' now...", MenuEntries[HighligtedEntryId].EntryName);
|
BlConsolePrint(L"Booting '%S' now...\n", MenuEntries[HighligtedEntryId].EntryName);
|
||||||
|
|
||||||
/* Disable the timer just in case booting OS fails */
|
/* Disable the timer just in case booting OS fails */
|
||||||
TimeOut = -1;
|
TimeOut = -1;
|
||||||
|
|
||||||
/* Boot the highlighted (default) OS */
|
/* Boot the highlighted (default) OS */
|
||||||
BlDisplayInfoDialog(L"XTLDR", L"Booting highlighted OS ...");
|
Status = BlInvokeBootProtocol(MenuEntries[HighligtedEntryId].Options);
|
||||||
|
if(Status != STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to boot OS */
|
||||||
|
BlDebugPrint(L"Failed to boot OS '%S' with status code: 0x%lx!\n",
|
||||||
|
MenuEntries[HighligtedEntryId].EntryName, Status);
|
||||||
|
BlDisplayErrorDialog(L"XTLDR", L"Failed to startup the selected Operating System.");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
303
xtldr2/xtldr.c
303
xtldr2/xtldr.c
@ -9,6 +9,14 @@
|
|||||||
#include <xtldr.h>
|
#include <xtldr.h>
|
||||||
|
|
||||||
|
|
||||||
|
XTCDECL
|
||||||
|
EFI_STATUS
|
||||||
|
BlLoadModule(IN PWCHAR Module);
|
||||||
|
|
||||||
|
XTCDECL
|
||||||
|
EFI_STATUS
|
||||||
|
BlLoadModules(IN PWCHAR ModulesList);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes a list of operating systems for XTLDR boot menu.
|
* Initializes a list of operating systems for XTLDR boot menu.
|
||||||
*
|
*
|
||||||
@ -96,6 +104,266 @@ BlInitializeBootMenuList(OUT PXTBL_BOOTMENU_ITEM MenuEntries,
|
|||||||
MenuEntries = OsList;
|
MenuEntries = OsList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads all necessary modules and invokes boot protocol.
|
||||||
|
*
|
||||||
|
* @param OptionsList
|
||||||
|
* Supplies a pointer to list of options associated with chosen boot menu entry.
|
||||||
|
*
|
||||||
|
* @return This routine returns a status code.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTCDECL
|
||||||
|
EFI_STATUS
|
||||||
|
BlInvokeBootProtocol(IN PLIST_ENTRY OptionsList)
|
||||||
|
{
|
||||||
|
PWCHAR ModulesList, ProtocolName;
|
||||||
|
PLIST_ENTRY OptionsListEntry;
|
||||||
|
PXTBL_CONFIG_ENTRY Option;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
/* Set default values */
|
||||||
|
ModulesList = NULL;
|
||||||
|
ProtocolName = NULL;
|
||||||
|
|
||||||
|
/* Iterate through all options provided by boot menu entry */
|
||||||
|
OptionsListEntry = OptionsList->Flink;
|
||||||
|
while(OptionsListEntry != OptionsList)
|
||||||
|
{
|
||||||
|
/* Get option */
|
||||||
|
Option = CONTAIN_RECORD(OptionsListEntry, XTBL_CONFIG_ENTRY, Flink);
|
||||||
|
|
||||||
|
/* Look for boot protocol and modules list */
|
||||||
|
if(RtlCompareWideStringInsensitive(Option->Name, L"SYSTEMTYPE", 0) == 0)
|
||||||
|
{
|
||||||
|
/* Boot protocol found */
|
||||||
|
ProtocolName = Option->Value;
|
||||||
|
}
|
||||||
|
else if(RtlCompareWideStringInsensitive(Option->Name, L"BOOTMODULES", 0) == 0)
|
||||||
|
{
|
||||||
|
/* Set protocol name */
|
||||||
|
ModulesList = Option->Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move to the next option entry */
|
||||||
|
OptionsListEntry = OptionsListEntry->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load all necessary modules */
|
||||||
|
Status = BlLoadModules(ModulesList);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to load modules, print error message and return status code */
|
||||||
|
BlDebugPrint(L"Failed to load XTLDR modules\n");
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
for(;;);
|
||||||
|
|
||||||
|
/* This point should never be reached */
|
||||||
|
return STATUS_EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
XTCDECL
|
||||||
|
EFI_STATUS
|
||||||
|
BlLoadModules(IN PWCHAR ModulesList)
|
||||||
|
{
|
||||||
|
PWCHAR LastModule, Module;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
if(ModulesList != NULL)
|
||||||
|
{
|
||||||
|
/* Tokenize provided list of modules */
|
||||||
|
Module = RtlTokenizeWideString(ModulesList, L" ", &LastModule);
|
||||||
|
|
||||||
|
/* Iterate over all arguments passed to boot loader */
|
||||||
|
while(Module != NULL)
|
||||||
|
{
|
||||||
|
Status = BlLoadModule(Module);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to load module, print error message and return status code */
|
||||||
|
BlDebugPrint(L"Failed to load module '%S', status = 0x%lx\n", Module, Status);
|
||||||
|
// return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Take next module from the list */
|
||||||
|
Module = RtlTokenizeWideString(NULL, L" ", &LastModule);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return success */
|
||||||
|
return STATUS_EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
XTCDECL
|
||||||
|
EFI_STATUS
|
||||||
|
BlLoadModule(IN PWCHAR ModuleName)
|
||||||
|
{
|
||||||
|
EFI_MEMMAP_DEVICE_PATH ModuleDevicePath[2];
|
||||||
|
PEFI_FILE_HANDLE DirHandle, FsHandle;
|
||||||
|
EFI_HANDLE DiskHandle, ModuleHandle;
|
||||||
|
PPECOFF_IMAGE_SECTION_HEADER SectionHeader;
|
||||||
|
PPECOFF_IMAGE_DOS_HEADER DosHeader;
|
||||||
|
PPECOFF_IMAGE_PE_HEADER PeHeader;
|
||||||
|
PLIST_ENTRY ModuleListEntry;
|
||||||
|
WCHAR ModuleFileName[1024];
|
||||||
|
USHORT SectionIndex;
|
||||||
|
SIZE_T ModuleSize;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
PVOID ModuleData;
|
||||||
|
PWCHAR DepsData;
|
||||||
|
PXTBL_MODULE_INFO ModuleInfo;
|
||||||
|
|
||||||
|
ModuleListEntry = BlpLoadedModules.Flink;
|
||||||
|
while(ModuleListEntry != &BlpLoadedModules)
|
||||||
|
{
|
||||||
|
/* Get module information */
|
||||||
|
ModuleInfo = CONTAIN_RECORD(ModuleListEntry, XTBL_MODULE_INFO, Flink);
|
||||||
|
|
||||||
|
if(RtlCompareWideStringInsensitive(ModuleInfo->ModuleName, ModuleName, 0) == 0)
|
||||||
|
{
|
||||||
|
/* Module already loaded */
|
||||||
|
BlDebugPrint(L"Module '%S' already loaded\n", ModuleName);
|
||||||
|
return STATUS_EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move to the module */
|
||||||
|
ModuleListEntry = ModuleListEntry->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print debug message */
|
||||||
|
BlDebugPrint(L"Loading module '%S' ...\n", ModuleName);
|
||||||
|
|
||||||
|
/* Set module path */
|
||||||
|
RtlCopyMemory(ModuleFileName, ModuleName, sizeof(ModuleFileName) / sizeof(WCHAR));
|
||||||
|
RtlConcatenateWideString(ModuleFileName, L".EFI", 0);
|
||||||
|
|
||||||
|
/* Open EFI volume */
|
||||||
|
Status = BlOpenVolume(NULL, &DiskHandle, &FsHandle);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to open a volume */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open XTLDR modules directory and close the FS immediately */
|
||||||
|
Status = FsHandle->Open(FsHandle, &DirHandle, XTBL_MODULES_DIRECTORY_PATH, EFI_FILE_MODE_READ, 0);
|
||||||
|
FsHandle->Close(FsHandle);
|
||||||
|
|
||||||
|
/* Check if directory opened successfully */
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to open directory */
|
||||||
|
BlCloseVolume(DiskHandle);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read module file from disk and close EFI volume */
|
||||||
|
Status = BlReadFile(DirHandle, ModuleFileName, &ModuleData, &ModuleSize);
|
||||||
|
BlCloseVolume(DiskHandle);
|
||||||
|
|
||||||
|
/* Make sure module file was read successfully */
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to read file */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate memory for new option */
|
||||||
|
Status = BlMemoryAllocatePool(sizeof(XTBL_MODULE_INFO), (PVOID*)&ModuleInfo);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to allocate memory */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlZeroMemory(ModuleInfo, sizeof(XTBL_MODULE_INFO));
|
||||||
|
|
||||||
|
/* Setup PE/COFF EFI image headers */
|
||||||
|
DosHeader = (PPECOFF_IMAGE_DOS_HEADER)ModuleData;
|
||||||
|
PeHeader = (PPECOFF_IMAGE_PE_HEADER)(ModuleData + DosHeader->e_lfanew);
|
||||||
|
SectionHeader = (PPECOFF_IMAGE_SECTION_HEADER)((PUCHAR)&PeHeader->OptionalHeader +
|
||||||
|
PeHeader->FileHeader.SizeOfOptionalHeader);
|
||||||
|
|
||||||
|
/* Look for .moddeps section */
|
||||||
|
for(SectionIndex = 0; SectionIndex < PeHeader->FileHeader.NumberOfSections; SectionIndex++)
|
||||||
|
{
|
||||||
|
/* Check section name */
|
||||||
|
if(RtlCompareString((PCHAR)SectionHeader[SectionIndex].Name, ".moddeps", 8) == 0)
|
||||||
|
{
|
||||||
|
/* Store address of .moddeps data segment */
|
||||||
|
DepsData = ModuleData + SectionHeader[SectionIndex].PointerToRawData;
|
||||||
|
|
||||||
|
/* Iterate over all dependencies stored */
|
||||||
|
while(*DepsData != 0)
|
||||||
|
{
|
||||||
|
/* Load dependency module */
|
||||||
|
BlDebugPrint(L"Module '%S' requires '%S' ...\n", ModuleName, DepsData);
|
||||||
|
Status = BlLoadModule(DepsData);
|
||||||
|
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to load module, print error message and return status code */
|
||||||
|
BlDebugPrint(L"Failed to load dependency module '%S', status = 0x%lx\n", DepsData, Status);
|
||||||
|
return STATUS_EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add dependency module name to the list */
|
||||||
|
RtlConcatenateWideString(ModuleInfo->Dependencies, DepsData, RtlWideStringLength(DepsData, 0));
|
||||||
|
RtlConcatenateWideString(ModuleInfo->Dependencies, L" ", 1);
|
||||||
|
|
||||||
|
/* Get next dependency module name */
|
||||||
|
DepsData += 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(RtlCompareString((PCHAR)SectionHeader[SectionIndex].Name, ".modinfo", 8) == 0)
|
||||||
|
{
|
||||||
|
/* Store module description */
|
||||||
|
ModuleInfo->ModuleDescription = ModuleData + SectionHeader[SectionIndex].PointerToRawData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store module name */
|
||||||
|
ModuleInfo->ModuleName = ModuleName;
|
||||||
|
|
||||||
|
/* Setup module device path */
|
||||||
|
ModuleDevicePath[0].Header.Length[0] = sizeof(EFI_MEMMAP_DEVICE_PATH);
|
||||||
|
ModuleDevicePath[0].Header.Length[1] = sizeof(EFI_MEMMAP_DEVICE_PATH) >> 8;
|
||||||
|
ModuleDevicePath[0].Header.Type = EFI_HARDWARE_DEVICE_PATH;
|
||||||
|
ModuleDevicePath[0].Header.SubType = EFI_HARDWARE_MEMMAP_DP;
|
||||||
|
ModuleDevicePath[0].MemoryType = EfiLoaderData;
|
||||||
|
ModuleDevicePath[0].StartingAddress = (UINT_PTR)ModuleData;
|
||||||
|
ModuleDevicePath[0].EndingAddress = (UINT_PTR)ModuleData + ModuleSize;
|
||||||
|
ModuleDevicePath[1].Header.Length[0] = sizeof(EFI_DEVICE_PATH_PROTOCOL);
|
||||||
|
ModuleDevicePath[1].Header.Length[1] = sizeof(EFI_DEVICE_PATH_PROTOCOL) >> 8;
|
||||||
|
ModuleDevicePath[1].Header.Type = EFI_END_DEVICE_PATH;
|
||||||
|
ModuleDevicePath[1].Header.SubType = EFI_END_ENTIRE_DP;
|
||||||
|
|
||||||
|
/* Load EFI image */
|
||||||
|
Status = EfiSystemTable->BootServices->LoadImage(FALSE, EfiImageHandle, (PEFI_DEVICE_PATH_PROTOCOL)ModuleDevicePath,
|
||||||
|
ModuleData, ModuleSize, &ModuleHandle);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to load module image */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Start EFI image */
|
||||||
|
Status = EfiSystemTable->BootServices->StartImage(ModuleHandle, NULL, NULL);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to start module image */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add module to the list of loaded modules */
|
||||||
|
RtlInsertTailList(&BlpLoadedModules, &ModuleInfo->Flink);
|
||||||
|
|
||||||
|
/* Return success */
|
||||||
|
return STATUS_EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This routine is the entry point of the XT EFI boot loader.
|
* This routine is the entry point of the XT EFI boot loader.
|
||||||
*
|
*
|
||||||
@ -187,6 +455,41 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle,
|
|||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BlLoadModules(BlGetConfigValue(L"MODULES"));
|
||||||
|
|
||||||
|
BlLoadModule(L"DUMMY");
|
||||||
|
|
||||||
|
|
||||||
|
BlConsolePrint(L"\n\n\n\n\n\n\n\nList of loaded modules:");
|
||||||
|
PLIST_ENTRY ModuleListEntry;
|
||||||
|
PXTBL_MODULE_INFO ModuleInfo;
|
||||||
|
|
||||||
|
ModuleListEntry = BlpLoadedModules.Flink;
|
||||||
|
while(ModuleListEntry != &BlpLoadedModules)
|
||||||
|
{
|
||||||
|
/* Get module information */
|
||||||
|
ModuleInfo = CONTAIN_RECORD(ModuleListEntry, XTBL_MODULE_INFO, Flink);
|
||||||
|
|
||||||
|
/* Module already loaded */
|
||||||
|
BlConsolePrint(L"\n%.8S", ModuleInfo->ModuleName);
|
||||||
|
if(ModuleInfo->ModuleDescription != 0)
|
||||||
|
{
|
||||||
|
BlConsolePrint(L" (%S)", ModuleInfo->ModuleDescription);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ModuleInfo->Dependencies[0] != 0)
|
||||||
|
{
|
||||||
|
BlConsolePrint(L"\n - Uses: %S", ModuleInfo->Dependencies);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move to the module */
|
||||||
|
ModuleListEntry = ModuleListEntry->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
BlConsolePrint(L"\n\n END OF LIST\n");
|
||||||
|
|
||||||
|
for(;;);
|
||||||
|
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
if(BlpStatus.BootMenu != NULL)
|
if(BlpStatus.BootMenu != NULL)
|
||||||
|
Loading…
Reference in New Issue
Block a user