bootstd: support scanning a single partition

The "bootflow" command currently doesn't support scanning a single
partition. This is inconvenient in setups with multiple bootable
partitions within a single disk, but only one is desired.

Support scanning a single disk partition. Specifically, support the
syntax:
	bootflow scan mmc1:4
which scans only mmc device 1, partition 4.

Signed-off-by: Nam Cao <namcao@linutronix.de>
This commit is contained in:
Nam Cao 2024-02-21 13:41:44 +01:00 committed by Tom Rini
parent c15d73d189
commit 1132471405
4 changed files with 43 additions and 2 deletions

View file

@ -172,8 +172,10 @@ 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 this is the whole disk, check if we have bootable partitions */ if (iter->flags & BOOTFLOWIF_SINGLE_PARTITION) {
if (!iter->part) { /* a particular partition was specified, scan it without checking */
} else if (!iter->part) {
/* This is the whole disk, check if we have bootable partitions */
iter->first_bootable = part_get_bootable(desc); iter->first_bootable = part_get_bootable(desc);
log_debug("checking bootable=%d\n", iter->first_bootable); log_debug("checking bootable=%d\n", iter->first_bootable);
} else if (allow_any_part) { } else if (allow_any_part) {
@ -710,8 +712,37 @@ int bootdev_setup_iter(struct bootflow_iter *iter, const char *label,
struct udevice *bootstd, *dev = NULL; struct udevice *bootstd, *dev = NULL;
bool show = iter->flags & BOOTFLOWIF_SHOW; bool show = iter->flags & BOOTFLOWIF_SHOW;
int method_flags; int method_flags;
char buf[32];
int ret; int ret;
if (label) {
const char *end = strchr(label, ':');
if (end) {
size_t len = (size_t)(end - label);
const char *part = end + 1;
if (len + 1 > sizeof(buf)) {
log_err("label \"%s\" is way too long\n", label);
return -EINVAL;
}
memcpy(buf, label, len);
buf[len] = '\0';
label = buf;
unsigned long tmp;
if (strict_strtoul(part, 0, &tmp)) {
log_err("Invalid partition number: %s\n", part);
return -EINVAL;
}
iter->flags |= BOOTFLOWIF_SINGLE_PARTITION;
iter->part = tmp;
}
}
ret = uclass_first_device_err(UCLASS_BOOTSTD, &bootstd); ret = uclass_first_device_err(UCLASS_BOOTSTD, &bootstd);
if (ret) { if (ret) {
log_err("Missing bootstd device\n"); log_err("Missing bootstd device\n");

View file

@ -217,6 +217,9 @@ static int iter_incr(struct bootflow_iter *iter)
} }
} }
if (iter->flags & BOOTFLOWIF_SINGLE_PARTITION)
return BF_NO_MORE_DEVICES;
/* No more bootmeths; start at the first one, and... */ /* No more bootmeths; start at the first one, and... */
iter->cur_method = 0; iter->cur_method = 0;
iter->method = iter->method_order[iter->cur_method]; iter->method = iter->method_order[iter->cur_method];

View file

@ -531,6 +531,10 @@ Then the iterator is set up to according to the parameters given:
`BOOTFLOWIF_SINGLE_MEDIA` is set. In this case, moving to the next bootdev `BOOTFLOWIF_SINGLE_MEDIA` is set. In this case, moving to the next bootdev
processes just the children of the media device. Hunters are used, in this processes just the children of the media device. Hunters are used, in this
example just the "mmc" hunter. example just the "mmc" hunter.
- If `label` indicates a particular partition in a particular media device
(e.g. "mmc1:3") then `BOOTFLOWIF_SINGLE_PARTITION` is set. In this case,
only a single partition within a bootdev is processed. Hunters are used, in
this example just the "mmc" hunter.
- If `label` indicates a media uclass (e.g. "mmc") then - If `label` indicates a media uclass (e.g. "mmc") then
`BOOTFLOWIF_SINGLE_UCLASS` is set. In this case, all bootdevs in that uclass `BOOTFLOWIF_SINGLE_UCLASS` is set. In this case, all bootdevs in that uclass
are used. Hunters are used, in this example just the "mmc" hunter are used. Hunters are used, in this example just the "mmc" hunter

View file

@ -133,6 +133,8 @@ struct bootflow {
* this uclass (used with things like "mmc") * this uclass (used with things like "mmc")
* @BOOTFLOWIF_SINGLE_MEDIA: (internal) Scan one media device in the uclass (used * @BOOTFLOWIF_SINGLE_MEDIA: (internal) Scan one media device in the uclass (used
* with things like "mmc1") * with things like "mmc1")
* @BOOTFLOWIF_SINGLE_PARTITION: (internal) Scan one partition in media device
* (used with things like "mmc1:3")
*/ */
enum bootflow_iter_flags_t { enum bootflow_iter_flags_t {
BOOTFLOWIF_FIXED = 1 << 0, BOOTFLOWIF_FIXED = 1 << 0,
@ -148,6 +150,7 @@ enum bootflow_iter_flags_t {
BOOTFLOWIF_SKIP_GLOBAL = 1 << 17, BOOTFLOWIF_SKIP_GLOBAL = 1 << 17,
BOOTFLOWIF_SINGLE_UCLASS = 1 << 18, BOOTFLOWIF_SINGLE_UCLASS = 1 << 18,
BOOTFLOWIF_SINGLE_MEDIA = 1 << 19, BOOTFLOWIF_SINGLE_MEDIA = 1 << 19,
BOOTFLOWIF_SINGLE_PARTITION = 1 << 20,
}; };
/** /**