diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index 687684e..23192bd 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -50,6 +50,7 @@ typedef EFI_STATUS (*PBL_ALLOCATE_PAGES)(IN UINT64 Size, OUT PEFI_PHYSICAL_ADDRESS Memory); typedef EFI_STATUS (*PBL_ALLOCATE_POOL)(IN UINT_PTR Size, OUT PVOID *Memory); typedef VOID (*PBL_BOOTMENU_INITIALIZE_OS_LIST)(OUT PXTBL_BOOTMENU_ITEM MenuEntries, OUT PULONG EntriesCount, OUT PULONG DefaultId); +typedef EFI_STATUS (*PBL_BOOTPROTO_BOOT_SYSTEM)(IN PXTBL_BOOT_PARAMETERS Parameters); typedef EFI_STATUS (*PBL_CLOSE_VOLUME)(IN PEFI_HANDLE VolumeHandle); typedef VOID (*PBL_CLEAR_CONSOLE_LINE)(IN ULONGLONG LineNo); typedef VOID (*PBL_CONSOLE_CLEAR_SCREEN)(); @@ -64,12 +65,15 @@ typedef VOID (*PBL_CONSOLE_SET_CURSOR_POSITION)(IN ULONGLONG PosX, IN ULONGLONG typedef VOID (*PBL_CONSOLE_WRITE)(IN PUSHORT String); typedef VOID (*PBL_DEBUG_PRINT)(IN PUINT16 Format, IN ...); typedef EFI_STATUS (*PBL_EXIT_BOOT_SERVICES)(IN UINT_PTR MapKey); +typedef EFI_STATUS (*PBL_FIND_BOOT_PROTOCOL)(IN PWCHAR SystemType, OUT PEFI_GUID BootProtocolGuid); typedef EFI_STATUS (*PBL_FREE_PAGES)(IN UINT64 Size, IN EFI_PHYSICAL_ADDRESS Memory); typedef EFI_STATUS (*PBL_FREE_POOL)(IN PVOID Memory); typedef INT_PTR (*PBL_GET_SECURE_BOOT_STATUS)(); +typedef EFI_STATUS (*PBL_INVOKE_BOOT_PROTOCOL)(IN PLIST_ENTRY OptionsList); typedef EFI_STATUS (*PBL_OPEN_VOLUME)(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, OUT PEFI_HANDLE DiskHandle, OUT PEFI_FILE_HANDLE *FsHandle); typedef EFI_STATUS (*PBL_OPEN_XT_PROTOCOL)(OUT PVOID *ProtocolHandler, IN PEFI_GUID ProtocolGuid); typedef EFI_STATUS (*PBL_READ_FILE)(IN PEFI_FILE_HANDLE DirHandle, IN CONST PWCHAR FileName, OUT PVOID *FileData, OUT PSIZE_T FileSize); +typedef EFI_STATUS (*PBL_REGISTER_BOOT_PROTOCOL)(IN PWCHAR SystemType, IN PEFI_GUID BootProtocolGuid); typedef VOID (*PBL_REGISTER_XT_BOOT_MENU)(PVOID BootMenuRoutine); typedef VOID (*PBL_SLEEP_EXECUTION)(IN ULONG_PTR Milliseconds); typedef VOID (*PBL_TUI_DISPLAY_ERROR_DIALOG)(IN PWCHAR Caption, IN PWCHAR Message); @@ -92,6 +96,12 @@ typedef struct _XTBL_BOOT_PARAMETERS PWCHAR Parameters; } XTBL_BOOT_PARAMETERS, *PXTBL_BOOT_PARAMETERS; +/* Boot protocol structure */ +typedef struct _XTBL_BOOT_PROTOCOL +{ + PBL_BOOTPROTO_BOOT_SYSTEM BootSystem; +} XTBL_BOOT_PROTOCOL, *PXTBL_BOOT_PROTOCOL; + /* Boot menu list structure */ typedef struct _XTBL_BOOTMENU_ITEM { @@ -129,9 +139,25 @@ typedef struct _XTBL_DIALOG_HANDLE UINT_PTR Height; } XTBL_DIALOG_HANDLE, *PXTBL_DIALOG_HANDLE; +/* Registered boot protocol structure */ +typedef struct _XTBL_KNOWN_BOOT_PROTOCOL +{ + LIST_ENTRY Flink; + PWCHAR SystemType; + EFI_GUID Guid; +} XTBL_KNOWN_BOOT_PROTOCOL, *PXTBL_KNOWN_BOOT_PROTOCOL; + /* XTLDR Loader protocol */ typedef struct _XTBL_LOADER_PROTOCOL { + struct + { + PBL_FIND_BOOT_PROTOCOL FindProtocol; + PBL_BOOTMENU_INITIALIZE_OS_LIST InitializeMenuList; + PBL_INVOKE_BOOT_PROTOCOL InvokeProtocol; + PBL_REGISTER_XT_BOOT_MENU RegisterMenu; + PBL_REGISTER_BOOT_PROTOCOL RegisterProtocol; + } Boot; struct { PBL_CLEAR_CONSOLE_LINE ClearLine; @@ -165,9 +191,7 @@ typedef struct _XTBL_LOADER_PROTOCOL } Memory; struct { - PBL_BOOTMENU_INITIALIZE_OS_LIST InitializeBootMenuList; - PBL_OPEN_XT_PROTOCOL OpenProtocol; - PBL_REGISTER_XT_BOOT_MENU RegisterBootMenu; + PBL_OPEN_XT_PROTOCOL Open; } Protocol; struct { diff --git a/sdk/xtdk/xtstruct.h b/sdk/xtdk/xtstruct.h index b005bfd..a8835f4 100644 --- a/sdk/xtdk/xtstruct.h +++ b/sdk/xtdk/xtstruct.h @@ -264,12 +264,17 @@ typedef struct _UEFI_FIRMWARE_INFORMATION UEFI_FIRMWARE_INFORMATION, *PUEFI_FIRM typedef struct _UNICODE_STRING UNICODE_STRING, *PUNICODE_STRING; typedef struct _UNICODE_STRING32 UNICODE_STRING32, *PUNICODE_STRING32; typedef struct _UNICODE_STRING64 UNICODE_STRING64, *PUNICODE_STRING64; +typedef struct _XTBL_BOOT_PARAMETERS XTBL_BOOT_PARAMETERS, *PXTBL_BOOT_PARAMETERS; +typedef struct _XTBL_BOOT_PROTOCOL XTBL_BOOT_PROTOCOL, *PXTBL_BOOT_PROTOCOL; typedef struct _XTBL_BOOTMENU_ITEM XTBL_BOOTMENU_ITEM, *PXTBL_BOOTMENU_ITEM; typedef struct _XTBL_CONFIG_ENTRY XTBL_CONFIG_ENTRY, *PXTBL_CONFIG_ENTRY; typedef struct _XTBL_CONFIG_SECTION XTBL_CONFIG_SECTION, *PXTBL_CONFIG_SECTION; typedef struct _XTBL_DIALOG_HANDLE XTBL_DIALOG_HANDLE, *PXTBL_DIALOG_HANDLE; -typedef struct _XTBL_STATUS XTBL_STATUS, *PXTBL_STATUS; +typedef struct _XTBL_KNOWN_BOOT_PROTOCOL XTBL_KNOWN_BOOT_PROTOCOL, *PXTBL_KNOWN_BOOT_PROTOCOL; typedef struct _XTBL_LOADER_PROTOCOL XTBL_LOADER_PROTOCOL, *PXTBL_LOADER_PROTOCOL; +typedef struct _XTBL_MODULE_DEPS XTBL_MODULE_DEPS, *PXTBL_MODULE_DEPS; +typedef struct _XTBL_MODULE_INFO XTBL_MODULE_INFO, *PXTBL_MODULE_INFO; +typedef struct _XTBL_STATUS XTBL_STATUS, *PXTBL_STATUS; /* Unions forward references */ typedef union _EFI_DEV_PATH EFI_DEV_PATH, *PEFI_DEV_PATH; diff --git a/xtldr2/efiutils.c b/xtldr2/efiutils.c index a41b5a5..41e7f5a 100644 --- a/xtldr2/efiutils.c +++ b/xtldr2/efiutils.c @@ -143,7 +143,8 @@ BlpInitializeEfiBootLoader() /* Print XTLDR version */ BlConsolePrint(L"XTLDR boot loader v%s\n", XTOS_VERSION); - /* Initialize XTLDR configuration and loaded modules lists */ + /* Initialize XTLDR configuration linked lists */ + RtlInitializeListHead(&BlpBootProtocols); RtlInitializeListHead(&BlpConfig); RtlInitializeListHead(&BlpLoadedModules); diff --git a/xtldr2/globals.c b/xtldr2/globals.c index 431c828..cbfc400 100644 --- a/xtldr2/globals.c +++ b/xtldr2/globals.c @@ -9,6 +9,9 @@ #include +/* XT Boot Loader registered boot protocol list */ +LIST_ENTRY BlpBootProtocols; + /* XT Boot Loader configuration list */ LIST_ENTRY BlpConfig; diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index 8bec805..246096b 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -78,6 +78,11 @@ XTCDECL EFI_STATUS BlExitBootServices(IN UINT_PTR MapKey); +XTCDECL +EFI_STATUS +BlFindBootProtocol(IN PWCHAR SystemType, + OUT PEFI_GUID BootProtocolGuid); + XTCDECL EFI_STATUS BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle, @@ -105,6 +110,10 @@ BlInitializeBootMenuList(OUT PXTBL_BOOTMENU_ITEM MenuEntries, OUT PULONG EntriesCount, OUT PULONG DefaultId); +XTCDECL +EFI_STATUS +BlInvokeBootProtocol(IN PLIST_ENTRY OptionsList); + XTCDECL EFI_STATUS BlLoadModule(IN PWCHAR ModuleName); @@ -163,6 +172,11 @@ XTCDECL VOID BlRegisterBootMenu(PVOID BootMenuRoutine); +XTCDECL +EFI_STATUS +BlRegisterBootProtocol(IN PWCHAR SystemType, + IN PEFI_GUID BootProtocolGuid); + XTCDECL VOID BlResetConsoleInputBuffer(); diff --git a/xtldr2/includes/globals.h b/xtldr2/includes/globals.h index 5fe9363..b5eed43 100644 --- a/xtldr2/includes/globals.h +++ b/xtldr2/includes/globals.h @@ -12,6 +12,9 @@ #include +/* XT Boot Loader registered boot protocol list */ +EXTERN LIST_ENTRY BlpBootProtocols; + /* XT Boot Loader configuration list */ EXTERN LIST_ENTRY BlpConfig; diff --git a/xtldr2/protocol.c b/xtldr2/protocol.c index ac743e2..3ba341e 100644 --- a/xtldr2/protocol.c +++ b/xtldr2/protocol.c @@ -9,6 +9,49 @@ #include +/** + * Finds a boot protocol for specified system type. + * + * @param SystemType + * Specifies the system type to search for. + * + * @param BootProtocolGuid + * Receives the GUID of the registered boot protocol, that supports specified system. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlFindBootProtocol(IN PWCHAR SystemType, + OUT PEFI_GUID BootProtocolGuid) +{ + PXTBL_KNOWN_BOOT_PROTOCOL ProtocolEntry; + PLIST_ENTRY ProtocolListEntry; + + ProtocolListEntry = BlpBootProtocols.Flink; + while(ProtocolListEntry != &BlpBootProtocols) + { + /* Get boot protocol entry */ + ProtocolEntry = CONTAIN_RECORD(ProtocolListEntry, XTBL_KNOWN_BOOT_PROTOCOL, Flink); + + /* Check if this boot protocol supports specified system */ + if(RtlCompareWideStringInsensitive(ProtocolEntry->SystemType, SystemType, 0) == 0) + { + /* Boot protocol matched, return success */ + BootProtocolGuid = &ProtocolEntry->Guid; + return STATUS_EFI_SUCCESS; + } + + /* Move to the next registered boot protocol */ + ProtocolListEntry = ProtocolListEntry->Flink; + } + + /* Boot protocol not found, return error */ + return STATUS_EFI_NOT_FOUND; +} + /** * Loads a specified XTLDR module from disk. * @@ -287,7 +330,7 @@ BlLoadModules(IN PWCHAR ModulesList) * @param ProtocolGuid * Supplies a pointer to the unique protocol GUID. * - * @return This routine returns status code. + * @return This routine returns a status code. * * @since XT 1.0 */ @@ -361,10 +404,66 @@ BlRegisterBootMenu(PVOID BootMenuRoutine) BlpStatus.BootMenu = BootMenuRoutine; } +/** + * Registers a known boot protocol for a specified OS. + * + * @param SystemType + * Supplies the type of the OS, such as "LINUX", "XTOS", etc. that is supported by the boot protocol. + * + * @param BootProtocolGuid + * Supplies a pointer to the unique protocol GUID. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlRegisterBootProtocol(IN PWCHAR SystemType, + IN PEFI_GUID BootProtocolGuid) +{ + PXTBL_KNOWN_BOOT_PROTOCOL ProtocolEntry; + PLIST_ENTRY ProtocolListEntry; + EFI_STATUS Status; + + ProtocolListEntry = BlpBootProtocols.Flink; + while(ProtocolListEntry != &BlpBootProtocols) + { + /* Get boot protocol entry */ + ProtocolEntry = CONTAIN_RECORD(ProtocolListEntry, XTBL_KNOWN_BOOT_PROTOCOL, Flink); + + /* Check if boot protocol already registered for specified system */ + if(RtlCompareWideStringInsensitive(ProtocolEntry->SystemType, SystemType, 0) == 0) + { + /* Boot protocol already registered */ + return STATUS_EFI_ABORTED; + } + + /* Move to the next registered boot protocol */ + ProtocolListEntry = ProtocolListEntry->Flink; + } + + /* Create new boot protocol entry */ + Status = BlMemoryAllocatePool(sizeof(XTBL_BOOT_PROTOCOL), (PVOID *)&ProtocolEntry); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure */ + return STATUS_EFI_OUT_OF_RESOURCES; + } + + /* Set protocol properties and add it to the list */ + ProtocolEntry->SystemType = SystemType; + ProtocolEntry->Guid = *BootProtocolGuid; + RtlInsertTailList(&BlpBootProtocols, &ProtocolEntry->Flink); + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + /** * This routine registers XTLDR protocol for further usage by modules. * - * @return This routine returns status code. + * @return This routine returns a status code. * * @since XT 1.0 */ @@ -377,6 +476,11 @@ BlpRegisterXtLoaderProtocol() EFI_HANDLE Handle = NULL; /* Set all routines available via loader protocol */ + LdrProtocol.Boot.FindProtocol = BlFindBootProtocol; + LdrProtocol.Boot.InitializeMenuList = BlInitializeBootMenuList; + LdrProtocol.Boot.InvokeProtocol = BlInvokeBootProtocol; + LdrProtocol.Boot.RegisterMenu = BlRegisterBootMenu; + LdrProtocol.Boot.RegisterProtocol = BlRegisterBootProtocol; LdrProtocol.Console.ClearLine = BlClearConsoleLine; LdrProtocol.Console.ClearScreen = BlClearConsoleScreen; LdrProtocol.Console.DisableCursor = BlDisableConsoleCursor; @@ -396,9 +500,7 @@ BlpRegisterXtLoaderProtocol() LdrProtocol.Memory.AllocatePool = BlMemoryAllocatePool; LdrProtocol.Memory.FreePages = BlMemoryFreePages; LdrProtocol.Memory.FreePool = BlMemoryFreePool; - LdrProtocol.Protocol.InitializeBootMenuList = BlInitializeBootMenuList; - LdrProtocol.Protocol.OpenProtocol = BlOpenXtProtocol; - LdrProtocol.Protocol.RegisterBootMenu = BlRegisterBootMenu; + LdrProtocol.Protocol.Open = BlOpenXtProtocol; LdrProtocol.Tui.DisplayErrorDialog = BlDisplayErrorDialog; LdrProtocol.Tui.DisplayInfoDialog = BlDisplayInfoDialog; LdrProtocol.Tui.DisplayProgressDialog = BlDisplayProgressDialog; diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index 8a4e324..921104c 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -111,10 +111,12 @@ EFI_STATUS BlInvokeBootProtocol(IN PLIST_ENTRY OptionsList) { XTBL_BOOT_PARAMETERS BootParameters; - PWCHAR ModulesList; + PXTBL_BOOT_PROTOCOL BootProtocol; PLIST_ENTRY OptionsListEntry; PXTBL_CONFIG_ENTRY Option; + EFI_GUID BootProtocolGuid; SIZE_T ModuleListLength; + PWCHAR ModulesList; EFI_STATUS Status; /* Initialize boot parameters */ @@ -151,8 +153,14 @@ BlInvokeBootProtocol(IN PLIST_ENTRY OptionsList) } else if(RtlCompareWideStringInsensitive(Option->Name, L"SYSTEMPATH", 0) == 0) { - /* System path found, get boot volume */ - + /* System path found, get volume device path */ + Status = BlGetVolumeDevicePath((PWCHAR)Option->Value, &BootParameters.DevicePath, &BootParameters.ArcName, &BootParameters.SystemPath); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to find volume */ + BlDebugPrint(L"ERROR: Failed to find volume device path (Status Code: 0x%lx)\n", Status); + return Status; + } } else if(RtlCompareWideStringInsensitive(Option->Name, L"KERNELFILE", 0) == 0) { @@ -188,11 +196,26 @@ BlInvokeBootProtocol(IN PLIST_ENTRY OptionsList) return STATUS_EFI_NOT_READY; } - // TODO: Add support for boot protocol and invoke it - return STATUS_EFI_UNSUPPORTED; + /* Attempt to get boot protocol GUID */ + Status = BlFindBootProtocol(BootParameters.SystemType, &BootProtocolGuid); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to get boot protocol GUID */ + BlDebugPrint(L"ERROR: Unable to find appropriate boot protocol (Status Code: 0x%lx)\n", Status); + return STATUS_EFI_UNSUPPORTED; + } - /* This point should never be reached */ - return STATUS_EFI_SUCCESS; + /* Open boot protocol */ + Status = BlOpenXtProtocol((PVOID *)&BootProtocol, &BootProtocolGuid); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to open boot protocol */ + BlDebugPrint(L"ERROR: Failed to open boot protocol (Status Code: 0x%lx)\n", Status); + return Status; + } + + /* Boot Operating System */ + return BootProtocol->BootSystem(&BootParameters); } /**