[PATCH] efi_loader: improve detection of ESP for storing UEFI variables
Paulo Alcantara
pc at cjr.nz
Mon Nov 9 00:58:55 CET 2020
The UEFI specification does not restrict on the number and location of
ESPs in a system. They are discovered as required by looking at the
partition type, but firmware implementations are allowed to support
ESPs which do not contain a valid partition type.
Besides checking for the partition type, for non-removable media check
if /EFI directory exists, otherwise check if /EFI/BOOT/BOOT{ARCH}.EFI
file exists as specified in UEFI 2.8 "13.3.1.3 Directory Structure".
Signed-off-by: Paulo Alcantara (SUSE) <pc at cjr.nz>
---
lib/efi_loader/efi_disk.c | 60 +++++++++++++++++++++++++--------------
1 file changed, 38 insertions(+), 22 deletions(-)
diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c
index 7bd1ccec4501..2940a2edf2e8 100644
--- a/lib/efi_loader/efi_disk.c
+++ b/lib/efi_loader/efi_disk.c
@@ -335,6 +335,35 @@ static int efi_fs_exists(struct blk_desc *desc, int part)
return 1;
}
+/**
+ * efi_part_is_esp() - check if a partition is an EFI system partition
+ *
+ * @desc: block device descriptor
+ * @part: partition number
+ * Return: true if a partition is an EFI system partition
+ * false otherwise
+ */
+static bool efi_part_is_esp(struct blk_desc *desc, int part)
+{
+ int ret;
+ struct disk_partition info;
+
+ ret = part_get_info(desc, part, &info);
+ if (ret)
+ return false;
+
+ if (info.bootable & PART_EFI_SYSTEM_PARTITION)
+ return true;
+
+ if (fs_set_blk_dev_with_part(desc, part))
+ return false;
+
+ if (!desc->removable)
+ return !!fs_exists("/EFI");
+
+ return !!fs_exists("/EFI/BOOT/" BOOTEFI_NAME);
+}
+
/**
* efi_disk_add_dev() - create a handle for a partition or disk
*
@@ -436,21 +465,14 @@ static efi_status_t efi_disk_add_dev(
*disk = diskobj;
/* Store first EFI system partition */
- if (part && !efi_system_partition.if_type) {
- int r;
- struct disk_partition info;
-
- r = part_get_info(desc, part, &info);
- if (r)
- return EFI_DEVICE_ERROR;
- if (info.bootable & PART_EFI_SYSTEM_PARTITION) {
- efi_system_partition.if_type = desc->if_type;
- efi_system_partition.devnum = desc->devnum;
- efi_system_partition.part = part;
- EFI_PRINT("EFI system partition: %s %d:%d\n",
- blk_get_if_type_name(desc->if_type),
- desc->devnum, part);
- }
+ if (part && !efi_system_partition.if_type &&
+ efi_part_is_esp(desc, part)) {
+ efi_system_partition.if_type = desc->if_type;
+ efi_system_partition.devnum = desc->devnum;
+ efi_system_partition.part = part;
+ EFI_PRINT("EFI system partition: %s %d:%d\n",
+ blk_get_if_type_name(desc->if_type),
+ desc->devnum, part);
}
return EFI_SUCCESS;
}
@@ -614,9 +636,7 @@ bool efi_disk_is_system_part(efi_handle_t handle)
{
struct efi_handler *handler;
struct efi_disk_obj *diskobj;
- struct disk_partition info;
efi_status_t ret;
- int r;
/* check if this is a block device */
ret = efi_search_protocol(handle, &efi_block_io_guid, &handler);
@@ -625,9 +645,5 @@ bool efi_disk_is_system_part(efi_handle_t handle)
diskobj = container_of(handle, struct efi_disk_obj, header);
- r = part_get_info(diskobj->desc, diskobj->part, &info);
- if (r)
- return false;
-
- return !!(info.bootable & PART_EFI_SYSTEM_PARTITION);
+ return efi_part_is_esp(diskobj->desc, diskobj->part);
}
--
2.29.2
More information about the U-Boot
mailing list