[Concept,07/16] part: Add a BLS target-partition check

Message ID 20260421183511.2044469-8-sjg@u-boot.org
State New
Headers
Series efi-x86: Boot Ubuntu live ISOs via U-Boot + BLS, end to end |

Commit Message

Simon Glass April 21, 2026, 6:34 p.m. UTC
  From: Simon Glass <sjg@chromium.org>

The Boot Loader Specification places Type #1 entries on the ESP, the
Extended Boot Loader Partition (XBOOTLDR), or an MBR type 0xea
partition. Discovery is by partition type only; the spec never mentions
the GPT or MBR 'bootable' flag.

Add a small helper that identifies those three cases so the bootflow
layer can scan them for loader/entry.conf regardless of bootable
attribute. Keep it in disk/part.c alongside part_get_bootable(), with a
trivial stub for !CONFIG_PARTITIONS builds.

Also add a sandbox unit test that exercises the helper with the three
partition type identifiers the spec calls out (ESP, XBOOTLDR and MBR
0xea), plus a few negative cases covering a common Linux partition
type and a stray Linux MBR sys_ind, and verifies that the GUID match
is case-insensitive.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 disk/part.c    | 21 +++++++++++++++++++++
 include/part.h | 17 +++++++++++++++++
 test/dm/part.c | 42 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 80 insertions(+)
  

Patch

diff --git a/disk/part.c b/disk/part.c
index 2ddbf50ee6c..e22dabc4090 100644
--- a/disk/part.c
+++ b/disk/part.c
@@ -882,3 +882,24 @@  int part_get_bootable(struct blk_desc *desc)
 
 	return 0;
 }
+
+bool part_is_bls_target(const struct disk_partition *info)
+{
+	if (IS_ENABLED(CONFIG_PARTITION_TYPE_GUID)) {
+		const char *guid = disk_partition_type_guid(info);
+
+		/* EFI System Partition */
+		if (!strcasecmp(guid, "c12a7328-f81f-11d2-ba4b-00a0c93ec93b"))
+			return true;
+		/* Extended Boot Loader Partition (XBOOTLDR) */
+		if (!strcasecmp(guid, "bc13c2ff-59e6-4262-a352-b275fd6f7172"))
+			return true;
+	}
+
+	/* MBR/DOS disks: BLS uses partition type 0xea */
+	if (IS_ENABLED(CONFIG_DOS_PARTITION) &&
+	    disk_partition_sys_ind(info) == 0xea)
+		return true;
+
+	return false;
+}
diff --git a/include/part.h b/include/part.h
index 6c9558e2c71..3ecf6d8e165 100644
--- a/include/part.h
+++ b/include/part.h
@@ -755,6 +755,20 @@  int part_get_type_by_name(const char *name);
  */
 int part_get_bootable(struct blk_desc *desc);
 
+/**
+ * part_is_bls_target() - Check whether a partition holds BLS boot entries
+ *
+ * The Boot Loader Specification defines two GPT partition types as homes
+ * for Type #1 entries (the ESP and the Extended Boot Loader Partition) and
+ * one MBR type ID (0xea). This helper returns true when @info names one of
+ * them, so the caller can scan the partition for loader/entries/<name>.conf
+ * (or loader/entry.conf) regardless of any 'bootable' flag.
+ *
+ * @info:	Partition information
+ * Return:	true if the partition is an ESP, XBOOTLDR or MBR-0xea partition
+ */
+bool part_is_bls_target(const struct disk_partition *info);
+
 /**
  * part_driver_lookup_type() - Look up the partition driver for a blk device
  *
@@ -783,6 +797,9 @@  static inline struct part_driver *part_driver_get_first(void)
 static inline bool part_get_bootable(struct blk_desc *desc)
 { return false; }
 
+static inline bool part_is_bls_target(const struct disk_partition *info)
+{ return false; }
+
 static inline struct part_driver *part_driver_lookup_type(struct blk_desc *desc)
 { return NULL; }
 
diff --git a/test/dm/part.c b/test/dm/part.c
index caae23bd4aa..02f36c0803a 100644
--- a/test/dm/part.c
+++ b/test/dm/part.c
@@ -109,6 +109,48 @@  static int dm_test_part_bootable(struct unit_test_state *uts)
 }
 DM_TEST(dm_test_part_bootable, UTF_SCAN_FDT);
 
+static int dm_test_part_is_bls_target(struct unit_test_state *uts)
+{
+	struct disk_partition info;
+
+	/* GPT: ESP type GUID */
+	memset(&info, '\0', sizeof(info));
+	disk_partition_set_type_guid(&info,
+				     "c12a7328-f81f-11d2-ba4b-00a0c93ec93b");
+	ut_asserteq(true, part_is_bls_target(&info));
+
+	/* GPT: XBOOTLDR type GUID */
+	memset(&info, '\0', sizeof(info));
+	disk_partition_set_type_guid(&info,
+				     "bc13c2ff-59e6-4262-a352-b275fd6f7172");
+	ut_asserteq(true, part_is_bls_target(&info));
+
+	/* GPT: GUID match must be case-insensitive */
+	memset(&info, '\0', sizeof(info));
+	disk_partition_set_type_guid(&info,
+				     "c12a7328-f81f-11d2-ba4b-00a0c93ec93b");
+	ut_asserteq(true, part_is_bls_target(&info));
+
+	/* GPT: a Linux filesystem partition is not a BLS target */
+	memset(&info, '\0', sizeof(info));
+	disk_partition_set_type_guid(&info,
+				     "0fc63daf-8483-4772-8e79-3d69d8477de4");
+	ut_asserteq(false, part_is_bls_target(&info));
+
+	/* MBR: BLS partition type 0xea */
+	memset(&info, '\0', sizeof(info));
+	info.sys_ind = 0xea;
+	ut_asserteq(true, part_is_bls_target(&info));
+
+	/* MBR: a Linux partition (0x83) is not a BLS target */
+	memset(&info, '\0', sizeof(info));
+	info.sys_ind = 0x83;
+	ut_asserteq(false, part_is_bls_target(&info));
+
+	return 0;
+}
+DM_TEST(dm_test_part_is_bls_target, 0);
+
 static int do_get_info_test(struct unit_test_state *uts,
 			    struct blk_desc *dev_desc, int part, int part_type,
 			    struct disk_partition const *reference)