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:
@@ -168,8 +168,10 @@ int bootdev_find_in_blk(struct udevice *dev, struct udevice *blk,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* if there are bootable partitions, scan only those */
|
/* 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)) {
|
(iter->first_bootable ? !info.bootable : iter->part != 1)) {
|
||||||
|
log_debug("Skipping non-bootable partition %d\n", iter->part);
|
||||||
return log_msg_ret("boot", -EINVAL);
|
return log_msg_ret("boot", -EINVAL);
|
||||||
} else {
|
} else {
|
||||||
ret = fs_set_blk_dev_with_part(desc, bflow->part);
|
ret = fs_set_blk_dev_with_part(desc, bflow->part);
|
||||||
|
@@ -173,7 +173,7 @@ static int do_bootflow_scan(struct cmd_tbl *cmdtp, int flag, int argc,
|
|||||||
|
|
||||||
std->cur_bootflow = NULL;
|
std->cur_bootflow = NULL;
|
||||||
|
|
||||||
flags = 0;
|
flags = BOOTFLOWIF_ONLY_BOOTABLE;
|
||||||
if (list)
|
if (list)
|
||||||
flags |= BOOTFLOWIF_SHOW;
|
flags |= BOOTFLOWIF_SHOW;
|
||||||
if (all)
|
if (all)
|
||||||
|
@@ -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
|
block device and calls a bootdev helper function to do the rest. The
|
||||||
implementation of `bootdev_find_in_blk()` checks the partition table, and
|
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
|
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,
|
`@iter->part` parameter. If there are any bootable partitions in the table and
|
||||||
then only bootable partitions are considered.
|
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,
|
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
|
if `boot_targets` is not used. Faster bootdevs are used first, since they are
|
||||||
|
@@ -160,6 +160,7 @@ struct bootflow_img {
|
|||||||
* before using it
|
* before using it
|
||||||
* @BOOTFLOWIF_ALL: Return bootflows with errors as well
|
* @BOOTFLOWIF_ALL: Return bootflows with errors as well
|
||||||
* @BOOTFLOWIF_HUNT: Hunt for new bootdevs using the bootdrv hunters
|
* @BOOTFLOWIF_HUNT: Hunt for new bootdevs using the bootdrv hunters
|
||||||
|
* @BOOTFLOWIF_ONLY_BOOTABLE: Only consider partitions marked 'bootable'
|
||||||
*
|
*
|
||||||
* Internal flags:
|
* Internal flags:
|
||||||
* @BOOTFLOWIF_SINGLE_DEV: (internal) Just scan one bootdev
|
* @BOOTFLOWIF_SINGLE_DEV: (internal) Just scan one bootdev
|
||||||
@@ -176,6 +177,7 @@ enum bootflow_iter_flags_t {
|
|||||||
BOOTFLOWIF_SHOW = 1 << 1,
|
BOOTFLOWIF_SHOW = 1 << 1,
|
||||||
BOOTFLOWIF_ALL = 1 << 2,
|
BOOTFLOWIF_ALL = 1 << 2,
|
||||||
BOOTFLOWIF_HUNT = 1 << 3,
|
BOOTFLOWIF_HUNT = 1 << 3,
|
||||||
|
BOOTFLOWIF_ONLY_BOOTABLE = BIT(4),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* flags used internally by standard boot - do not set these when
|
* flags used internally by standard boot - do not set these when
|
||||||
|
@@ -509,6 +509,7 @@ static int bootdev_test_bootable(struct unit_test_state *uts)
|
|||||||
iter.part = 0;
|
iter.part = 0;
|
||||||
ut_assertok(uclass_get_device_by_name(UCLASS_BLK, "mmc1.blk", &blk));
|
ut_assertok(uclass_get_device_by_name(UCLASS_BLK, "mmc1.blk", &blk));
|
||||||
iter.dev = blk;
|
iter.dev = blk;
|
||||||
|
iter.flags = BOOTFLOWIF_ONLY_BOOTABLE;
|
||||||
ut_assertok(device_find_next_child(&iter.dev));
|
ut_assertok(device_find_next_child(&iter.dev));
|
||||||
uclass_first_device(UCLASS_BOOTMETH, &bflow.method);
|
uclass_first_device(UCLASS_BOOTMETH, &bflow.method);
|
||||||
|
|
||||||
|
@@ -297,8 +297,9 @@ static int bootflow_iter(struct unit_test_state *uts)
|
|||||||
|
|
||||||
/* The first device is mmc2.bootdev which has no media */
|
/* The first device is mmc2.bootdev which has no media */
|
||||||
ut_asserteq(-EPROTONOSUPPORT,
|
ut_asserteq(-EPROTONOSUPPORT,
|
||||||
bootflow_scan_first(NULL, NULL, &iter,
|
bootflow_scan_first(NULL, NULL, &iter, BOOTFLOWIF_ALL |
|
||||||
BOOTFLOWIF_ALL | BOOTFLOWIF_SKIP_GLOBAL, &bflow));
|
BOOTFLOWIF_SKIP_GLOBAL |
|
||||||
|
BOOTFLOWIF_ONLY_BOOTABLE, &bflow));
|
||||||
ut_asserteq(2, iter.num_methods);
|
ut_asserteq(2, iter.num_methods);
|
||||||
ut_asserteq(0, iter.cur_method);
|
ut_asserteq(0, iter.cur_method);
|
||||||
ut_asserteq(0, iter.part);
|
ut_asserteq(0, iter.part);
|
||||||
|
Reference in New Issue
Block a user