[PATCH] efi_loader: support EFI_OS_INDICATIONS_BOOT_TO_FW_UI

Heinrich Schuchardt xypron.glpk at gmx.de
Fri Apr 3 12:30:08 CEST 2026


Am 31. März 2026 21:18:51 MESZ schrieb Gary Guo <gary at garyguo.net>:
>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>

Thank you Gary for the patch. I am currently on travel and will have to look at it once I have returned.

@Ilias
Should we preferably integrate the detection of this bit into efi_init_early()?

Best regards

Heinrich



>---
> 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()) &&
>+	    (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
>+ *
>+ * 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();
>+	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