From 37fa369066c2db1ecc6c7046192503aedc2431f6 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 26 Feb 2015 18:33:37 +0100 Subject: [PATCH] boot: efi - support embedded splash image --- Makefile.am | 2 ++ src/boot/efi/boot.c | 19 +++---------------- src/boot/efi/graphics.c | 10 ++++++++++ src/boot/efi/stub.c | 8 +++++++- test/test-efi-create-disk.sh | 3 ++- 5 files changed, 24 insertions(+), 18 deletions(-) diff --git a/Makefile.am b/Makefile.am index 470d58b23..25cc50c5e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2601,11 +2601,13 @@ $(systemd_boot): $(systemd_boot_solib) stub_headers = \ src/boot/efi/util.h \ src/boot/efi/pefile.h \ + src/boot/efi/graphics.h \ src/boot/efi/linux.h stub_sources = \ src/boot/efi/util.c \ src/boot/efi/pefile.c \ + src/boot/efi/graphics.c \ src/boot/efi/linux.c \ src/boot/efi/stub.c diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index e739e9412..8bdc7f8c6 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -65,7 +65,6 @@ typedef struct { UINTN timeout_sec_config; INTN timeout_sec_efivar; CHAR16 *entry_default_pattern; - EFI_GRAPHICS_OUTPUT_BLT_PIXEL *background; CHAR16 *entry_oneshot; CHAR16 *options_edit; CHAR16 *entries_auto; @@ -365,7 +364,7 @@ static VOID print_status(Config *config, EFI_FILE *root_dir, CHAR16 *loaded_imag UINTN size; EFI_STATUS err; UINTN color = 0; - const EFI_GRAPHICS_OUTPUT_BLT_PIXEL *pixel = config->background; + const EFI_GRAPHICS_OUTPUT_BLT_PIXEL *pixel = NULL; uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut, EFI_LIGHTGRAY|EFI_BACKGROUND_BLACK); uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut); @@ -402,9 +401,6 @@ static VOID print_status(Config *config, EFI_FILE *root_dir, CHAR16 *loaded_imag Print(L"timeout (config): %d\n", config->timeout_sec_config); if (config->entry_default_pattern) Print(L"default pattern: '%s'\n", config->entry_default_pattern); - if (config->background) - Print(L"background '#%02x%02x%02x'\n", - config->background->Red, config->background->Green, config->background->Blue); Print(L"\n"); Print(L"config entry count: %d\n", config->entry_count); @@ -1761,7 +1757,6 @@ static VOID config_free(Config *config) { FreePool(config->options_edit); FreePool(config->entry_oneshot); FreePool(config->entries_auto); - FreePool(config->background); } EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { @@ -1842,15 +1837,6 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { ZeroMem(&config, sizeof(Config)); config_load(&config, loaded_image->DeviceHandle, root_dir, loaded_image_path); - if (!config.background) { - config.background = AllocateZeroPool(sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); - if (StriCmp(L"Apple", ST->FirmwareVendor) == 0) { - config.background->Red = 0xc0; - config.background->Green = 0xc0; - config.background->Blue = 0xc0; - } - } - /* if we find some well-known loaders, add them to the end of the list */ config_entry_add_linux(&config, loaded_image, root_dir); config_entry_add_loader_auto(&config, loaded_image->DeviceHandle, root_dir, loaded_image_path, @@ -1927,7 +1913,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { len = file_read(root_dir, entry->splash, 0, 0, &content); if (len > 0) - graphics_splash(content, len, config.background); + graphics_splash(content, len, NULL); FreePool(content); } @@ -1938,6 +1924,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { uefi_call_wrapper(BS->SetWatchdogTimer, 4, 5 * 60, 0x10000, 0, NULL); err = image_start(image, &config, entry); if (EFI_ERROR(err)) { + graphics_mode(FALSE); Print(L"\nFailed to execute %s (%s): %r\n", entry->title, entry->loader, err); uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000); goto out; diff --git a/src/boot/efi/graphics.c b/src/boot/efi/graphics.c index 9fbcbc10b..124022a68 100644 --- a/src/boot/efi/graphics.c +++ b/src/boot/efi/graphics.c @@ -322,6 +322,7 @@ EFI_STATUS bmp_to_blt(EFI_GRAPHICS_OUTPUT_BLT_PIXEL *buf, } EFI_STATUS graphics_splash(UINT8 *content, UINTN len, const EFI_GRAPHICS_OUTPUT_BLT_PIXEL *background) { + EFI_GRAPHICS_OUTPUT_BLT_PIXEL pixel = {}; EFI_GUID GraphicsOutputProtocolGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput = NULL; struct bmp_dib *dib; @@ -333,6 +334,15 @@ EFI_STATUS graphics_splash(UINT8 *content, UINTN len, const EFI_GRAPHICS_OUTPUT_ UINTN y_pos = 0; EFI_STATUS err; + if (!background) { + if (StriCmp(L"Apple", ST->FirmwareVendor) == 0) { + pixel.Red = 0xc0; + pixel.Green = 0xc0; + pixel.Blue = 0xc0; + } + background = &pixel; + } + err = LibLocateProtocol(&GraphicsOutputProtocolGuid, (VOID **)&GraphicsOutput); if (EFI_ERROR(err)) return err; diff --git a/src/boot/efi/stub.c b/src/boot/efi/stub.c index e18faac66..bd391965b 100644 --- a/src/boot/efi/stub.c +++ b/src/boot/efi/stub.c @@ -18,10 +18,11 @@ #include "util.h" #include "pefile.h" +#include "graphics.h" #include "linux.h" /* magic string to find in the binary image */ -static const char __attribute__((used)) magic[] = "#### LoaderInfo: stub " VERSION " ####"; +static const char __attribute__((used)) magic[] = "#### LoaderInfo: systemd-stub " VERSION " ####"; static const EFI_GUID global_guid = EFI_GLOBAL_VARIABLE; @@ -36,6 +37,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { (UINT8 *)".cmdline", (UINT8 *)".linux", (UINT8 *)".initrd", + (UINT8 *)".splash", NULL }; UINTN addrs[ELEMENTSOF(sections)-1] = {}; @@ -96,10 +98,14 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { cmdline = line; } + if (szs[3] > 0) + graphics_splash((UINT8 *)((UINTN)loaded_image->ImageBase + addrs[3]), szs[3], NULL); + err = linux_exec(image, cmdline, cmdline_len, (UINTN)loaded_image->ImageBase + addrs[1], (UINTN)loaded_image->ImageBase + addrs[2], szs[2]); + graphics_mode(FALSE); Print(L"Execution of embedded linux image failed: %r\n", err); uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000); return err; diff --git a/test/test-efi-create-disk.sh b/test/test-efi-create-disk.sh index 454b48a08..62d8439ed 100755 --- a/test/test-efi-create-disk.sh +++ b/test/test-efi-create-disk.sh @@ -22,7 +22,8 @@ echo -n "foo=yes bar=no root=/dev/fakeroot debug rd.break=initqueue" > mnt/cmdli objcopy \ --add-section .osrel=/etc/os-release --change-section-vma .osrel=0x20000 \ --add-section .cmdline=mnt/cmdline.txt --change-section-vma .cmdline=0x30000 \ - --add-section .linux=/boot/$(cat /etc/machine-id)/$(uname -r)/linux --change-section-vma .linux=0x40000 \ + --add-section .splash=test/splash.bmp --change-section-vma .splash=0x40000 \ + --add-section .linux=/boot/$(cat /etc/machine-id)/$(uname -r)/linux --change-section-vma .linux=0x2000000 \ --add-section .initrd=/boot/$(cat /etc/machine-id)/$(uname -r)/initrd --change-section-vma .initrd=0x3000000 \ linuxx64.efi.stub mnt/EFI/Linux/linux-test.efi -- 2.30.2