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(+)
@@ -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;
+}
@@ -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; }
@@ -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)