[PATCH 3/3] efi_loader: disk: add EFI_PARTITION_INFO_PROTOCOL support
Javier Martinez Canillas
javierm at redhat.com
Fri Jun 13 10:57:38 CEST 2025
The UEFI 2.10 specification mentions that this protocol shall be installed
along with EFI_BLOCK_IO_PROTOCOL. It provides cached partition information
for MBR and GPT partition types.
This patch just implements support for GPT partition types. The legacy MBR
partition types is only needed for backward compatibility and can be added
as a follow-up if needed, to make it fully compliant with the EFI spec.
Signed-off-by: Javier Martinez Canillas <javierm at redhat.com>
---
include/part_efi.h | 20 ++++++++++++++++++++
lib/efi_loader/efi_disk.c | 38 ++++++++++++++++++++++++++++++++++++--
2 files changed, 56 insertions(+), 2 deletions(-)
diff --git a/include/part_efi.h b/include/part_efi.h
index 59b7895b8a23..fb402df6f13e 100644
--- a/include/part_efi.h
+++ b/include/part_efi.h
@@ -138,4 +138,24 @@ typedef struct _legacy_mbr {
__le16 signature;
} __packed legacy_mbr;
+#define EFI_PARTITION_INFO_PROTOCOL_GUID \
+ EFI_GUID(0x8cf2f62c, 0xbc9b, 0x4821, 0x80, \
+ 0x8d, 0xec, 0x9e, 0xc4, 0x21, 0xa1, 0xa0)
+
+#define EFI_PARTITION_INFO_PROTOCOL_REVISION 0x0001000
+#define PARTITION_TYPE_OTHER 0x00
+#define PARTITION_TYPE_MBR 0x01
+#define PARTITION_TYPE_GPT 0x02
+
+struct efi_partition_info {
+ u32 revision;
+ u32 type;
+ u8 system;
+ u8 reserved[7];
+ union {
+ struct partition mbr;
+ gpt_entry gpt;
+ } info;
+} __packed;
+
#endif /* _DISK_PART_EFI_H */
diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c
index 47b583cc5e12..ba41b77b9d1c 100644
--- a/lib/efi_loader/efi_disk.c
+++ b/lib/efi_loader/efi_disk.c
@@ -26,6 +26,7 @@ struct efi_system_partition efi_system_partition = {
const efi_guid_t efi_block_io_guid = EFI_BLOCK_IO_PROTOCOL_GUID;
const efi_guid_t efi_system_partition_guid = PARTITION_SYSTEM_GUID;
+const efi_guid_t efi_partition_info_guid = EFI_PARTITION_INFO_PROTOCOL_GUID;
/**
* struct efi_disk_obj - EFI disk object
@@ -35,6 +36,7 @@ const efi_guid_t efi_system_partition_guid = PARTITION_SYSTEM_GUID;
* @media: block I/O media information
* @dp: device path to the block device
* @volume: simple file system protocol of the partition
+ * @info: EFI partition info protocol interface
*/
struct efi_disk_obj {
struct efi_object header;
@@ -42,6 +44,7 @@ struct efi_disk_obj {
struct efi_block_io_media media;
struct efi_device_path *dp;
struct efi_simple_file_system_protocol *volume;
+ struct efi_partition_info info;
};
/**
@@ -426,6 +429,7 @@ static efi_status_t efi_disk_add_dev(
/* Fill in object data */
if (part_info) {
struct efi_device_path *node = efi_dp_part_node(desc, part);
+ struct efi_partition_info *info = &diskobj->info;
struct efi_handler *handler;
void *protocol_interface;
@@ -454,18 +458,47 @@ static efi_status_t efi_disk_add_dev(
goto error;
}
+ info->revision = EFI_PARTITION_INFO_PROTOCOL_REVISION;
+
+ switch (desc->part_type) {
+ case PART_TYPE_EFI:
+ info->type = PARTITION_TYPE_GPT;
+ ret = part_get_gpt_pte(desc, part, &info->info.gpt);
+ if (ret) {
+ log_debug("get PTE for part %d failed %ld\n",
+ part, ret);
+ goto error;
+ }
+
+ break;
+ case PART_TYPE_DOS:
+ info->type = PARTITION_TYPE_MBR;
+
+ /* TODO: implement support for MBR partition types */
+ log_debug("EFI_PARTITION_INFO_PROTOCOL doesn't support MBR\n");
+
+ break;
+ default:
+ info->type = PARTITION_TYPE_OTHER;
+
+ break;
+ }
+
diskobj->dp = efi_dp_append_node(dp_parent, node);
efi_free_pool(node);
diskobj->media.last_block = part_info->size - 1;
- if (part_info->bootable & PART_EFI_SYSTEM_PARTITION)
+ if (part_info->bootable & PART_EFI_SYSTEM_PARTITION) {
esp_guid = &efi_system_partition_guid;
+ info->system = 1;
+ }
+
} else {
diskobj->dp = efi_dp_from_part(desc, part);
diskobj->media.last_block = desc->lba - 1;
}
/*
- * Install the device path and the block IO protocol.
+ * Install the device path, the block IO and partition info protocols.
*
* InstallMultipleProtocolInterfaces() checks if the device path is
* already installed on an other handle and returns EFI_ALREADY_STARTED
@@ -476,6 +509,7 @@ static efi_status_t efi_disk_add_dev(
&handle,
&efi_guid_device_path, diskobj->dp,
&efi_block_io_guid, &diskobj->ops,
+ &efi_partition_info_guid, &diskobj->info,
/*
* esp_guid must be last entry as it
* can be NULL. Its interface is NULL.
--
2.49.0
More information about the U-Boot
mailing list