[PATCH] efi_loader: support EFI_OS_INDICATIONS_BOOT_TO_FW_UI
Heinrich Schuchardt
xypron.glpk at gmx.de
Fri Apr 17 07:59:36 CEST 2026
On 3/31/26 21:18, Gary Guo wrote:
> EFI variable OsIndications have a bit EFI_OS_INDICATIONS_BOOT_TO_FW_UI
> indicating that the OS (or next stage bootloader) requests booting into
> firmware UI instead of continuing autoboot process.
>
> Support it by having autoboot.c asking EFI bootmgr if boot should continue,
> which checks and clear the bit (so the next boot continue as normal).
>
> With this change, systemd-boot will show a "Reboot Into Firmware Interface"
> option which will be able to drop back to u-boot. This can be useful if
> bootdelay is configured to be -2.
>
> Signed-off-by: Gary Guo <gary at garyguo.net>
> ---
> common/autoboot.c | 4 +++-
> include/efi_loader.h | 2 ++
> lib/efi_loader/efi_bootmgr.c | 45 ++++++++++++++++++++++++++++++++++++
> lib/efi_loader/efi_setup.c | 4 ++++
> 4 files changed, 54 insertions(+), 1 deletion(-)
>
> diff --git a/common/autoboot.c b/common/autoboot.c
> index 1783ef92c94c..b889407612dc 100644
> --- a/common/autoboot.c
> +++ b/common/autoboot.c
> @@ -11,6 +11,7 @@
> #include <cli.h>
> #include <command.h>
> #include <console.h>
> +#include <efi_loader.h>
> #include <env.h>
> #include <errno.h>
> #include <fdtdec.h>
> @@ -503,7 +504,8 @@ void autoboot_command(const char *s)
> {
> debug("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>");
>
> - if (s && (stored_bootdelay == -2 ||
> + if (s && !(IS_ENABLED(CONFIG_EFI_BOOTMGR) && efi_should_abort_autoboot()) &&
I do not understand why the logic should depend on CONFIG_EFI_BOOTMGR
instead of CONFIG_EFI_LOADER. It seems applicable whenever we support UEFI.
> + (stored_bootdelay == -2 ||
> (stored_bootdelay != -1 && !abortboot(stored_bootdelay)))) {
> bool lock;
> int prev;
> diff --git a/include/efi_loader.h b/include/efi_loader.h
> index 3e70ac070550..449697ad13b3 100644
> --- a/include/efi_loader.h
> +++ b/include/efi_loader.h
> @@ -583,6 +583,8 @@ efi_status_t efi_bootmgr_get_unused_bootoption(u16 *buf,
> efi_status_t efi_bootmgr_update_media_device_boot_option(void);
> /* Delete selected boot option */
> efi_status_t efi_bootmgr_delete_boot_option(u16 boot_index);
> +/* Check if autoboot should be aborted based on EFI vars */
> +bool efi_should_abort_autoboot(void);
> /* Invoke EFI boot manager */
> efi_status_t efi_bootmgr_run(void *fdt);
> /* search the boot option index in BootOrder */
> diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c
> index a687f4d8e85c..39f255ac9de4 100644
> --- a/lib/efi_loader/efi_bootmgr.c
> +++ b/lib/efi_loader/efi_bootmgr.c
> @@ -1290,6 +1290,51 @@ out:
> return ret;
> }
>
> +/**
> + * efi_should_abort_autoboot() - check if autoboot should be aborted per EFI vars
Please, mention the relevant flag.
> + *
> + * Return: true if autoboot should abort
> + */
> +bool efi_should_abort_autoboot(void)
> +{
> + efi_status_t ret;
> + u64 os_indications = 0x0;
> + efi_uintn_t size;
> + efi_status_t r;
> +
> + /* Initialize EFI drivers */
> + ret = efi_init_obj_list();
@Ilias:
Essentially this ends up in always running efi_init_obj_list() if we
have UEFI enabled.
Shouldn't we then replace all invocations of efi_init_obj_list() by a
single call after preboot but before EVT_POST_PREBOOT?
Best regards
Heinrich
> + if (ret != EFI_SUCCESS) {
> + log_err("Error: Cannot initialize UEFI sub-system, r = %lu\n",
> + ret & ~EFI_ERROR_MASK);
> + return false;
> + }
> +
> + size = sizeof(os_indications);
> + r = efi_get_variable_int(u"OsIndications", &efi_global_variable_guid,
> + NULL, &size, &os_indications, NULL);
> + if (r != EFI_SUCCESS || size != sizeof(os_indications))
> + return false;
> +
> + if (!(os_indications & EFI_OS_INDICATIONS_BOOT_TO_FW_UI))
> + return false;
> +
> + /* Clear the BOOT_TO_FW_UI so next boot returns to normal */
> + os_indications &= ~EFI_OS_INDICATIONS_BOOT_TO_FW_UI;
> + r = efi_set_variable_int(u"OsIndications",
> + &efi_global_variable_guid,
> + EFI_VARIABLE_NON_VOLATILE |
> + EFI_VARIABLE_BOOTSERVICE_ACCESS |
> + EFI_VARIABLE_RUNTIME_ACCESS,
> + sizeof(os_indications),
> + &os_indications, false);
> +
> + if (r != EFI_SUCCESS)
> + log_err("Setting %ls failed\n", L"OsIndications");
> +
> + return true;
> +}
> +
> /**
> * efi_bootmgr_run() - execute EFI boot manager
> * @fdt: Flat device tree
> diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c
> index f06cf49e4435..0ad02e9fe0dd 100644
> --- a/lib/efi_loader/efi_setup.c
> +++ b/lib/efi_loader/efi_setup.c
> @@ -156,6 +156,10 @@ static efi_status_t efi_init_os_indications(void)
> {
> u64 os_indications_supported = 0;
>
> + if (IS_ENABLED(CONFIG_EFI_BOOTMGR))
> + os_indications_supported |=
> + EFI_OS_INDICATIONS_BOOT_TO_FW_UI;
> +
> if (IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT))
> os_indications_supported |=
> EFI_OS_INDICATIONS_CAPSULE_RESULT_VAR_SUPPORTED;
More information about the U-Boot
mailing list