[PATCH v3 24/31] bootstd: Add an implementation of EFI bootmgr

Heinrich Schuchardt xypron.glpk at gmx.de
Wed Jan 19 12:47:25 CET 2022


On 1/19/22 02:43, Simon Glass wrote:
> Add a bootmeth driver which handles EFI boot manager, using EFI_LOADER.
>
> In effect, this provides the same functionality as the 'bootefi bootmgr'
> command and shares the same code. But the interface into it is via a
> bootmeth, so it does not require any special scripts, etc.
>
> For now this requires the 'bootefi' command be enabled. Future work may
> tidy this up so that it can be used without CONFIG_CMDLINE being enabled.
>
> Signed-off-by: Simon Glass <sjg at chromium.org>
> ---
>
> Changes in v3:
> - Add a log category
>
>   boot/Makefile           |  3 ++
>   boot/bootmeth_efi_mgr.c | 86 +++++++++++++++++++++++++++++++++++++++++
>   2 files changed, 89 insertions(+)
>   create mode 100644 boot/bootmeth_efi_mgr.c
>
> diff --git a/boot/Makefile b/boot/Makefile
> index 795665f7ce5..38b10d81f0d 100644
> --- a/boot/Makefile
> +++ b/boot/Makefile
> @@ -31,6 +31,9 @@ obj-$(CONFIG_$(SPL_TPL_)BOOTSTD) += bootstd-uclass.o
>   obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_DISTRO) += bootmeth_distro.o
>   obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_DISTRO_PXE) += bootmeth_pxe.o
>   obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_EFILOADER) += bootmeth_efi.o
> +ifdef CONFIG_$(SPL_TPL_)BOOTSTD_FULL
> +obj-$(CONFIG_$(SPL_TPL_)CMD_BOOTEFI_BOOTMGR) += bootmeth_efi_mgr.o
> +endif
>
>   obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += image-fdt.o
>   obj-$(CONFIG_$(SPL_TPL_)FIT_SIGNATURE) += fdt_region.o
> diff --git a/boot/bootmeth_efi_mgr.c b/boot/bootmeth_efi_mgr.c
> new file mode 100644
> index 00000000000..a6914466db7
> --- /dev/null
> +++ b/boot/bootmeth_efi_mgr.c
> @@ -0,0 +1,86 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Bootmethod for EFI boot manager
> + *
> + * Copyright 2021 Google LLC
> + * Written by Simon Glass <sjg at chromium.org>
> + */
> +
> +#define LOG_CATEGORY UCLASS_BOOTSTD
> +
> +#include <common.h>
> +#include <bootdev.h>
> +#include <bootflow.h>
> +#include <bootmeth.h>
> +#include <command.h>
> +#include <dm.h>
> +
> +static int efi_mgr_check(struct udevice *dev, struct bootflow_iter *iter)
> +{
> +	int ret;
> +
> +	/* Must be an bootstd device */
> +	ret = bootflow_iter_uses_system(iter);
> +	if (ret)
> +		return log_msg_ret("net", ret);
> +
> +	return 0;
> +}
> +
> +static int efi_mgr_read_bootflow(struct udevice *dev, struct bootflow *bflow)
> +{
> +	/*
> +	 * Just assume there is something to boot since we don't have any way
> +	 * of knowing in advance
> +	 */
> +	bflow->state = BOOTFLOWST_READY;
> +
> +	return 0;
> +}
> +
> +static int efi_mgr_read_file(struct udevice *dev, struct bootflow *bflow,
> +				const char *file_path, ulong addr, ulong *sizep)
> +{
> +	/* Files are loaded by the 'bootefi bootmgr' command */
> +
> +	return -ENOSYS;
> +}
> +
> +static int efi_mgr_boot(struct udevice *dev, struct bootflow *bflow)
> +{
> +	int ret;
> +
> +	/* Booting is handled by the 'bootefi bootmgr' command */
> +	ret = run_command("bootefi bootmgr", 0);

You are missing to provide the device tree.

Best regards

Heinrich

> +
> +	return 0;
> +}
> +
> +static int bootmeth_efi_mgr_bind(struct udevice *dev)
> +{
> +	struct bootmeth_uc_plat *plat = dev_get_uclass_plat(dev);
> +
> +	plat->desc = "EFI bootmgr flow";
> +
> +	return 0;
> +}
> +
> +static struct bootmeth_ops efi_mgr_bootmeth_ops = {
> +	.check		= efi_mgr_check,
> +	.read_bootflow	= efi_mgr_read_bootflow,
> +	.read_file	= efi_mgr_read_file,
> +	.boot		= efi_mgr_boot,
> +};
> +
> +static const struct udevice_id efi_mgr_bootmeth_ids[] = {
> +	{ .compatible = "u-boot,efi-bootmgr" },
> +	{ }
> +};
> +
> +U_BOOT_DRIVER(bootmeth_zefi_mgr) = {
> +	.name		= "bootmeth_efi_mgr",
> +	.id		= UCLASS_BOOTMETH,
> +	.of_match	= efi_mgr_bootmeth_ids,
> +	.ops		= &efi_mgr_bootmeth_ops,
> +	.bind		= bootmeth_efi_mgr_bind,
> +};



More information about the U-Boot mailing list