[PATCH v4 38/47] boot: Consider non-bootable partitions

Simon Glass sjg at chromium.org
Thu Mar 6 17:04:05 CET 2025


Any 'bootable' flag in a DOS partition causes boostd to only scan
bootable partitions for that media. This can mean that extlinux.conf
files on the root disk are missed.

Put this logic behind a flag and update the documentation.

For now, the flag is enabled, to preserve existing behaviour. Future
work may provide a command (or some other mechanism) to control this.

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

Changes in v4:
- Rewrite the commit message
- Enable the flag by default

Changes in v3:
- Add new patch to consider non-bootable partitions

 boot/bootdev-uclass.c            | 4 +++-
 cmd/bootflow.c                   | 2 +-
 doc/develop/bootstd/overview.rst | 5 +++--
 include/bootflow.h               | 2 ++
 test/boot/bootdev.c              | 1 +
 test/boot/bootflow.c             | 5 +++--
 6 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/boot/bootdev-uclass.c b/boot/bootdev-uclass.c
index c39147940b6..9e4c3db2dc1 100644
--- a/boot/bootdev-uclass.c
+++ b/boot/bootdev-uclass.c
@@ -168,8 +168,10 @@ int bootdev_find_in_blk(struct udevice *dev, struct udevice *blk,
 		 */
 
 	/* if there are bootable partitions, scan only those */
-	} else if (iter->first_bootable >= 0 &&
+	} else if ((iter->flags & BOOTFLOWIF_ONLY_BOOTABLE) &&
+		   iter->first_bootable >= 0 &&
 		   (iter->first_bootable ? !info.bootable : iter->part != 1)) {
+		log_debug("Skipping non-bootable partition %d\n", iter->part);
 		return log_msg_ret("boot", -EINVAL);
 	} else {
 		ret = fs_set_blk_dev_with_part(desc, bflow->part);
diff --git a/cmd/bootflow.c b/cmd/bootflow.c
index a89c3bfd9c5..e9ac9746104 100644
--- a/cmd/bootflow.c
+++ b/cmd/bootflow.c
@@ -174,7 +174,7 @@ static int do_bootflow_scan(struct cmd_tbl *cmdtp, int flag, int argc,
 
 	std->cur_bootflow = NULL;
 
-	flags = 0;
+	flags = BOOTFLOWIF_ONLY_BOOTABLE;
 	if (list)
 		flags |= BOOTFLOWIF_SHOW;
 	if (all)
diff --git a/doc/develop/bootstd/overview.rst b/doc/develop/bootstd/overview.rst
index c46bd7a5a90..7bca043791b 100644
--- a/doc/develop/bootstd/overview.rst
+++ b/doc/develop/bootstd/overview.rst
@@ -235,8 +235,9 @@ means that `default_get_bootflow()` is used. This simply obtains the
 block device and calls a bootdev helper function to do the rest. The
 implementation of `bootdev_find_in_blk()` checks the partition table, and
 attempts to read a file from a filesystem on the partition number given by the
-`@iter->part` parameter. If there are any bootable partitions in the table,
-then only bootable partitions are considered.
+`@iter->part` parameter. If there are any bootable partitions in the table and
+the BOOTFLOWIF_ONLY_BOOTABLE flag is set in `@iter->flags`, then only bootable
+partitions are considered.
 
 Each bootdev has a priority, which indicates the order in which it is used,
 if `boot_targets` is not used. Faster bootdevs are used first, since they are
diff --git a/include/bootflow.h b/include/bootflow.h
index d9045bc3dae..2caeb80b878 100644
--- a/include/bootflow.h
+++ b/include/bootflow.h
@@ -161,6 +161,7 @@ struct bootflow_img {
  * before using it
  * @BOOTFLOWIF_ALL: Return bootflows with errors as well
  * @BOOTFLOWIF_HUNT: Hunt for new bootdevs using the bootdrv hunters
+ * @BOOTFLOWIF_ONLY_BOOTABLE: Only consider partitions marked 'bootable'
  *
  * Internal flags:
  * @BOOTFLOWIF_SINGLE_DEV: (internal) Just scan one bootdev
@@ -177,6 +178,7 @@ enum bootflow_iter_flags_t {
 	BOOTFLOWIF_SHOW			= 1 << 1,
 	BOOTFLOWIF_ALL			= 1 << 2,
 	BOOTFLOWIF_HUNT			= 1 << 3,
+	BOOTFLOWIF_ONLY_BOOTABLE	= BIT(4),
 
 	/*
 	 * flags used internally by standard boot - do not set these when
diff --git a/test/boot/bootdev.c b/test/boot/bootdev.c
index 5f07430714e..d5499918249 100644
--- a/test/boot/bootdev.c
+++ b/test/boot/bootdev.c
@@ -509,6 +509,7 @@ static int bootdev_test_bootable(struct unit_test_state *uts)
 	iter.part = 0;
 	ut_assertok(uclass_get_device_by_name(UCLASS_BLK, "mmc1.blk", &blk));
 	iter.dev = blk;
+	iter.flags = BOOTFLOWIF_ONLY_BOOTABLE;
 	ut_assertok(device_find_next_child(&iter.dev));
 	uclass_first_device(UCLASS_BOOTMETH, &bflow.method);
 
diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c
index 49ef4d0c3ab..1447af2eb14 100644
--- a/test/boot/bootflow.c
+++ b/test/boot/bootflow.c
@@ -301,8 +301,9 @@ static int bootflow_iter(struct unit_test_state *uts)
 
 	/* The first device is mmc2.bootdev which has no media */
 	ut_asserteq(-EPROTONOSUPPORT,
-		    bootflow_scan_first(NULL, NULL, &iter,
-					BOOTFLOWIF_ALL | BOOTFLOWIF_SKIP_GLOBAL, &bflow));
+		    bootflow_scan_first(NULL, NULL, &iter, BOOTFLOWIF_ALL |
+					BOOTFLOWIF_SKIP_GLOBAL |
+					BOOTFLOWIF_ONLY_BOOTABLE, &bflow));
 	ut_asserteq(2, iter.num_methods);
 	ut_asserteq(0, iter.cur_method);
 	ut_asserteq(0, iter.part);
-- 
2.43.0



More information about the U-Boot mailing list