Added test multiboot2 module for XTLDR and relevant XTLDR configuration
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -4,4 +4,4 @@ build
|
|||||||
build-*
|
build-*
|
||||||
|
|
||||||
# TODO: Don't forget to remove this ;)
|
# TODO: Don't forget to remove this ;)
|
||||||
xtldr/modules/multiboot2
|
bootdata/xtldr/kernel.elf
|
@@ -1 +1,2 @@
|
|||||||
set_install_file(xtldr.ini efi/boot/xtldr)
|
set_install_file(xtldr.ini efi/boot/xtldr)
|
||||||
|
set_install_file(kernel.elf exectos/boot)
|
||||||
|
@@ -37,6 +37,14 @@ SystemPath=multi(0)disk(0)rdisk(0)partition(1)/ExectOS
|
|||||||
KernelFile=xtoskrnl.exe
|
KernelFile=xtoskrnl.exe
|
||||||
Parameters=DEBUG=COM1,115200
|
Parameters=DEBUG=COM1,115200
|
||||||
|
|
||||||
|
[ELFTest]
|
||||||
|
SystemName="ELF Test"
|
||||||
|
SystemType=MULTIBOOT2
|
||||||
|
BootModules=multiboot2
|
||||||
|
SystemPath=multi(0)disk(0)rdisk(0)partition(1)/ExectOS
|
||||||
|
KernelFile=kernel.elf
|
||||||
|
Parameters=
|
||||||
|
|
||||||
[Windows]
|
[Windows]
|
||||||
SystemName="Microsoft Windows 2000"
|
SystemName="Microsoft Windows 2000"
|
||||||
SystemType=NT50
|
SystemType=NT50
|
||||||
|
@@ -275,6 +275,7 @@ ElfLoadImage(IN PEFI_FILE_HANDLE FileHandle,
|
|||||||
XtLdrProtocol->Debug.Print(L"Entry point: 0x%lx (0x%lx)\n", ImageData->EntryPoint, ImageData->Header64->e_entry);
|
XtLdrProtocol->Debug.Print(L"Entry point: 0x%lx (0x%lx)\n", ImageData->EntryPoint, ImageData->Header64->e_entry);
|
||||||
|
|
||||||
/* Load individual segments according to program headers */
|
/* Load individual segments according to program headers */
|
||||||
|
XtLdrProtocol->Debug.Print(L"Program header count: %d\n", ImageData->Header64->e_phnum);
|
||||||
PELF_IMAGE_PROGRAM_HEADER64 ProgramHeaders = (PELF_IMAGE_PROGRAM_HEADER64)(Data + ImageData->Header64->e_phoff);
|
PELF_IMAGE_PROGRAM_HEADER64 ProgramHeaders = (PELF_IMAGE_PROGRAM_HEADER64)(Data + ImageData->Header64->e_phoff);
|
||||||
for (UINT Count = 0; Count < ImageData->Header64->e_phnum; Count++)
|
for (UINT Count = 0; Count < ImageData->Header64->e_phnum; Count++)
|
||||||
{
|
{
|
||||||
@@ -293,7 +294,7 @@ ElfLoadImage(IN PEFI_FILE_HANDLE FileHandle,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Read segment into memory */
|
/* Read segment into memory */
|
||||||
Status = FileHandle->SetPosition(FileHandle, (UINT64)&ProgramHeaders[Count].p_offset);
|
Status = FileHandle->SetPosition(FileHandle, ProgramHeaders[Count].p_offset);
|
||||||
Status = FileHandle->Read(FileHandle, (PUINT_PTR)&ProgramHeaders[Count].p_filesz, (PVOID)(UINT_PTR)ProgramHeaders[Count].p_paddr);
|
Status = FileHandle->Read(FileHandle, (PUINT_PTR)&ProgramHeaders[Count].p_filesz, (PVOID)(UINT_PTR)ProgramHeaders[Count].p_paddr);
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
@@ -310,6 +311,8 @@ ElfLoadImage(IN PEFI_FILE_HANDLE FileHandle,
|
|||||||
UINT_PTR ZeroedMemoryStart = (UINT_PTR)ProgramHeaders[Count].p_paddr + (UINT_PTR)ProgramHeaders[Count].p_filesz;
|
UINT_PTR ZeroedMemoryStart = (UINT_PTR)ProgramHeaders[Count].p_paddr + (UINT_PTR)ProgramHeaders[Count].p_filesz;
|
||||||
RtlZeroMemory((PVOID)ZeroedMemoryStart, ZeroCount);
|
RtlZeroMemory((PVOID)ZeroedMemoryStart, ZeroCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XtLdrProtocol->Debug.Print(L"Read %d pages (%d bytes) to %lx\n", PageCount, ZeroCount, (UINT64)ProgramHeaders[Count].p_offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
26
xtldr/modules/multiboot2/CMakeLists.txt
Normal file
26
xtldr/modules/multiboot2/CMakeLists.txt
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
# XT Boot Loader
|
||||||
|
PROJECT(XTLDR_MULTIBOOT2)
|
||||||
|
|
||||||
|
# Specify include directories
|
||||||
|
include_directories(
|
||||||
|
${EXECTOS_SOURCE_DIR}/sdk/xtdk
|
||||||
|
${XTLDR_MULTIBOOT2_SOURCE_DIR}/includes)
|
||||||
|
|
||||||
|
# Specify list of source code files
|
||||||
|
list(APPEND XTLDR_MULTIBOOT2_SOURCE
|
||||||
|
${XTLDR_MULTIBOOT2_SOURCE_DIR}/multiboot2.c)
|
||||||
|
|
||||||
|
# Link bootloader executable
|
||||||
|
add_executable(multiboot2 ${XTLDR_MULTIBOOT2_SOURCE})
|
||||||
|
|
||||||
|
# Add linker libraries
|
||||||
|
target_link_libraries(multiboot2 libxtos libxtldr)
|
||||||
|
|
||||||
|
# Set proper binary name and install target
|
||||||
|
set_target_properties(multiboot2 PROPERTIES SUFFIX .efi)
|
||||||
|
set_install_target(multiboot2 efi/boot/xtldr/modules)
|
||||||
|
|
||||||
|
# Set module entrypoint and subsystem
|
||||||
|
set_entrypoint(multiboot2 "XtLdrModuleMain")
|
||||||
|
set_linker_map(multiboot2 TRUE)
|
||||||
|
set_subsystem(multiboot2 efi_boot_service_driver)
|
63
xtldr/modules/multiboot2/includes/multiboot2.h
Normal file
63
xtldr/modules/multiboot2/includes/multiboot2.h
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
/**
|
||||||
|
* PROJECT: ExectOS
|
||||||
|
* COPYRIGHT: See COPYING.md in the top level directory
|
||||||
|
* FILE: xtldr/modules/xtos/includes/xtos.h
|
||||||
|
* DESCRIPTION: XTOS boot protocol support header
|
||||||
|
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __XTLDR_MODULES_XTOS_H
|
||||||
|
#define __XTLDR_MODULES_XTOS_H
|
||||||
|
|
||||||
|
#include <xtblapi.h>
|
||||||
|
|
||||||
|
typedef VOID (*PXT_FRAMEBUFFER_GET_DISPLAY_DRIVER)(OUT PWCHAR DriverName);
|
||||||
|
typedef VOID (*PXT_FRAMEBUFFER_GET_DISPLAY_INFORMATION)(OUT PLOADER_GRAPHICS_INFORMATION_BLOCK InformationBlock);
|
||||||
|
typedef EFI_STATUS (*PXT_FRAMEBUFFER_INITIALIZE)();
|
||||||
|
typedef VOID (*PXT_FRAMEBUFFER_PRINT_DISPLAY_INFORMATION)();
|
||||||
|
|
||||||
|
/* XT framebuffer support protocol */
|
||||||
|
typedef struct _XT_FRAMEBUFFER_PROTOCOL
|
||||||
|
{
|
||||||
|
PXT_FRAMEBUFFER_GET_DISPLAY_DRIVER GetDisplayDriver;
|
||||||
|
PXT_FRAMEBUFFER_GET_DISPLAY_INFORMATION GetDisplayInformation;
|
||||||
|
PXT_FRAMEBUFFER_INITIALIZE Initialize;
|
||||||
|
PXT_FRAMEBUFFER_PRINT_DISPLAY_INFORMATION PrintDisplayInformation;
|
||||||
|
} XT_FRAMEBUFFER_PROTOCOL, *PXT_FRAMEBUFFER_PROTOCOL;
|
||||||
|
|
||||||
|
/* EFI XT Loader Protocol */
|
||||||
|
EXTERN PXTBL_LOADER_PROTOCOL XtLdrProtocol;
|
||||||
|
|
||||||
|
/* XTOS kernel entry point */
|
||||||
|
typedef VOID (XTAPI *PXT_ENTRY_POINT)(IN PKERNEL_INITIALIZATION_BLOCK BootParameters);
|
||||||
|
|
||||||
|
/* XTOS boot protocol related routines forward references */
|
||||||
|
XTCDECL
|
||||||
|
EFI_STATUS
|
||||||
|
Multiboot2BootSystem(IN PXTBL_BOOT_PARAMETERS Parameters);
|
||||||
|
|
||||||
|
XTCDECL
|
||||||
|
EFI_STATUS
|
||||||
|
XtpBootSequence(IN PEFI_FILE_HANDLE BootDir,
|
||||||
|
IN PXTBL_BOOT_PARAMETERS Parameters);
|
||||||
|
|
||||||
|
XTCDECL
|
||||||
|
EFI_STATUS
|
||||||
|
XtpInitializeLoaderBlock(IN PLIST_ENTRY MemoryMappings,
|
||||||
|
IN PVOID *VirtualAddress,
|
||||||
|
IN PXTBL_BOOT_PARAMETERS Parameters);
|
||||||
|
|
||||||
|
XTCDECL
|
||||||
|
EFI_STATUS
|
||||||
|
XtpLoadModule(IN PEFI_FILE_HANDLE BootDir,
|
||||||
|
IN PWCHAR FileName,
|
||||||
|
IN PVOID VirtualAddress,
|
||||||
|
IN LOADER_MEMORY_TYPE MemoryType,
|
||||||
|
OUT PELF_IMAGE_CONTEXT *ImageContext);
|
||||||
|
|
||||||
|
XTCDECL
|
||||||
|
EFI_STATUS
|
||||||
|
BlXtLdrModuleMain(IN EFI_HANDLE ImageHandle,
|
||||||
|
IN PEFI_SYSTEM_TABLE SystemTable);
|
||||||
|
|
||||||
|
#endif /* __XTLDR_MODULES_XTOS_H */
|
331
xtldr/modules/multiboot2/multiboot2.c
Normal file
331
xtldr/modules/multiboot2/multiboot2.c
Normal file
@@ -0,0 +1,331 @@
|
|||||||
|
/**
|
||||||
|
* PROJECT: ExectOS
|
||||||
|
* COPYRIGHT: See COPYING.md in the top level directory
|
||||||
|
* FILE: xtldr/modules/multiboot2/multiboot2.c
|
||||||
|
* DESCRIPTION: Multiboot2 boot protocol support
|
||||||
|
* DEVELOPERS: Jozef Nagy <schkwve@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <multiboot2.h>
|
||||||
|
|
||||||
|
/* XTOS module information */
|
||||||
|
XTBL_MODINFO = L"Multiboot2 boot protocol support";
|
||||||
|
XTBL_MODDEPS = {L"elf"};
|
||||||
|
|
||||||
|
/* EFI XT Loader Protocol */
|
||||||
|
PXTBL_LOADER_PROTOCOL XtLdrProtocol;
|
||||||
|
|
||||||
|
/* XTOS ELF Image Protocol */
|
||||||
|
PXTBL_EXECUTABLE_IMAGE_PROTOCOL XtElfProtocol;
|
||||||
|
|
||||||
|
/* XTOS Boot Protocol */
|
||||||
|
XTBL_BOOT_PROTOCOL Multiboot2BootProtocol;
|
||||||
|
|
||||||
|
/* XTOS Page Map */
|
||||||
|
PVOID XtPageMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the operating system according to the provided parameters using XTOS boot protocol.
|
||||||
|
*
|
||||||
|
* @param Parameters
|
||||||
|
* Input parameters with detailed system configuration like boot device or kernel path.
|
||||||
|
*
|
||||||
|
* @return This routine returns a status code.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTCDECL
|
||||||
|
EFI_STATUS
|
||||||
|
Multiboot2BootSystem(IN PXTBL_BOOT_PARAMETERS Parameters)
|
||||||
|
{
|
||||||
|
EFI_GUID ElfProtocolGuid = XT_ELF_IMAGE_PROTOCOL_GUID;
|
||||||
|
EFI_HANDLE DiskHandle, ProtocolHandle;
|
||||||
|
PEFI_FILE_HANDLE FsHandle, BootDir;
|
||||||
|
PWCHAR SystemPath;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
/* Print debug message */
|
||||||
|
XtLdrProtocol->Debug.Print(L"Multiboot2 boot protocol activated\n");
|
||||||
|
|
||||||
|
/* Open the XT ELF protocol */
|
||||||
|
Status = XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID *)&XtElfProtocol, &ElfProtocolGuid);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to open loader protocol */
|
||||||
|
XtLdrProtocol->Debug.Print(L"ERROR: Unable to load ELF image protocol\n");
|
||||||
|
return STATUS_EFI_PROTOCOL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check device path */
|
||||||
|
if(Parameters->DevicePath == NULL)
|
||||||
|
{
|
||||||
|
/* No device path set */
|
||||||
|
XtLdrProtocol->Debug.Print(L"ERROR: No device path provided, unable to boot system\n");
|
||||||
|
return STATUS_EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if system path is set */
|
||||||
|
if(Parameters->SystemPath != NULL)
|
||||||
|
{
|
||||||
|
/* Make sure system path begins with backslash, the only separator supported by EFI */
|
||||||
|
if(Parameters->SystemPath[0] == '/')
|
||||||
|
{
|
||||||
|
/* Replace directory separator if needed */
|
||||||
|
Parameters->SystemPath[0] = '\\';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate system path */
|
||||||
|
SystemPath = &Parameters->SystemPath[1];
|
||||||
|
while(*SystemPath)
|
||||||
|
{
|
||||||
|
/* Make sure it does not point to any subdirectory and not contains special characters */
|
||||||
|
if(((*SystemPath | 32) - 'a' >= 26) && ((*SystemPath - '0') >= 10))
|
||||||
|
{
|
||||||
|
/* Invalid path specified */
|
||||||
|
XtLdrProtocol->Debug.Print(L"ERROR: System path does not point to the valid XTOS installation\n");
|
||||||
|
return STATUS_EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
/* Check next character in the path */
|
||||||
|
SystemPath++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Fallback to '/ExectOS' by default */
|
||||||
|
XtLdrProtocol->Debug.Print(L"WARNING: No system path set, falling back to defaults\n");
|
||||||
|
Parameters->SystemPath = L"\\ExectOS";
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if kernel file is set */
|
||||||
|
if(Parameters->KernelFile == NULL)
|
||||||
|
{
|
||||||
|
/* No kernel filename set, fallback to default */
|
||||||
|
XtLdrProtocol->Debug.Print(L"WARNING: No kernel file specified, falling back to defaults\n");
|
||||||
|
Parameters->KernelFile = L"kernel.elf";
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if provided any kernel boot arguments */
|
||||||
|
if(Parameters->Parameters == NULL)
|
||||||
|
{
|
||||||
|
/* No argument supplied */
|
||||||
|
Parameters->Parameters = L"";
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print a debug message */
|
||||||
|
XtLdrProtocol->Debug.Print(L"[XTOS] ARC Path: %S\n"
|
||||||
|
L"[XTOS] System Path: %S\n"
|
||||||
|
L"[XTOS] Kernel File: %S\n"
|
||||||
|
L"[XTOS] Boot Arguments: %S\n",
|
||||||
|
Parameters->ArcName, Parameters->SystemPath,
|
||||||
|
Parameters->KernelFile, Parameters->Parameters);
|
||||||
|
|
||||||
|
/* Open EFI volume */
|
||||||
|
Status = XtLdrProtocol->Disk.OpenVolume(NULL, &DiskHandle, &FsHandle);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to open a volume */
|
||||||
|
XtLdrProtocol->Debug.Print(L"ERROR: Unable to open boot volume\n");
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* System path has to point to the boot directory */
|
||||||
|
RtlConcatenateWideString(Parameters->SystemPath, L"\\Boot", 0);
|
||||||
|
|
||||||
|
/* Open XTOS system boot directory */
|
||||||
|
Status = FsHandle->Open(FsHandle, &BootDir, Parameters->SystemPath, EFI_FILE_MODE_READ, 0);
|
||||||
|
FsHandle->Close(FsHandle);
|
||||||
|
|
||||||
|
/* Check if system path directory opened successfully */
|
||||||
|
if(Status == STATUS_EFI_NOT_FOUND)
|
||||||
|
{
|
||||||
|
/* Directory not found, nothing to load */
|
||||||
|
XtLdrProtocol->Debug.Print(L"ERROR: System boot directory not found\n");
|
||||||
|
|
||||||
|
/* Close volume */
|
||||||
|
XtLdrProtocol->Disk.CloseVolume(DiskHandle);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
else if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to open directory */
|
||||||
|
XtLdrProtocol->Debug.Print(L"ERROR: Unable to open system boot directory\n");
|
||||||
|
XtLdrProtocol->Disk.CloseVolume(DiskHandle);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Start boot sequence */
|
||||||
|
return XtpBootSequence(BootDir, Parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This routine initiates an XTOS boot sequence.
|
||||||
|
*
|
||||||
|
* @param BootDir
|
||||||
|
* An EFI handle to the XTOS boot directory.
|
||||||
|
*
|
||||||
|
* @param Parameters
|
||||||
|
* Input parameters with detailed system configuration like boot device or kernel path.
|
||||||
|
*
|
||||||
|
* @return This routine returns a status code.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTCDECL
|
||||||
|
EFI_STATUS
|
||||||
|
XtpBootSequence(IN PEFI_FILE_HANDLE BootDir,
|
||||||
|
IN PXTBL_BOOT_PARAMETERS Parameters)
|
||||||
|
{
|
||||||
|
EFI_GUID LoadedImageGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
|
||||||
|
PKERNEL_INITIALIZATION_BLOCK KernelParameters;
|
||||||
|
PELF_IMAGE_CONTEXT ImageContext = NULL;
|
||||||
|
PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol;
|
||||||
|
PVOID VirtualAddress, VirtualMemoryArea;
|
||||||
|
PXT_ENTRY_POINT KernelEntryPoint;
|
||||||
|
LIST_ENTRY MemoryMappings;
|
||||||
|
EFI_HANDLE ProtocolHandle;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
/* Initialize XTOS startup sequence */
|
||||||
|
XtLdrProtocol->Debug.Print(L"Initializing XTOS startup sequence\n");
|
||||||
|
|
||||||
|
/* Set base virtual memory area for the kernel mappings */
|
||||||
|
VirtualMemoryArea = (PVOID)KSEG0_BASE;
|
||||||
|
VirtualAddress = (PVOID)(KSEG0_BASE + KSEG0_KERNEL_BASE);
|
||||||
|
|
||||||
|
/* Load the kernel */
|
||||||
|
Status = XtpLoadModule(BootDir, Parameters->KernelFile, VirtualAddress, LoaderSystemCode, &ImageContext);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to load the kernel */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get kernel entry point */
|
||||||
|
XtElfProtocol->GetEntryPoint(ImageContext, (PVOID)&KernelEntryPoint);
|
||||||
|
|
||||||
|
/* Close boot directory handle */
|
||||||
|
BootDir->Close(BootDir);
|
||||||
|
|
||||||
|
/* Call XTOS kernel */
|
||||||
|
XtLdrProtocol->Debug.Print(L"Booting the ELF Multiboot2 kernel\n");
|
||||||
|
KernelEntryPoint(KernelParameters);
|
||||||
|
|
||||||
|
/* Return success */
|
||||||
|
return STATUS_EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads XTOS ELF module.
|
||||||
|
*
|
||||||
|
* @param SystemDir
|
||||||
|
* An EFI handle to the opened system directory containing a module that will be loaded.
|
||||||
|
*
|
||||||
|
* @param FileName
|
||||||
|
* An on disk filename of the module that will be loaded.
|
||||||
|
*
|
||||||
|
* @param VirtualAddress
|
||||||
|
* Optional virtual address pointing to the memory area where ELF file will be loaded.
|
||||||
|
*
|
||||||
|
* @param MemoryType
|
||||||
|
* Supplies the type of memory to be assigned to the memory descriptor.
|
||||||
|
*
|
||||||
|
* @param ImageContext
|
||||||
|
* Supplies pointer to the memory area where loaded ELF image context will be stored.
|
||||||
|
*
|
||||||
|
* @return This routine returns a status code.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTCDECL
|
||||||
|
EFI_STATUS
|
||||||
|
XtpLoadModule(IN PEFI_FILE_HANDLE SystemDir,
|
||||||
|
IN PWCHAR FileName,
|
||||||
|
IN PVOID VirtualAddress,
|
||||||
|
IN LOADER_MEMORY_TYPE MemoryType,
|
||||||
|
OUT PELF_IMAGE_CONTEXT *ImageContext)
|
||||||
|
{
|
||||||
|
PEFI_FILE_HANDLE ModuleHandle;
|
||||||
|
USHORT MachineType, SubSystem;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
/* Print debug message */
|
||||||
|
XtLdrProtocol->Debug.Print(L"Loading %S... \n", FileName);
|
||||||
|
|
||||||
|
/* Open module file */
|
||||||
|
Status = SystemDir->Open(SystemDir, &ModuleHandle, FileName, EFI_FILE_MODE_READ, 0);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Unable to open the file */
|
||||||
|
XtLdrProtocol->Debug.Print(L"ERROR: Failed to open '%S'\n", FileName);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load the ELF image file */
|
||||||
|
Status = XtElfProtocol->LoadImage(ModuleHandle, MemoryType, VirtualAddress, (PVOID)ImageContext);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Unable to load the file */
|
||||||
|
XtLdrProtocol->Debug.Print(L"ERROR: Failed to load '%S'\n", FileName);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close image file */
|
||||||
|
ModuleHandle->Close(ModuleHandle);
|
||||||
|
|
||||||
|
/* Check ELF image machine type compatibility */
|
||||||
|
XtElfProtocol->GetMachineType(*ImageContext, &MachineType);
|
||||||
|
if(MachineType != 0x03 &&
|
||||||
|
MachineType != 0x32 &&
|
||||||
|
MachineType != 0x3E)
|
||||||
|
{
|
||||||
|
/* Machine type mismatch */
|
||||||
|
XtLdrProtocol->Debug.Print(L"ERROR: Loaded incompatible ELF image (machine type mismatch)\n");
|
||||||
|
return STATUS_EFI_INCOMPATIBLE_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print debug message */
|
||||||
|
XtLdrProtocol->Debug.Print(L"Loaded %S at PA: 0x%lx, VA: 0x%lx\n", FileName,
|
||||||
|
(*ImageContext)->PhysicalAddress, (*ImageContext)->VirtualAddress);
|
||||||
|
|
||||||
|
/* Return success */
|
||||||
|
return STATUS_EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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_XTOS_BOOT_PROTOCOL_GUID;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
/* Open the XTLDR protocol */
|
||||||
|
Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to open loader protocol */
|
||||||
|
return STATUS_EFI_PROTOCOL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set routines available via Multiboot2 boot protocol */
|
||||||
|
Multiboot2BootProtocol.BootSystem = Multiboot2BootSystem;
|
||||||
|
|
||||||
|
/* Register XTOS boot protocol */
|
||||||
|
XtLdrProtocol->Boot.RegisterProtocol(L"MULTIBOOT2", &Guid);
|
||||||
|
|
||||||
|
/* Install XTOS protocol */
|
||||||
|
return XtLdrProtocol->Protocol.Install(&Multiboot2BootProtocol, &Guid);
|
||||||
|
}
|
Reference in New Issue
Block a user