[PATCH v2 3/4] efi_loader: disk: add EFI_PARTITION_INFO_PROTOCOL support

Ilias Apalodimas ilias.apalodimas at linaro.org
Wed Jun 18 10:54:40 CEST 2025


On Wed, 18 Jun 2025 at 11:06, Javier Martinez Canillas
<javierm at redhat.com> wrote:
>
> 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>

Reviewed-by: Ilias Apalodimas <ilias.apalodimas at linaro.org>

> ---
>
> (no changes since v1)
>
>  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