/*++ Copyright (c) 2024, Quinn Stephens. Provided under the BSD 3-Clause license. Module Name: bootlib.c Abstract: Provides boot library utilities. --*/ #include #include "bootlib.h" #define MIN_INPUT_PARAMETERS_SIZE ( \ sizeof(BOOT_APPLICATION_PARAMETERS) + \ sizeof(BOOT_MEMORY_INFO) + \ sizeof(BOOT_INIT_APPLICATION_ENTRY) + \ sizeof(BOOT_FIRMWARE_DATA) + \ sizeof(BOOT_RETURN_DATA) \ ) ULONG BlPlatformFlags = 0x002a0000 | FIRMWARE_FLAG_EXECUTION_CONTEXT_SUPPORTED; PBOOT_DEVICE BlpBootDevice; PBOOT_APPLICATION_PARAMETERS BlpApplicationParameters; BOOT_LIBRARY_PARAMETERS BlpLibraryParameters; BOOT_APPLICATION_ENTRY BlpApplicationEntry; NTSTATUS InitializeLibrary ( IN PBOOT_APPLICATION_PARAMETERS ApplicationParameters, IN PBOOT_LIBRARY_PARAMETERS LibraryParameters ) /*++ Routine Description: Initializes the boot library. Arguments: ApplicationParameters - Pointer to the application's input parameters. LibraryParameters - Pointer to the library parameters. Return Value: STATUS_SUCCESS if successful. --*/ { NTSTATUS Status; PBOOT_MEMORY_INFO MemoryInfo; PBOOT_INIT_APPLICATION_ENTRY ApplicationEntry; PBOOT_FIRMWARE_DATA FirmwareData; if (ApplicationParameters == NULL || ApplicationParameters->Signature != BOOT_APPLICATION_PARAMETERS_SIGNATURE || ApplicationParameters->Size < MIN_INPUT_PARAMETERS_SIZE) { return STATUS_INVALID_PARAMETER; } MemoryInfo = (PBOOT_MEMORY_INFO)((PUCHAR)ApplicationParameters + ApplicationParameters->MemoryInfoOffset); ApplicationEntry = (PBOOT_INIT_APPLICATION_ENTRY)((PUCHAR)ApplicationParameters + ApplicationParameters->ApplicationEntryOffset); BlpBootDevice = (PBOOT_DEVICE)((PUCHAR)ApplicationParameters + ApplicationParameters->BootDeviceOffset); FirmwareData = (PBOOT_FIRMWARE_DATA)((PUCHAR)ApplicationParameters + ApplicationParameters->FirmwareDataOffset); // // Initialize firmware library. // It is important to do this early so that // ConsolePrint() and DebugPrint() can be used. // Status = BlpFwInitialize(0, FirmwareData); if (!NT_SUCCESS(Status)) { goto Stage0Failed; } ConsolePrint(L"> Alcyone EFI Boot Manager\r\n"); ConsolePrintf(L"Image base: %x %x\r\nImage size: %x\r\n", HIDWORD((ULONG_PTR)ApplicationParameters->ImageBase), LODWORD((ULONG_PTR)ApplicationParameters->ImageBase), ApplicationParameters->ImageSize); if (ApplicationEntry->Signature != BOOT_INIT_APPLICATION_ENTRY_SIGNATURE) { DebugPrint(L"InitializeLibrary(): ApplicationEntry Signature is invalid\r\n"); Status = STATUS_INVALID_PARAMETER_9; goto Stage0Failed; } // // Save library and application parameters. // BlpApplicationParameters = ApplicationParameters; RtlCopyMemory(&BlpLibraryParameters, LibraryParameters, sizeof(BOOT_LIBRARY_PARAMETERS)); // // Save application entry. // BlpApplicationEntry.Attributes = ApplicationEntry->Attributes; RtlCopyMemory(&BlpApplicationEntry.BcdIdentifier, &ApplicationEntry->BcdIdentifier, sizeof(GUID)); BlpApplicationEntry.Options = &ApplicationEntry->Options; Status = BlpArchInitialize(0); if (!NT_SUCCESS(Status)) { goto Stage0Failed; } Status = BlpMmInitialize(MemoryInfo, ApplicationParameters->TranslationType, LibraryParameters); if (!NT_SUCCESS(Status)) { goto Stage0Failed; } Status = BlpFwInitialize(1, FirmwareData); if (!NT_SUCCESS(Status)) { goto Stage1Failed; } Status = BlpArchInitialize(1); if (!NT_SUCCESS(Status)) { goto Stage1Failed; } Stage1Failed: BlpMmDestroy(1); Stage0Failed: return STATUS_SUCCESS; } NTSTATUS BlInitializeLibrary ( IN PBOOT_APPLICATION_PARAMETERS ApplicationParameters, IN PBOOT_LIBRARY_PARAMETERS LibraryParameters ) /*++ Routine Description: Initializes the boot library. Wrapper for InitializeLibrary(). Arguments: ApplicationParameters - Pointer to the application's input parameters. LibraryParameters - Pointer to the library parameters. Return Value: Any value returned by InitializeLibrary(). --*/ { return InitializeLibrary(ApplicationParameters, LibraryParameters); } NTSTATUS BlDestroyLibrary ( VOID ) /*++ Routine Description: Cleans up after the boot library. Arguments: None. Return Value: STATUS_SUCCESS if successful. Error code on failure. --*/ { NTSTATUS Status, ExitStatus; ExitStatus = STATUS_SUCCESS; Status = BlpMmDestroy(0); if (!NT_SUCCESS(Status)) { ExitStatus = Status; } Status = BlpMmDestroy(1); if (!NT_SUCCESS(Status)) { ExitStatus = Status; } return ExitStatus; }