From mboxrd@z Thu Jan 1 00:00:00 1970 From: Cristian Ciocaltea Date: Tue, 10 Dec 2019 10:56:50 +0200 Subject: [PATCH v2 2/4] bootm: Add a bootm command for type IH_OS_EFI In-Reply-To: References: Message-ID: List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de Add support for booting EFI binaries contained in FIT images. A typical usage scenario is chain-loading GRUB2 in a verified boot environment. Signed-off-by: Cristian Ciocaltea --- cmd/Kconfig | 7 ++++++ common/bootm_os.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/cmd/Kconfig b/cmd/Kconfig index cf982ff65e..39fa87082d 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -263,6 +263,13 @@ config CMD_BOOTI help Boot an AArch64 Linux Kernel image from memory. +config BOOTM_EFI + bool "Support booting EFI OS images" + depends on CMD_BOOTEFI + default y + help + Support booting EFI images via the bootm command. + config BOOTM_LINUX bool "Support booting Linux OS images" depends on CMD_BOOTM || CMD_BOOTZ || CMD_BOOTI diff --git a/common/bootm_os.c b/common/bootm_os.c index 6fb7d658da..7aa76052b9 100644 --- a/common/bootm_os.c +++ b/common/bootm_os.c @@ -6,10 +6,12 @@ #include #include +#include #include #include #include #include +#include #include #include @@ -462,6 +464,62 @@ static int do_bootm_tee(int flag, int argc, char * const argv[], } #endif +#ifdef CONFIG_BOOTM_EFI +static int do_bootm_efi(int flag, int argc, char * const argv[], + bootm_headers_t *images) +{ + int ret; + efi_status_t efi_ret; + uintptr_t fdt_addr; + void *image_buf; + + if (flag != BOOTM_STATE_OS_GO) + return 0; + + /* Locate EFI binary and FDT, if provided */ + ret = bootm_find_images(flag, argc, argv); + if (ret) + return ret; + + /* Initialize EFI drivers */ + efi_ret = efi_init_obj_list(); + if (efi_ret != EFI_SUCCESS) { + printf("## Error: Cannot initialize UEFI sub-system, r = %lu\n", + efi_ret & ~EFI_ERROR_MASK); + return 1; + } + + /* Install device tree */ + if (images->ft_len) + fdt_addr = (uintptr_t)images->ft_addr; + else + fdt_addr = EFI_FDT_USE_INTERNAL; + + efi_ret = efi_install_fdt(fdt_addr); + if (efi_ret != EFI_SUCCESS) { + printf("## Error: Cannot install device tree, r = %lu\n", + efi_ret & ~EFI_ERROR_MASK); + return 1; + } + + /* Run EFI image */ + printf("## Transferring control to EFI (at address %08lx) ...\n", + images->ep); + bootstage_mark(BOOTSTAGE_ID_RUN_OS); + + image_buf = map_sysmem(images->ep, images->os.image_len); + + efi_ret = efi_run_image(image_buf, images->os.image_len); + if (efi_ret != EFI_SUCCESS) { + printf("## Error: Cannot run EFI image, r = %lu\n", + efi_ret & ~EFI_ERROR_MASK); + return 1; + } + + return 0; +} +#endif + static boot_os_fn *boot_os[] = { [IH_OS_U_BOOT] = do_bootm_standalone, #ifdef CONFIG_BOOTM_LINUX @@ -498,6 +556,9 @@ static boot_os_fn *boot_os[] = { #ifdef CONFIG_BOOTM_OPTEE [IH_OS_TEE] = do_bootm_tee, #endif +#ifdef CONFIG_BOOTM_EFI + [IH_OS_EFI] = do_bootm_efi, +#endif }; /* Allow for arch specific config before we boot */ -- 2.17.1