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 <[email protected]> --- 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
