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>
This commit is contained in:
@@ -163,7 +163,15 @@ int bootdev_find_in_blk(struct udevice *dev, struct udevice *blk,
|
|||||||
*/
|
*/
|
||||||
iter->max_part = MAX_PART_PER_BOOTDEV;
|
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);
|
ret = fs_set_blk_dev_with_part(desc, bflow->part);
|
||||||
bflow->state = BOOTFLOWST_PART;
|
bflow->state = BOOTFLOWST_PART;
|
||||||
|
|
||||||
|
@@ -123,6 +123,7 @@ enum bootflow_flags_t {
|
|||||||
* @method: Current bootmeth
|
* @method: Current bootmeth
|
||||||
* @max_part: Maximum hardware partition number in @dev, 0 if there is no
|
* @max_part: Maximum hardware partition number in @dev, 0 if there is no
|
||||||
* partition table
|
* partition table
|
||||||
|
* @first_bootable: First bootable partition, or 0 if none
|
||||||
* @err: Error obtained from checking the last iteration. This is used to skip
|
* @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)
|
* forward (e.g. to skip the current partition because it is not valid)
|
||||||
* -ESHUTDOWN: try next bootdev
|
* -ESHUTDOWN: try next bootdev
|
||||||
@@ -144,6 +145,7 @@ struct bootflow_iter {
|
|||||||
int part;
|
int part;
|
||||||
struct udevice *method;
|
struct udevice *method;
|
||||||
int max_part;
|
int max_part;
|
||||||
|
int first_bootable;
|
||||||
int err;
|
int err;
|
||||||
int num_devs;
|
int num_devs;
|
||||||
int cur_dev;
|
int cur_dev;
|
||||||
|
@@ -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 |
|
BOOTSTD_TEST(bootdev_test_cmd_hunt, UT_TESTF_DM | UT_TESTF_SCAN_FDT |
|
||||||
UT_TESTF_ETH_BOOTDEV);
|
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);
|
||||||
|
@@ -316,14 +316,14 @@ static int bootflow_iter(struct unit_test_state *uts)
|
|||||||
bootflow_free(&bflow);
|
bootflow_free(&bflow);
|
||||||
|
|
||||||
/* Then more to partition 2 which exists but is not bootable */
|
/* 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(2, iter.num_methods);
|
||||||
ut_asserteq(0, iter.cur_method);
|
ut_asserteq(0, iter.cur_method);
|
||||||
ut_asserteq(2, iter.part);
|
ut_asserteq(2, iter.part);
|
||||||
ut_asserteq(0x1e, iter.max_part);
|
ut_asserteq(0x1e, iter.max_part);
|
||||||
ut_asserteq_str("syslinux", iter.method->name);
|
ut_asserteq_str("syslinux", iter.method->name);
|
||||||
ut_asserteq(0, bflow.err);
|
ut_asserteq(0, bflow.err);
|
||||||
ut_asserteq(BOOTFLOWST_PART, bflow.state);
|
ut_asserteq(BOOTFLOWST_MEDIA, bflow.state);
|
||||||
bootflow_free(&bflow);
|
bootflow_free(&bflow);
|
||||||
|
|
||||||
bootflow_iter_uninit(&iter);
|
bootflow_iter_uninit(&iter);
|
||||||
|
Reference in New Issue
Block a user