[PATCH v2 19/35] bootstd: Allow bootmeths to be marked as global

Simon Glass sjg at chromium.org
Sat Jul 30 23:52:21 CEST 2022


The current way of handling things like EFI bootmgr is a bit odd, since
that bootmeth handles selection of the bootdev itself. VBE needs to work
the same way, so we should support it properly.

Add a flag that indicates that the bootmeth is global, rather than being
invoked on each bootdev. Provide a helper to read a bootflow from the
bootmeth.

Signed-off-by: Simon Glass <sjg at chromium.org>
---

(no changes since v1)

 boot/Kconfig            |  7 +++++++
 boot/bootmeth-uclass.c  | 14 ++++++++++++++
 boot/bootmeth_efi_mgr.c |  3 ++-
 cmd/bootmeth.c          |  4 +++-
 include/bootmeth.h      | 23 +++++++++++++++++++++++
 lib/efi_loader/Kconfig  |  1 +
 6 files changed, 50 insertions(+), 2 deletions(-)

diff --git a/boot/Kconfig b/boot/Kconfig
index 7a9ee483bc3..b8adc64b9a7 100644
--- a/boot/Kconfig
+++ b/boot/Kconfig
@@ -343,6 +343,13 @@ config BOOTSTD_BOOTCOMMAND
 	  standard boot does not support all of the features of distro boot
 	  yet.
 
+config BOOTMETH_GLOBAL
+	bool
+	help
+	  Add support for global bootmeths. This feature is used by VBE and
+	  EFI bootmgr, since they take full control over which bootdevs are
+	  selected to boot.
+
 config BOOTMETH_DISTRO
 	bool "Bootdev support for distro boot"
 	depends on CMD_PXE
diff --git a/boot/bootmeth-uclass.c b/boot/bootmeth-uclass.c
index 1e276c0f26b..88bbb32c47f 100644
--- a/boot/bootmeth-uclass.c
+++ b/boot/bootmeth-uclass.c
@@ -71,6 +71,20 @@ int bootmeth_read_file(struct udevice *dev, struct bootflow *bflow,
 	return ops->read_file(dev, bflow, file_path, addr, sizep);
 }
 
+int bootmeth_get_bootflow(struct udevice *dev, struct bootflow *bflow)
+{
+	const struct bootmeth_ops *ops = bootmeth_get_ops(dev);
+
+	if (!ops->read_bootflow)
+		return -ENOSYS;
+	memset(bflow, '\0', sizeof(*bflow));
+	bflow->dev = NULL;
+	bflow->method = dev;
+	bflow->state = BOOTFLOWST_BASE;
+
+	return ops->read_bootflow(dev, bflow);
+}
+
 /**
  * bootmeth_setup_iter_order() - Set up the ordering of bootmeths to scan
  *
diff --git a/boot/bootmeth_efi_mgr.c b/boot/bootmeth_efi_mgr.c
index a6914466db7..08d9328af4e 100644
--- a/boot/bootmeth_efi_mgr.c
+++ b/boot/bootmeth_efi_mgr.c
@@ -61,6 +61,7 @@ static int bootmeth_efi_mgr_bind(struct udevice *dev)
 	struct bootmeth_uc_plat *plat = dev_get_uclass_plat(dev);
 
 	plat->desc = "EFI bootmgr flow";
+	plat->flags = BOOTMETHF_GLOBAL;
 
 	return 0;
 }
@@ -77,7 +78,7 @@ static const struct udevice_id efi_mgr_bootmeth_ids[] = {
 	{ }
 };
 
-U_BOOT_DRIVER(bootmeth_zefi_mgr) = {
+U_BOOT_DRIVER(bootmeth_efi_mgr) = {
 	.name		= "bootmeth_efi_mgr",
 	.id		= UCLASS_BOOTMETH,
 	.of_match	= efi_mgr_bootmeth_ids,
diff --git a/cmd/bootmeth.c b/cmd/bootmeth.c
index c9a27fe8ac6..9fbcccdba7e 100644
--- a/cmd/bootmeth.c
+++ b/cmd/bootmeth.c
@@ -69,7 +69,9 @@ static int do_bootmeth_list(struct cmd_tbl *cmdtp, int flag, int argc,
 			}
 		}
 
-		if (order == -1)
+		if (ucp->flags & BOOTMETHF_GLOBAL)
+			printf("%5s", "glob");
+		else if (order == -1)
 			printf("%5s", "-");
 		else
 			printf("%5x", order);
diff --git a/include/bootmeth.h b/include/bootmeth.h
index 4967031a0a8..c93367b0995 100644
--- a/include/bootmeth.h
+++ b/include/bootmeth.h
@@ -12,13 +12,24 @@ struct bootflow;
 struct bootflow_iter;
 struct udevice;
 
+/**
+ * enum bootmeth_flags - Flags for bootmeths
+ *
+ * @BOOTMETHF_GLOBAL: bootmeth handles bootdev selection automatically
+ */
+enum bootmeth_flags {
+	BOOTMETHF_GLOBAL	= BIT(0),
+};
+
 /**
  * struct bootmeth_uc_plat - information the uclass keeps about each bootmeth
  *
  * @desc: A long description of the bootmeth
+ * @flags: Flags for this bootmeth (enum bootmeth_flags)
  */
 struct bootmeth_uc_plat {
 	const char *desc;
+	int flags;
 };
 
 /** struct bootmeth_ops - Operations for boot methods */
@@ -267,4 +278,16 @@ int bootmeth_alloc_file(struct bootflow *bflow, uint size_limit, uint align);
 int bootmeth_common_read_file(struct udevice *dev, struct bootflow *bflow,
 			      const char *file_path, ulong addr, ulong *sizep);
 
+/**
+ * bootmeth_get_bootflow() - Get a bootflow from a global bootmeth
+ *
+ * Check the bootmeth for a bootflow which can be used. In this case the
+ * bootmeth handles all bootdev selection, etc.
+ *
+ * @dev: bootmeth device to read from
+ * @bflow: Bootflow information
+ * @return 0 on success, -ve if a bootflow could not be found or had an error
+ */
+int bootmeth_get_bootflow(struct udevice *dev, struct bootflow *bflow);
+
 #endif
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
index e3f2402d0e8..e4c51ed231d 100644
--- a/lib/efi_loader/Kconfig
+++ b/lib/efi_loader/Kconfig
@@ -37,6 +37,7 @@ if EFI_LOADER
 config CMD_BOOTEFI_BOOTMGR
 	bool "UEFI Boot Manager"
 	default y
+	select BOOTMETH_GLOBAL
 	help
 	  Select this option if you want to select the UEFI binary to be booted
 	  via UEFI variables Boot####, BootOrder, and BootNext. This enables the
-- 
2.37.1.455.g008518b4e5-goog



More information about the U-Boot mailing list