boot: Consider non-bootable partitions

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 the existing behaviour of
bootstd which is to ignore non-bootable partitions so long as there is
at least one bootable partition on the disk.  Future work may provide a
command (or some other mechanism) to control this.

Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Simon Glass 2025-03-15 14:25:58 +00:00 committed by Tom Rini
parent 8d6097d300
commit 6acb0d28b0
6 changed files with 13 additions and 6 deletions

View file

@ -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);

View file

@ -173,7 +173,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)

View file

@ -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

View file

@ -160,6 +160,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
@ -176,6 +177,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

View file

@ -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);

View file

@ -297,8 +297,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);