From 0d5405a648d6e6a40ec46e42e9795d15368d90c7 Mon Sep 17 00:00:00 2001 From: Geoffroy Van Cutsem Date: Thu, 26 Apr 2018 14:34:46 +0200 Subject: [PATCH] Make the Service OS bootloader configurable This patch makes the Service OS bootloader configurable by passing a command-line argument to 'acrn.efi' when setting up the EFI bootloader using, e.g., 'efibootmgr'. If no argument is passed, the default bootloader used is: "\EFI\org.clearlinux\bootloaderx64.efi". This is the default bootloader/setting used by Clearlinux and is set in the bsp/uefi/include/bsp/bsp_cfg.h file (via the CONFIG_UEFI_OS_LOADER_NAME define) The general format of the argument is: "bootloader=<\path\to\bootloader>". As a concrete example, imagine the following set-up: * You have installed the Service OS (bare-metal for now) * Bootloader is "\EFI\org.clearlinux\bootloaderx64.efi" * Boot device is '/dev/sda' * EFI System Partition (ESP) is '1' * You put the ACRN hypervisor under "\EFI\acrn\" To change the default boot entry to boot the ACRN hypervisor, enter: # efibootmgr -c -l "\EFI\acrn\acrn.efi" -d /dev/sda -p 1 \ -L "ACRN Hypervisor" -u "bootloader=\EFI\org.clearlinux\bootloaderx64.efi" And reboot your machine. Signed-off-by: Geoffroy Van Cutsem --- bsp/uefi/efi/boot.c | 38 ++++++++++++++++++++++++++++++---- bsp/uefi/include/bsp/bsp_cfg.h | 2 +- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/bsp/uefi/efi/boot.c b/bsp/uefi/efi/boot.c index af7f82f6f..7a6721103 100644 --- a/bsp/uefi/efi/boot.c +++ b/bsp/uefi/efi/boot.c @@ -331,18 +331,21 @@ efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *_table) UINTN sec_size; char *section; EFI_DEVICE_PATH *path; - CHAR16 *bootloader_name; + + INTN Argc, i, index; + CHAR16 **Argv; + CHAR16 *bootloader_name = NULL; + CHAR16 bootloader_param[] = L"bootloader="; EFI_HANDLE bootloader_image; InitializeLib(image, _table); - + Argc = GetShellArgcArgv(image, &Argv); sys_table = _table; boot = sys_table->BootServices; if (CheckCrc(sys_table->Hdr.HeaderSize, &sys_table->Hdr) != TRUE) return EFI_LOAD_ERROR; - err = handle_protocol(image, &LoadedImageProtocol, (void **)&info); if (err != EFI_SUCCESS) goto failed; @@ -368,7 +371,27 @@ efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *_table) goto failed; /* load and start the default bootloader */ - bootloader_name = ch8_2_ch16(CONFIG_UEFI_OS_LOADER_NAME); + + /* First check if we were given a bootloader name + * E.g.: "bootloader=\EFI\org.clearlinux\bootloaderx64.efi" + */ + for (i = 0 ; i < Argc ; ++i) { + bootloader_name = strstr_16(Argv[i], bootloader_param); + if (bootloader_name) { + bootloader_name = bootloader_name + StrLen(bootloader_param); + break; + } + } + + if (!bootloader_name) { + /* + * If we reach this point, it means we did not receive a specific + * bootloader name to be used. Fall back to the default bootloader + * as specified in bsp_cfg.h + */ + bootloader_name = ch8_2_ch16(CONFIG_UEFI_OS_LOADER_NAME); + } + path = FileDevicePath(info->DeviceHandle, bootloader_name); if (!path) goto free_args; @@ -408,6 +431,13 @@ failed: StatusToString(error_buf, err); Print(L": %s\n", error_buf); + + /* If we don't wait for user input, (s)he will not see the error message */ + uefi_call_wrapper(sys_table->ConOut->OutputString, 2, sys_table->ConOut, \ + L"\r\n\r\n\r\nHit any key to exit\r\n"); + uefi_call_wrapper(sys_table->BootServices->WaitForEvent, 3, 1, \ + &sys_table->ConIn->WaitForKey, &index); + return exit(image, err, ERROR_STRING_LENGTH, error_buf); } diff --git a/bsp/uefi/include/bsp/bsp_cfg.h b/bsp/uefi/include/bsp/bsp_cfg.h index 16ec336ed..53b145c7d 100644 --- a/bsp/uefi/include/bsp/bsp_cfg.h +++ b/bsp/uefi/include/bsp/bsp_cfg.h @@ -48,5 +48,5 @@ #define CONFIG_DMAR_PARSE_ENABLED 1 #define CONFIG_GPU_SBDF 0x00000010 /* 0000:00:02.0 */ #define CONFIG_EFI_STUB 1 -#define CONFIG_UEFI_OS_LOADER_NAME "\\EFI\\org.clearlinux\\bootloaderx64_origin.efi" +#define CONFIG_UEFI_OS_LOADER_NAME "\\EFI\\org.clearlinux\\bootloaderx64.efi" #endif /* BSP_CFG_H */