[PATCH] efi_loader: support EFI_OS_INDICATIONS_BOOT_TO_FW_UI

Gary Guo gary at garyguo.net
Tue Mar 31 21:18:51 CEST 2026


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



More information about the U-Boot mailing list