Move XTLDR under boot directory
This commit is contained in:
328
boot/xtldr/xtldr.cc
Normal file
328
boot/xtldr/xtldr.cc
Normal file
@@ -0,0 +1,328 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/xtldr.cc
|
||||
* DESCRIPTION: XTOS UEFI Boot Loader
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtldr.hh>
|
||||
|
||||
|
||||
/**
|
||||
* Disables access to EFI Boot Services.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
XtLoader::DisableBootServices()
|
||||
{
|
||||
LoaderStatus.BootServices = FALSE;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries the availability of EFI Boot Services.
|
||||
*
|
||||
* @return This routine returns TRUE if EFI Boot Services are available, FALSE otherwise.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
BOOLEAN
|
||||
XtLoader::GetBootServicesStatus()
|
||||
{
|
||||
return LoaderStatus.BootServices;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the EFI image handle.
|
||||
*
|
||||
* @return This routine returns a handle to the EFI-loaded image.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_HANDLE
|
||||
XtLoader::GetEfiImageHandle()
|
||||
{
|
||||
return XtLoader::EfiImageHandle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the EFI system table pointer.
|
||||
*
|
||||
* @return This routine returns a pointer to the EFI system table.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
PEFI_SYSTEM_TABLE
|
||||
XtLoader::GetEfiSystemTable()
|
||||
{
|
||||
return XtLoader::EfiSystemTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides base address and size of the XTLDR image.
|
||||
*
|
||||
* @param LoaderBase
|
||||
* Supplies a pointer to a variable that receives the base address of the XTLDR image.
|
||||
*
|
||||
* @param LoaderSize
|
||||
* Supplies a pointer to a variable that receives the size of the XTLDR image.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
XtLoader::GetLoaderImageInformation(PVOID *LoaderBase,
|
||||
PULONGLONG LoaderSize)
|
||||
{
|
||||
*LoaderBase = XtLoader::LoaderStatus.LoaderBase;
|
||||
*LoaderSize = XtLoader::LoaderStatus.LoaderSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the Secure Boot status.
|
||||
*
|
||||
* @return This routine returns SecureBoot status.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
INT_PTR
|
||||
XtLoader::GetSecureBootStatus()
|
||||
{
|
||||
return LoaderStatus.SecureBoot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes EFI Boot Loader (XTLDR).
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
XtLoader::InitializeBootLoader(IN EFI_HANDLE ImageHandle,
|
||||
IN PEFI_SYSTEM_TABLE SystemTable)
|
||||
{
|
||||
EFI_GUID LipGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
|
||||
PEFI_LOADED_IMAGE_PROTOCOL LoadedImage;
|
||||
EFI_HANDLE Handle;
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Set the system table and image handle */
|
||||
EfiImageHandle = ImageHandle;
|
||||
EfiSystemTable = SystemTable;
|
||||
|
||||
/* Set current XTLDR's EFI BootServices status */
|
||||
LoaderStatus.BootServices = TRUE;
|
||||
|
||||
/* Initialize console */
|
||||
Console::InitializeConsole();
|
||||
|
||||
/* Print XTLDR version */
|
||||
Console::Print(L"XTLDR boot loader v%s\n", XTOS_VERSION);
|
||||
|
||||
/* Initialize XTLDR protocol */
|
||||
Protocol::InitializeProtocol();
|
||||
|
||||
/* Initialize XTLDR configuration */
|
||||
Configuration::InitializeConfiguration();
|
||||
|
||||
/* Store SecureBoot status */
|
||||
LoaderStatus.SecureBoot = EfiUtils::GetSecureBootStatus();
|
||||
|
||||
/* Attempt to open EFI LoadedImage protocol */
|
||||
Status = Protocol::OpenProtocol(&Handle, (PVOID *)&LoadedImage, &LipGuid);
|
||||
if(Status == STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Store boot loader image base and size */
|
||||
LoaderStatus.LoaderBase = LoadedImage->ImageBase;
|
||||
LoaderStatus.LoaderSize = LoadedImage->ImageSize;
|
||||
|
||||
/* Check if debug is enabled */
|
||||
if(DEBUG)
|
||||
{
|
||||
/* Protocol opened successfully, print useful debug information */
|
||||
Console::Print(L"\n---------- BOOTLOADER DEBUG ----------\n"
|
||||
L"Pointer Size : %d\n"
|
||||
L"Image Base Address : %P\n"
|
||||
L"Image Base Size : 0x%lX\n"
|
||||
L"Image Revision : 0x%lX\n"
|
||||
L"Secure Boot Status : %zd\n"
|
||||
L"--------------------------------------\n",
|
||||
sizeof(PVOID),
|
||||
LoadedImage->ImageBase,
|
||||
LoadedImage->ImageSize,
|
||||
LoadedImage->Revision,
|
||||
LoaderStatus.SecureBoot);
|
||||
EfiUtils::SleepExecution(3000);
|
||||
}
|
||||
|
||||
/* Close EFI LoadedImage protocol */
|
||||
Protocol::CloseProtocol(&Handle, &LipGuid);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a boot menu callback routine, that will be used to display alternative boot menu.
|
||||
*
|
||||
* @param BootMenuRoutine
|
||||
* Supplies a pointer to the boot menu callback routine.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
XtLoader::RegisterBootMenu(IN PVOID BootMenuRoutine)
|
||||
{
|
||||
/* Set boot menu routine */
|
||||
BootMenu = (PBL_XT_BOOT_MENU)BootMenuRoutine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes either a custom boot menu handler, if one has been registered, or displays the default boot menu.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
XtLoader::ShowBootMenu()
|
||||
{
|
||||
/* Check if custom boot menu registered */
|
||||
if(BootMenu != NULLPTR)
|
||||
{
|
||||
/* Display alternative boot menu */
|
||||
BootMenu();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Display default boot menu */
|
||||
TextUi::DisplayBootMenu();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine is the entry point of the XT EFI boot loader.
|
||||
*
|
||||
* @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
|
||||
BlStartXtLoader(IN EFI_HANDLE ImageHandle,
|
||||
IN PEFI_SYSTEM_TABLE SystemTable)
|
||||
{
|
||||
PWCHAR Modules;
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Initialize XTLDR and */
|
||||
XtLoader::InitializeBootLoader(ImageHandle, SystemTable);
|
||||
|
||||
/* Parse configuration options passed from UEFI shell */
|
||||
Status = Configuration::ParseCommandLine();
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to parse command line options */
|
||||
TextUi::DisplayErrorDialog(L"XTLDR", L"Failed to parse command line parameters.");
|
||||
}
|
||||
|
||||
/* Attempt to early initialize debug console */
|
||||
if(DEBUG)
|
||||
{
|
||||
Status = Debug::InitializeDebugConsole();
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Initialization failed, notify user on stdout */
|
||||
TextUi::DisplayErrorDialog(L"XTLDR", L"Failed to initialize debug console.");
|
||||
}
|
||||
}
|
||||
|
||||
/* Load XTLDR configuration file */
|
||||
Status = Configuration::LoadConfiguration();
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to load/parse config file */
|
||||
TextUi::DisplayErrorDialog(L"XTLDR", L"Failed to load and parse configuration file ");
|
||||
}
|
||||
|
||||
/* Reinitialize debug console if it was not initialized earlier */
|
||||
if(DEBUG)
|
||||
{
|
||||
Status = Debug::InitializeDebugConsole();
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Initialization failed, notify user on stdout */
|
||||
TextUi::DisplayErrorDialog(L"XTLDR", L"Failed to initialize debug console.");
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable watchdog timer */
|
||||
Status = XtLoader::GetEfiSystemTable()->BootServices->SetWatchdogTimer(0, 0x10000, 0, NULLPTR);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to disable the timer, print message */
|
||||
Debug::Print(L"WARNING: Failed to disable watchdog timer (Status Code: 0x%zX)\n", Status);
|
||||
}
|
||||
|
||||
/* Install loader protocol */
|
||||
Status = Protocol::InstallXtLoaderProtocol();
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to register loader protocol */
|
||||
Debug::Print(L"ERROR: Failed to register XTLDR loader protocol (Status Code: 0x%zX)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Load all necessary modules */
|
||||
Configuration::GetValue(L"MODULES", &Modules);
|
||||
Status = Protocol::LoadModules(Modules);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to load modules */
|
||||
Debug::Print(L"ERROR: Failed to load XTLDR modules (Status Code: 0x%zX)\n", Status);
|
||||
TextUi::DisplayErrorDialog(L"XTLDR", L"Failed to load some XTLDR modules.");
|
||||
}
|
||||
|
||||
/* Discover and enumerate EFI block devices */
|
||||
Status = Volume::EnumerateBlockDevices();
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to enumerate block devices */
|
||||
Debug::Print(L"ERROR: Failed to discover and enumerate block devices (Status Code: 0x%zX)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Main boot loader loop */
|
||||
while(TRUE)
|
||||
{
|
||||
/* Show boot menu */
|
||||
XtLoader::ShowBootMenu();
|
||||
|
||||
/* Fallback to shell, if boot menu returned */
|
||||
Shell::StartLoaderShell();
|
||||
}
|
||||
|
||||
/* This point should be never reached, if this happen return error code */
|
||||
return STATUS_EFI_LOAD_ERROR;
|
||||
}
|
Reference in New Issue
Block a user