Implement chain loader module
This commit is contained in:
parent
269858f5a1
commit
9421eee002
@ -1,4 +1,5 @@
|
|||||||
add_subdirectory(beep)
|
add_subdirectory(beep)
|
||||||
|
add_subdirectory(chainldr)
|
||||||
add_subdirectory(dummy)
|
add_subdirectory(dummy)
|
||||||
add_subdirectory(fb_o)
|
add_subdirectory(fb_o)
|
||||||
add_subdirectory(pecoff_o)
|
add_subdirectory(pecoff_o)
|
||||||
|
27
xtldr/modules/chainldr/CMakeLists.txt
Normal file
27
xtldr/modules/chainldr/CMakeLists.txt
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# XTLDR Chain Loader Module
|
||||||
|
PROJECT(XTLDR_CHAINLDR)
|
||||||
|
|
||||||
|
# Specify include directories
|
||||||
|
include_directories(
|
||||||
|
${EXECTOS_SOURCE_DIR}/sdk/xtdk
|
||||||
|
${XTLDR_CHAINLDR_SOURCE_DIR}/includes)
|
||||||
|
|
||||||
|
# Specify list of source code files
|
||||||
|
list(APPEND XTLDR_CHAINLDR_SOURCE
|
||||||
|
${XTLDR_CHAINLDR_SOURCE_DIR}/chainldr.c
|
||||||
|
${XTLDR_CHAINLDR_SOURCE_DIR}/globals.c)
|
||||||
|
|
||||||
|
# Link module executable
|
||||||
|
add_executable(chainldr ${XTLDR_CHAINLDR_SOURCE})
|
||||||
|
|
||||||
|
# Add linker libraries
|
||||||
|
target_link_libraries(chainldr libxtldr libxtos)
|
||||||
|
|
||||||
|
# Set proper binary name and install target
|
||||||
|
set_target_properties(chainldr PROPERTIES SUFFIX .efi)
|
||||||
|
set_install_target(chainldr efi/boot/xtldr/modules)
|
||||||
|
|
||||||
|
# Set module entrypoint and subsystem
|
||||||
|
set_entrypoint(chainldr "XtLdrModuleMain")
|
||||||
|
set_linker_map(chainldr TRUE)
|
||||||
|
set_subsystem(chainldr efi_boot_service_driver)
|
160
xtldr/modules/chainldr/chainldr.c
Normal file
160
xtldr/modules/chainldr/chainldr.c
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
/**
|
||||||
|
* PROJECT: ExectOS
|
||||||
|
* COPYRIGHT: See COPYING.md in the top level directory
|
||||||
|
* FILE: xtldr/modules/chainldr/chainldr.c
|
||||||
|
* DESCRIPTION: XTLDR Chain Loader
|
||||||
|
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <chainldr.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* ChainLoader module information */
|
||||||
|
XTBL_MODINFO = L"XTLDR Chain Loader";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chainloads another boot loader.
|
||||||
|
*
|
||||||
|
* @param Parameters
|
||||||
|
* Input parameters with detailed system configuration.
|
||||||
|
*
|
||||||
|
* @return This routine returns a status code.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTCDECL
|
||||||
|
EFI_STATUS
|
||||||
|
ChBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters)
|
||||||
|
{
|
||||||
|
EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
|
||||||
|
EFI_MEMMAP_DEVICE_PATH MemoryDevicePath[2];
|
||||||
|
PEFI_LOADED_IMAGE_PROTOCOL LoadedImage;
|
||||||
|
EFI_HANDLE DiskHandle, LoaderHandle;
|
||||||
|
PEFI_FILE_HANDLE FsHandle, BootDir;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
SIZE_T LoaderSize;
|
||||||
|
PVOID LoaderData;
|
||||||
|
|
||||||
|
/* Check if image file is provided */
|
||||||
|
if(Parameters->KernelFile == NULL)
|
||||||
|
{
|
||||||
|
/* No image filename provided, return error code */
|
||||||
|
XtLdrProtocol->Debug.Print(L"ERROR: No EFI image filename provided\n");
|
||||||
|
return STATUS_EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open EFI volume */
|
||||||
|
Status = XtLdrProtocol->Disk.OpenVolume(NULL, &DiskHandle, &FsHandle);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to open a volume, return error code */
|
||||||
|
XtLdrProtocol->Debug.Print(L"ERROR: Unable to open boot volume (Status Code: 0x%lx)\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open boot directory and close FS handle */
|
||||||
|
Status = FsHandle->Open(FsHandle, &BootDir, Parameters->EfiPath, EFI_FILE_MODE_READ, 0);
|
||||||
|
FsHandle->Close(FsHandle);
|
||||||
|
|
||||||
|
/* Check if system path directory opened successfully */
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to open directory */
|
||||||
|
XtLdrProtocol->Debug.Print(L"ERROR: Unable to open system boot directory (Status Code: 0x%lx)\n", Status);
|
||||||
|
|
||||||
|
/* Close volume and return error code */
|
||||||
|
XtLdrProtocol->Disk.CloseVolume(DiskHandle);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read EFI image file from disk and close both directory and EFI volume */
|
||||||
|
Status = XtLdrProtocol->Disk.ReadFile(BootDir, Parameters->KernelFile, &LoaderData, &LoaderSize);
|
||||||
|
BootDir->Close(BootDir);
|
||||||
|
XtLdrProtocol->Disk.CloseVolume(DiskHandle);
|
||||||
|
|
||||||
|
/* Setup device path for EFI image */
|
||||||
|
MemoryDevicePath[0].Header.Length[0] = sizeof(EFI_MEMMAP_DEVICE_PATH);
|
||||||
|
MemoryDevicePath[0].Header.Length[1] = sizeof(EFI_MEMMAP_DEVICE_PATH) >> 8;
|
||||||
|
MemoryDevicePath[0].Header.Type = EFI_HARDWARE_DEVICE_PATH;
|
||||||
|
MemoryDevicePath[0].Header.SubType = EFI_HARDWARE_MEMMAP_DP;
|
||||||
|
MemoryDevicePath[0].MemoryType = EfiLoaderData;
|
||||||
|
MemoryDevicePath[0].StartingAddress = (UINT_PTR)LoaderData;
|
||||||
|
MemoryDevicePath[0].EndingAddress = (UINT_PTR)LoaderData + LoaderSize;
|
||||||
|
MemoryDevicePath[1].Header.Length[0] = sizeof(EFI_DEVICE_PATH_PROTOCOL);
|
||||||
|
MemoryDevicePath[1].Header.Length[1] = sizeof(EFI_DEVICE_PATH_PROTOCOL) >> 8;
|
||||||
|
MemoryDevicePath[1].Header.Type = EFI_END_DEVICE_PATH;
|
||||||
|
MemoryDevicePath[1].Header.SubType = EFI_END_ENTIRE_DP;
|
||||||
|
|
||||||
|
/* Load EFI image */
|
||||||
|
Status = XtLdrProtocol->Util.LoadEfiImage((PEFI_DEVICE_PATH_PROTOCOL)MemoryDevicePath,
|
||||||
|
LoaderData, LoaderSize, &LoaderHandle);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to chainload EFI binary, return error code */
|
||||||
|
XtLdrProtocol->Debug.Print(L"ERROR: Unable to chainload '%S' (Status Code: 0x%lx)\n",
|
||||||
|
Parameters->KernelFile, Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Access loaded image protocol */
|
||||||
|
Status = XtLdrProtocol->Protocol.OpenHandle(LoaderHandle, (PVOID *)&LoadedImage, &LIPGuid);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to open EFI_LOADED_IMAGE_PROTOCOL, return error code */
|
||||||
|
XtLdrProtocol->Debug.Print(L"ERROR: Unable to access binary interface (Status Code: 0x%lx)\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if parameters provided */
|
||||||
|
if(Parameters->Parameters)
|
||||||
|
{
|
||||||
|
/* Pass arguments to chainloaded image */
|
||||||
|
LoadedImage->LoadOptionsSize = RtlWideStringLength(Parameters->Parameters, 0) * sizeof(WCHAR);
|
||||||
|
LoadedImage->LoadOptions = Parameters->Parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set device handle as LoadImage() is not going to do it */
|
||||||
|
LoadedImage->DeviceHandle = DiskHandle;
|
||||||
|
|
||||||
|
/* Chainload EFI image */
|
||||||
|
return XtLdrProtocol->Util.StartEfiImage(LoaderHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
EFI_GUID Guid = XT_CHAIN_BOOT_PROTOCOL_GUID;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
/* Open the XTLDR protocol */
|
||||||
|
Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to open the protocol, return error */
|
||||||
|
return STATUS_EFI_PROTOCOL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set routines available via ChainLoader boot protocol */
|
||||||
|
ChBootProtocol.BootSystem = ChBootSystem;
|
||||||
|
|
||||||
|
/* Register XTOS boot protocol */
|
||||||
|
XtLdrProtocol->Boot.RegisterProtocol(L"CHAINLOADER", &Guid);
|
||||||
|
|
||||||
|
/* Install XTOS protocol */
|
||||||
|
return XtLdrProtocol->Protocol.Install(&ChBootProtocol, &Guid);
|
||||||
|
}
|
16
xtldr/modules/chainldr/globals.c
Normal file
16
xtldr/modules/chainldr/globals.c
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/**
|
||||||
|
* PROJECT: ExectOS
|
||||||
|
* COPYRIGHT: See COPYING.md in the top level directory
|
||||||
|
* FILE: xtldr/modules/chainldr/globals.c
|
||||||
|
* DESCRIPTION: XTLDR Chain Loader global variables
|
||||||
|
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <xtblapi.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* ChainLoader Boot Protocol */
|
||||||
|
XTBL_BOOT_PROTOCOL ChBootProtocol;
|
||||||
|
|
||||||
|
/* XTLDR protocol handler */
|
||||||
|
PXTBL_LOADER_PROTOCOL XtLdrProtocol;
|
26
xtldr/modules/chainldr/includes/chainldr.h
Normal file
26
xtldr/modules/chainldr/includes/chainldr.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/**
|
||||||
|
* PROJECT: ExectOS
|
||||||
|
* COPYRIGHT: See COPYING.md in the top level directory
|
||||||
|
* FILE: xtldr/modules/chainldr/includes/chainldr.h
|
||||||
|
* DESCRIPTION: XTLDR Chain Loader header file
|
||||||
|
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __XTLDR_CHAINLDR_CHAINLDR_H
|
||||||
|
#define __XTLDR_CHAINLDR_CHAINLDR_H
|
||||||
|
|
||||||
|
#include <xtblapi.h>
|
||||||
|
#include <globals.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* ChainLoader module routines forward references */
|
||||||
|
XTCDECL
|
||||||
|
EFI_STATUS
|
||||||
|
ChBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters);
|
||||||
|
|
||||||
|
XTCDECL
|
||||||
|
EFI_STATUS
|
||||||
|
XtLdrModuleMain(IN EFI_HANDLE ImageHandle,
|
||||||
|
IN PEFI_SYSTEM_TABLE SystemTable);
|
||||||
|
|
||||||
|
#endif/* __XTLDR_CHAINLDR_CHAINLDR_H */
|
21
xtldr/modules/chainldr/includes/globals.h
Normal file
21
xtldr/modules/chainldr/includes/globals.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/**
|
||||||
|
* PROJECT: ExectOS
|
||||||
|
* COPYRIGHT: See COPYING.md in the top level directory
|
||||||
|
* FILE: xtldr/modules/chainldr/includes/globals.h
|
||||||
|
* DESCRIPTION: XTLDR Chain Loader global variables
|
||||||
|
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __XTLDR_CHAINLDR_GLOBALS_H
|
||||||
|
#define __XTLDR_CHAINLDR_GLOBALS_H
|
||||||
|
|
||||||
|
#include <chainldr.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* ChainLoader Boot Protocol */
|
||||||
|
EXTERN XTBL_BOOT_PROTOCOL ChBootProtocol;
|
||||||
|
|
||||||
|
/* XTLDR protocol handler */
|
||||||
|
EXTERN PXTBL_LOADER_PROTOCOL XtLdrProtocol;
|
||||||
|
|
||||||
|
#endif/* __XTLDR_CHAINLDR_GLOBALS_H */
|
Loading…
Reference in New Issue
Block a user