bootstd: add IGNORE_BOOTABLE option
Qualcomm devices have a ridiculous number of partitions (up in the
triple digits on modern devices) and often have random partitions with
the bootable flag set. However, there is usually not a dedicated ESP
partition, instead some partition has to be repurposed. To support this
usecase, add a new CONFIG_IGNORE_BOOTABLE option which disables the
optimisation added in f0e358f07d75 ("bootstd: Only scan bootable
partitions) and always scans all partitions.
Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
diff --git a/boot/Kconfig b/boot/Kconfig
index fbc49c5..850a9dc 100644
--- a/boot/Kconfig
+++ b/boot/Kconfig
@@ -452,6 +452,14 @@
standard boot does not support all of the features of distro boot
yet.
+config BOOTSTD_IGNORE_BOOTABLE
+ bool "Don't rely on the bootable flag when scanning bootflows"
+ help
+ Enable this to avoid relying on the bootable partition flag. On some
+ devices with complicated partition tables this flag may be set by mistake
+ resulting in bootflows not being recognised. Set this to always scan all
+ partitions.
+
config BOOTMETH_GLOBAL
bool
help
diff --git a/boot/bootdev-uclass.c b/boot/bootdev-uclass.c
index 44ae98a..d01d603 100644
--- a/boot/bootdev-uclass.c
+++ b/boot/bootdev-uclass.c
@@ -27,7 +27,7 @@
* have. Note that for disks this limits the partitions numbers that
* are scanned to 1..MAX_BOOTFLOWS_PER_BOOTDEV
*/
- MAX_PART_PER_BOOTDEV = 30,
+ MAX_PART_PER_BOOTDEV = 96,
/* Maximum supported length of the "boot_targets" env string */
BOOT_TARGETS_MAX_LEN = 100,
@@ -173,21 +173,25 @@
*/
iter->max_part = MAX_PART_PER_BOOTDEV;
- /* 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);
- } else if (allow_any_part) {
- /*
- * allow any partition to be scanned, by skipping any checks
- * for filesystems or partition contents on this disk
- */
+ if (!IS_ENABLED(CONFIG_BOOTSTD_IGNORE_BOOTABLE)) {
+ /* 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);
+ } else if (allow_any_part) {
+ /*
+ * allow any partition to be scanned, by skipping any checks
+ * for filesystems or partition contents on this disk
+ */
- /* if there are bootable partitions, scan only those */
- } else if (iter->first_bootable >= 0 &&
- (iter->first_bootable ? !info.bootable : iter->part != 1)) {
- return log_msg_ret("boot", -EINVAL);
- } else {
+ /* if there are bootable partitions, scan only those */
+ } else if (iter->first_bootable >= 0 &&
+ (iter->first_bootable ? !info.bootable : iter->part != 1)) {
+ return log_msg_ret("boot", -EINVAL);
+ }
+ }
+
+ if (iter->part) {
ret = fs_set_blk_dev_with_part(desc, bflow->part);
bflow->state = BOOTFLOWST_PART;
if (ret)