[PATCH 021/112] partitions: have parsers record bootable bits

Ahmad Fatoum a.fatoum at pengutronix.de
Wed Jan 3 10:11:41 PST 2024


barebox as EFI loader can use the information about which partitions are
bootable to guide its decision. Record this information.

Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
 common/partitions.c        |  4 ++--
 common/partitions/dos.c    | 10 ++++++++++
 common/partitions/efi.c    | 18 ++++++++++++++++++
 common/partitions/parser.h |  3 +++
 include/driver.h           |  5 +++++
 include/efi/partition.h    |  6 ++++--
 6 files changed, 42 insertions(+), 4 deletions(-)

diff --git a/common/partitions.c b/common/partitions.c
index 8a245a1eee3d..53001a64770f 100644
--- a/common/partitions.c
+++ b/common/partitions.c
@@ -52,8 +52,8 @@ static int register_one_partition(struct block_device *blk,
 		goto out;
 	}
 
-	cdev->flags |= DEVFS_PARTITION_FROM_TABLE;
-
+	cdev->flags |= DEVFS_PARTITION_FROM_TABLE | part->flags;
+	cdev->typeflags |= part->typeflags;
 	cdev->typeuuid = part->typeuuid;
 	strcpy(cdev->partuuid, part->partuuid);
 
diff --git a/common/partitions/dos.c b/common/partitions/dos.c
index 7472824b00b9..bf37b2852b9e 100644
--- a/common/partitions/dos.c
+++ b/common/partitions/dos.c
@@ -163,6 +163,15 @@ static void dos_extended_partition(struct block_device *blk, struct partition_de
 	return;
 }
 
+static void extract_flags(const struct partition_entry *p,
+			  struct partition *pentry)
+{
+	if (p->boot_indicator == 0x80)
+		pentry->flags |= DEVFS_PARTITION_BOOTABLE_LEGACY;
+	if (p->type == 0xef)
+		pentry->flags |= DEVFS_PARTITION_BOOTABLE_ESP;
+}
+
 /**
  * Check if a DOS like partition describes this block device
  * @param blk Block device to register to
@@ -199,6 +208,7 @@ static void dos_partition(void *buf, struct block_device *blk,
 			pd->parts[n].first_sec = pentry.first_sec;
 			pd->parts[n].size = pentry.size;
 			pd->parts[n].dos_partition_type = pentry.dos_partition_type;
+			extract_flags(&table[i], &pd->parts[n]);
 			if (signature)
 				sprintf(pd->parts[n].partuuid, "%08x-%02d",
 						signature, i + 1);
diff --git a/common/partitions/efi.c b/common/partitions/efi.c
index 0add66e6e4a6..6260702577f9 100644
--- a/common/partitions/efi.c
+++ b/common/partitions/efi.c
@@ -431,6 +431,23 @@ static void part_set_efi_name(gpt_entry *pte, char *dest)
 	dest[i] = 0;
 }
 
+static void extract_flags(const gpt_entry *p, struct partition *pentry)
+{
+	static const guid_t system_guid = PARTITION_SYSTEM_GUID;
+
+	if (p->attributes.required_to_function)
+		pentry->flags |= DEVFS_PARTITION_REQUIRED;
+	if (p->attributes.no_block_io_protocol)
+		pentry->flags |= DEVFS_PARTITION_NO_EXPORT;
+	if (p->attributes.legacy_bios_bootable)
+		pentry->flags |= DEVFS_PARTITION_BOOTABLE_LEGACY;
+
+	if (guid_equal(&p->partition_type_guid, &system_guid))
+		pentry->flags |=  DEVFS_PARTITION_BOOTABLE_ESP;
+
+	pentry->typeflags = p->attributes.type_guid_specific;
+}
+
 static void efi_partition(void *buf, struct block_device *blk,
 			  struct partition_desc *pd)
 {
@@ -466,6 +483,7 @@ static void efi_partition(void *buf, struct block_device *blk,
 		}
 
 		pentry = &pd->parts[pd->used_entries];
+		extract_flags(&ptes[i], pentry);
 		pentry->first_sec = le64_to_cpu(ptes[i].starting_lba);
 		pentry->size = le64_to_cpu(ptes[i].ending_lba) - pentry->first_sec;
 		pentry->size++;
diff --git a/common/partitions/parser.h b/common/partitions/parser.h
index 9cc41a7573fe..fce368156400 100644
--- a/common/partitions/parser.h
+++ b/common/partitions/parser.h
@@ -11,6 +11,7 @@
 #include <filetype.h>
 #include <linux/uuid.h>
 #include <linux/list.h>
+#include <driver.h>
 
 #define MAX_PARTITION		128
 #define MAX_PARTITION_NAME	38
@@ -24,6 +25,8 @@ struct partition {
 		u8 dos_partition_type;
 		guid_t typeuuid;
 	};
+	unsigned int flags;
+	unsigned int typeflags;
 };
 
 struct partition_desc {
diff --git a/include/driver.h b/include/driver.h
index c6da5a3d0d54..b6fe8712837b 100644
--- a/include/driver.h
+++ b/include/driver.h
@@ -543,6 +543,7 @@ struct cdev {
 	loff_t offset;
 	loff_t size;
 	unsigned int flags;
+	u16 typeflags; /* GPT type-specific attributes */
 	int open;
 	struct mtd_info *mtd;
 	struct cdev *link;
@@ -615,6 +616,10 @@ extern struct list_head cdev_list;
 #define DEVFS_PARTITION_FROM_TABLE	(1U << 6)
 #define DEVFS_IS_MBR_PARTITIONED	(1U << 7)
 #define DEVFS_IS_GPT_PARTITIONED	(1U << 8)
+#define DEVFS_PARTITION_REQUIRED	(1U << 9)
+#define DEVFS_PARTITION_NO_EXPORT	(1U << 10)
+#define DEVFS_PARTITION_BOOTABLE_LEGACY	(1U << 11)
+#define DEVFS_PARTITION_BOOTABLE_ESP	(1U << 12)
 
 static inline bool cdev_is_mbr_partitioned(const struct cdev *master)
 {
diff --git a/include/efi/partition.h b/include/efi/partition.h
index 0ca2a72eb9b7..29175673e351 100644
--- a/include/efi/partition.h
+++ b/include/efi/partition.h
@@ -95,8 +95,10 @@ typedef struct _gpt_header {
 
 typedef struct _gpt_entry_attributes {
 	u64 required_to_function:1;
-	u64 reserved:47;
-        u64 type_guid_specific:16;
+	u64 no_block_io_protocol:1;
+	u64 legacy_bios_bootable:1;
+	u64 reserved:45;
+	u64 type_guid_specific:16;
 } __attribute__ ((packed)) gpt_entry_attributes;
 
 #define GPT_PARTNAME_MAX_SIZE	(72 / sizeof (wchar_t))
-- 
2.39.2




More information about the barebox mailing list