diff options
author | Simon Glass <sjg@chromium.org> | 2023-01-17 10:47:42 -0700 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2023-01-23 18:11:40 -0500 |
commit | f0e358f07d75579b40eff8f723b280ab5d53d338 (patch) | |
tree | dd22560415627197881a374a11b4d55f4fff5af2 | |
parent | dcffa4428d0359fd09348fc05cf5b5ce2db38c5f (diff) | |
download | u-boot-f0e358f07d75579b40eff8f723b280ab5d53d338.tar.gz |
bootstd: Only scan bootable partitions
At present all partitions are scanned, whether marked bootable or not.
Use only bootable partitions, defaulting to partition 1 if none is
found.
Signed-off-by: Simon Glass <sjg@chromium.org>
-rw-r--r-- | boot/bootdev-uclass.c | 10 | ||||
-rw-r--r-- | include/bootflow.h | 2 | ||||
-rw-r--r-- | test/boot/bootdev.c | 37 | ||||
-rw-r--r-- | test/boot/bootflow.c | 4 |
4 files changed, 50 insertions, 3 deletions
diff --git a/boot/bootdev-uclass.c b/boot/bootdev-uclass.c index 081b94ce33..3dcf317c15 100644 --- a/boot/bootdev-uclass.c +++ b/boot/bootdev-uclass.c @@ -163,7 +163,15 @@ int bootdev_find_in_blk(struct udevice *dev, struct udevice *blk, */ iter->max_part = MAX_PART_PER_BOOTDEV; - if (iter->part) { + /* If this is the whole disk, check if we have bootable partitions */ + if (!iter->part) { + iter->first_bootable = part_get_bootable(desc); + log_debug("checking bootable=%d\n", iter->first_bootable); + + /* if there are bootable partitions, scan only those */ + } else if (iter->first_bootable ? !info.bootable : iter->part != 1) { + return log_msg_ret("boot", -EINVAL); + } else { ret = fs_set_blk_dev_with_part(desc, bflow->part); bflow->state = BOOTFLOWST_PART; diff --git a/include/bootflow.h b/include/bootflow.h index c201246c6d..3a93e4b5ca 100644 --- a/include/bootflow.h +++ b/include/bootflow.h @@ -123,6 +123,7 @@ enum bootflow_flags_t { * @method: Current bootmeth * @max_part: Maximum hardware partition number in @dev, 0 if there is no * partition table + * @first_bootable: First bootable partition, or 0 if none * @err: Error obtained from checking the last iteration. This is used to skip * forward (e.g. to skip the current partition because it is not valid) * -ESHUTDOWN: try next bootdev @@ -144,6 +145,7 @@ struct bootflow_iter { int part; struct udevice *method; int max_part; + int first_bootable; int err; int num_devs; int cur_dev; diff --git a/test/boot/bootdev.c b/test/boot/bootdev.c index 32a31c4460..db0e0ca20f 100644 --- a/test/boot/bootdev.c +++ b/test/boot/bootdev.c @@ -301,3 +301,40 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts) } BOOTSTD_TEST(bootdev_test_cmd_hunt, UT_TESTF_DM | UT_TESTF_SCAN_FDT | UT_TESTF_ETH_BOOTDEV); + +/* Check that only bootable partitions are processed */ +static int bootdev_test_bootable(struct unit_test_state *uts) +{ + struct bootflow_iter iter; + struct bootflow bflow; + struct udevice *blk; + + memset(&iter, '\0', sizeof(iter)); + memset(&bflow, '\0', sizeof(bflow)); + iter.part = 0; + ut_assertok(uclass_get_device_by_name(UCLASS_BLK, "mmc1.blk", &blk)); + iter.dev = blk; + ut_assertok(device_find_next_child(&iter.dev)); + uclass_first_device(UCLASS_BOOTMETH, &bflow.method); + + /* + * initially we don't have any knowledge of which partitions are + * bootable, but mmc1 has two partitions, with the first one being + * bootable + */ + iter.part = 2; + ut_asserteq(-EINVAL, bootdev_find_in_blk(iter.dev, blk, &iter, &bflow)); + ut_asserteq(0, iter.first_bootable); + + /* scan with part == 0 to get the partition info */ + iter.part = 0; + ut_asserteq(-ENOENT, bootdev_find_in_blk(iter.dev, blk, &iter, &bflow)); + ut_asserteq(1, iter.first_bootable); + + /* now it will refuse to use non-bootable partitions */ + iter.part = 2; + ut_asserteq(-EINVAL, bootdev_find_in_blk(iter.dev, blk, &iter, &bflow)); + + return 0; +} +BOOTSTD_TEST(bootdev_test_bootable, UT_TESTF_DM | UT_TESTF_SCAN_FDT); diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c index 38ffe8fa9b..f852b6e9b6 100644 --- a/test/boot/bootflow.c +++ b/test/boot/bootflow.c @@ -316,14 +316,14 @@ static int bootflow_iter(struct unit_test_state *uts) bootflow_free(&bflow); /* Then more to partition 2 which exists but is not bootable */ - ut_asserteq(-EPERM, bootflow_scan_next(&iter, &bflow)); + ut_asserteq(-EINVAL, bootflow_scan_next(&iter, &bflow)); ut_asserteq(2, iter.num_methods); ut_asserteq(0, iter.cur_method); ut_asserteq(2, iter.part); ut_asserteq(0x1e, iter.max_part); ut_asserteq_str("syslinux", iter.method->name); ut_asserteq(0, bflow.err); - ut_asserteq(BOOTFLOWST_PART, bflow.state); + ut_asserteq(BOOTFLOWST_MEDIA, bflow.state); bootflow_free(&bflow); bootflow_iter_uninit(&iter); |