[PATCH v1 44/54] efi: loader: add rudimentary EFI boot manager
Ahmad Fatoum
a.fatoum at pengutronix.de
Thu Dec 18 02:38:04 PST 2025
Actual efibootmgr is a bit more involved and would require evaluating
the Boot#### variables. This is planned, but for now let's only
implement the fallback when no variables have been found.
Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
common/boot.c | 7 ++--
efi/loader/Kconfig | 11 ++++++
efi/loader/Makefile | 1 +
efi/loader/efibootmgr.c | 79 +++++++++++++++++++++++++++++++++++++++++
4 files changed, 95 insertions(+), 3 deletions(-)
create mode 100644 efi/loader/efibootmgr.c
diff --git a/common/boot.c b/common/boot.c
index a8a92057844b..7b2ce4740759 100644
--- a/common/boot.c
+++ b/common/boot.c
@@ -136,9 +136,10 @@ static int init_boot(void)
{
if (!global_boot_default)
global_boot_default = xstrdup(
- IF_ENABLED(CONFIG_BOOT_DEFAULTS, "bootsource ")
- IF_ENABLED(CONFIG_BOOT_DEFAULTS, "storage.builtin ")
- IF_ENABLED(CONFIG_BOOT_DEFAULTS, "storage.removable ")
+ IF_ENABLED(CONFIG_EFI_LOADER_BOOTMGR, "efibootmgr ")
+ IF_ENABLED(CONFIG_BOOT_DEFAULTS, "bootsource ")
+ IF_ENABLED(CONFIG_BOOT_DEFAULTS, "storage.builtin ")
+ IF_ENABLED(CONFIG_BOOT_DEFAULTS, "storage.removable ")
"net"
);
diff --git a/efi/loader/Kconfig b/efi/loader/Kconfig
index d54783f9a084..ca0ec6b5010a 100644
--- a/efi/loader/Kconfig
+++ b/efi/loader/Kconfig
@@ -1,6 +1,17 @@
# SPDX-License-Identifier: GPL-2.0-only
# SPDX-Comment: Origin-URL: https://github.com/u-boot/u-boot/blob/a0fe8cedcbe8c76403a77e57eac228b8f778a3ae/lib/efi_loader/Kconfig
+config EFI_LOADER_BOOTMGR
+ bool "Rudimentary UEFI Boot Manager support"
+ select BOOT
+ select BOOT_DEFAULTS
+ default y
+ help
+ This boot manager doesn't yet make use of Boot# variables, but instead
+ hardcodes order to lookup removable and then builtin storage devices
+ for EFI payloads located at the removable media path indicated by
+ CONFIG_EFI_PAYLOAD_DEFAULT_PATH within their respective devices.
+
config EFI_LOADER_DEBUG_SUPPORT
bool "EFI Debug Support"
default y
diff --git a/efi/loader/Makefile b/efi/loader/Makefile
index 84a8bf1ca229..62483057b426 100644
--- a/efi/loader/Makefile
+++ b/efi/loader/Makefile
@@ -13,3 +13,4 @@ obj-y += watchdog.o
obj-y += pe.o
obj-y += loadopts.o
obj-$(CONFIG_BOOT) += bootesp.o
+obj-$(CONFIG_EFI_LOADER_BOOTMGR) += efibootmgr.o
diff --git a/efi/loader/efibootmgr.c b/efi/loader/efibootmgr.c
new file mode 100644
index 000000000000..4f8b04d8298c
--- /dev/null
+++ b/efi/loader/efibootmgr.c
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#define pr_fmt(fmt) "efi-loader: efibootmgr: " fmt
+
+#include <boot.h>
+#include <driver.h>
+
+struct resolve_ctx {
+ struct bootentry_provider *provider;
+ struct bootentries *entries;
+};
+
+static int populate_esp_bootentries(struct cdev *cdev, void *_ctx)
+{
+ struct resolve_ctx *ctx = _ctx;
+
+ pr_debug("processing %s\n", cdev->name);
+
+ return ctx->provider->generate(ctx->entries, cdev->name);
+}
+
+static int efibootmgr_add_entry_from_bootvars(struct bootentries *entries,
+ const char *name)
+{
+ /* TODO: actually make use of the Boot# variables
+ * instead of only hardcoding order
+ */
+ return 0;
+}
+
+static int efibootmgr_add_entry_from_fallback(struct bootentries *entries,
+ const char *name)
+{
+ struct resolve_ctx ctx;
+ int nremovable, nbuiltin;
+
+ ctx.provider = get_bootentry_provider("esp");
+ if (!ctx.provider)
+ return -ENOENT;
+
+ ctx.entries = entries;
+
+ nremovable = cdev_alias_resolve_for_each("storage.removable",
+ populate_esp_bootentries, &ctx);
+ if (nremovable < 0)
+ return nremovable;
+
+ nbuiltin = cdev_alias_resolve_for_each("storage.builtin",
+ populate_esp_bootentries, &ctx);
+ if (nbuiltin < 0)
+ return nbuiltin;
+
+ return nbuiltin + nremovable;
+}
+
+static int efibootmgr_add_entry(struct bootentries *entries, const char *name)
+{
+ int nentries;
+
+ if (strcmp(name, "efibootmgr"))
+ return 0;
+
+ nentries = efibootmgr_add_entry_from_bootvars(entries, name);
+ if (nentries)
+ return nentries;
+
+ return efibootmgr_add_entry_from_fallback(entries, name);
+}
+
+static struct bootentry_provider efibootmgr_entry_provider = {
+ .name = "efibootmgr",
+ .generate = efibootmgr_add_entry,
+};
+
+static int efibootmgr_init(void)
+{
+ return bootentry_register_provider(&efibootmgr_entry_provider);
+}
+device_initcall(efibootmgr_init);
--
2.47.3
More information about the barebox
mailing list