While we are keeping handover the default for now, this should change in future and the first step towards doing that is allowing users to try both at runtime.
Add a new $global.linux.efi.handover variable to control this. Signed-off-by: Ahmad Fatoum <[email protected]> --- arch/x86/configs/efi_defconfig | 1 + efi/payload/Kconfig | 24 ++++++++++++++++++++++-- efi/payload/Makefile | 2 +- efi/payload/bootm.c | 29 ++++++++++++++++++++++++++--- efi/payload/handover.c | 5 +++-- efi/payload/image.h | 11 +++++++++++ 6 files changed, 64 insertions(+), 8 deletions(-) diff --git a/arch/x86/configs/efi_defconfig b/arch/x86/configs/efi_defconfig index 1dd823af40ea..e21ac4fda3e7 100644 --- a/arch/x86/configs/efi_defconfig +++ b/arch/x86/configs/efi_defconfig @@ -18,6 +18,7 @@ CONFIG_STATE=y CONFIG_BOOTCHOOSER=y CONFIG_RESET_SOURCE=y CONFIG_DEBUG_LL=y +CONFIG_EFI_PAYLOAD_BOOTM=y CONFIG_CMD_DMESG=y CONFIG_LONGHELP=y CONFIG_CMD_IOMEM=y diff --git a/efi/payload/Kconfig b/efi/payload/Kconfig index 31eab4f3ef88..782e974d8f58 100644 --- a/efi/payload/Kconfig +++ b/efi/payload/Kconfig @@ -26,9 +26,29 @@ config EFI_STUB def_bool HAVE_EFI_STUB config EFI_HANDOVER_PROTOCOL - bool "EFI Handover protocol" - depends on !EFI_PAYLOAD_BOOTM + bool "EFI Handover protocol (DEPRECATED)" depends on X86 + default y + help + Select this in order to include support for booting Linux + over the deprecated EFI handover protocol, which defines alternative + entry points into the EFI stub. + + This is a practice that has no basis in the UEFI specification, + and requires a priori knowledge on the part of the bootloader about + Linux/x86 specific ways of passing the command line and initrd, + and where in memory those assets may be loaded. + + This method of booting has been deprecated in Linux v6.2 in favor + of the StartImage() boot service and should not be required with + Linux v5.7 and above. + + If you say y here, the handover protocol will be used, unless + global.linux.efi.handover=0 was set. + + If unsure, keep the default of y. The StartImage support for booting + Linux is still new in barebox and will be made the default once we + gain more confidence in its implementation. config EFI_PAYLOAD_BOOTM bool "EFI bootm protocol" diff --git a/efi/payload/Makefile b/efi/payload/Makefile index 083728c53cb4..34efe6105d22 100644 --- a/efi/payload/Makefile +++ b/efi/payload/Makefile @@ -3,7 +3,7 @@ obj-y += init.o obj-y += image.o obj-$(CONFIG_EFI_HANDOVER_PROTOCOL) += handover.o -obj-$(CONFIG_EFI_PAYLOAD_BOOTM) += bootm.o +obj-y += bootm.o obj-y += efi-initrd.o obj-$(CONFIG_OFTREE) += fdt.o bbenv-y += env-efi diff --git a/efi/payload/bootm.c b/efi/payload/bootm.c index da53e3939d26..2e060762f238 100644 --- a/efi/payload/bootm.c +++ b/efi/payload/bootm.c @@ -9,6 +9,7 @@ #include <clock.h> #include <common.h> +#include <globalvar.h> #include <linux/sizes.h> #include <linux/ktime.h> #include <memory.h> @@ -284,16 +285,32 @@ static int efi_app_execute(struct image_data *data) return efi_execute_image(handle, loaded_image, type); } +static int linux_efi_handover = true; + +bool efi_x86_boot_method_check(struct image_handler *handler, + struct image_data *data, + enum filetype detected_filetype) +{ + if (handler->filetype != detected_filetype) + return false; + + if (IS_ENABLED(CONFIG_EFI_HANDOVER_PROTOCOL) && linux_efi_handover) + return handler == &efi_x86_linux_handle_handover; + else + return handler == &efi_x86_linux_handle_tr; +} + static struct image_handler efi_app_handle_tr = { .name = "EFI Application", .bootm = efi_app_execute, .filetype = filetype_exe, }; -static struct image_handler efi_x86_linux_handle_tr = { - .name = "EFI X86 Linux kernel", +struct image_handler efi_x86_linux_handle_tr = { + .name = "EFI X86 Linux kernel (StartImage)", .bootm = do_bootm_efi_stub, .filetype = filetype_x86_efi_linux_image, + .check_image = efi_x86_boot_method_check, }; static struct image_handler efi_arm64_handle_tr = { @@ -302,12 +319,18 @@ static struct image_handler efi_arm64_handle_tr = { .filetype = filetype_arm64_efi_linux_image, }; +BAREBOX_MAGICVAR(global.linux.efi.handover, + "Use legacy x86 handover protocol instead of StartImage BootService"); + static int efi_register_bootm_handler(void) { register_image_handler(&efi_app_handle_tr); - if (IS_ENABLED(CONFIG_X86)) + if (IS_ENABLED(CONFIG_X86)) { + if (IS_ENABLED(CONFIG_EFI_HANDOVER_PROTOCOL)) + globalvar_add_simple_bool("linux.efi.handover", &linux_efi_handover); register_image_handler(&efi_x86_linux_handle_tr); + } if (IS_ENABLED(CONFIG_ARM64)) register_image_handler(&efi_arm64_handle_tr); diff --git a/efi/payload/handover.c b/efi/payload/handover.c index f549568b6d03..8c6dd2896f47 100644 --- a/efi/payload/handover.c +++ b/efi/payload/handover.c @@ -128,10 +128,11 @@ static int do_bootm_efi(struct image_data *data) return 0; } -static struct image_handler efi_x86_linux_handle_handover = { - .name = "EFI Application", +struct image_handler efi_x86_linux_handle_handover = { + .name = "EFI X86 Linux kernel (Legacy Handover)", .bootm = do_bootm_efi, .filetype = filetype_x86_efi_linux_image, + .check_image = efi_x86_boot_method_check, }; static int efi_register_handover_handler(void) diff --git a/efi/payload/image.h b/efi/payload/image.h index 673b21db839a..bab1be368c21 100644 --- a/efi/payload/image.h +++ b/efi/payload/image.h @@ -3,6 +3,10 @@ #define __EFI_PAYLOAD_IMAGE_H__ #include <efi/types.h> +#include <filetype.h> + +struct efi_loaded_image; +struct image_data; int efi_load_image(const char *file, struct efi_loaded_image **loaded_image, efi_handle_t *h); @@ -11,4 +15,11 @@ int efi_execute_image(efi_handle_t handle, struct efi_loaded_image *loaded_image, enum filetype filetype); +extern struct image_handler efi_x86_linux_handle_tr; +extern struct image_handler efi_x86_linux_handle_handover; + +bool efi_x86_boot_method_check(struct image_handler *handler, + struct image_data *data, + enum filetype detected_filetype); + #endif -- 2.47.3
