Current efibootmgr automatically creates the boot options of all disks and partitions installing EFI_SIMPLE_FILE_SYSTEM_PROTOCOL. Some of the automatically created boot options are useless if the disk and partition does not have the default file(e.g. EFI/BOOT/BOOTAA64.EFI).
This commit only creates the boot option if the disk and partition have the default file so that system can directly boot from it. Signed-off-by: Masahisa Kojima <masahisa.koj...@linaro.org> --- lib/efi_loader/efi_bootmgr.c | 53 +++++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 19 deletions(-) diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c index a40762c74c..a197127cdd 100644 --- a/lib/efi_loader/efi_bootmgr.c +++ b/lib/efi_loader/efi_bootmgr.c @@ -355,20 +355,21 @@ error: */ static efi_status_t efi_bootmgr_enumerate_boot_option(struct eficonfig_media_boot_option *opt, efi_handle_t *volume_handles, - efi_status_t count) + efi_uintn_t *count) { - u32 i; + u32 i, num = 0; struct efi_handler *handler; efi_status_t ret = EFI_SUCCESS; - for (i = 0; i < count; i++) { + for (i = 0; i < *count; i++) { u16 *p; u16 dev_name[BOOTMENU_DEVICE_NAME_MAX]; char *optional_data; struct efi_load_option lo; char buf[BOOTMENU_DEVICE_NAME_MAX]; - struct efi_device_path *device_path; + struct efi_device_path *device_path, *full_path; struct efi_device_path *short_dp; + efi_handle_t image_handle; ret = efi_search_protocol(volume_handles[i], &efi_guid_device_path, &handler); if (ret != EFI_SUCCESS) @@ -378,17 +379,27 @@ static efi_status_t efi_bootmgr_enumerate_boot_option(struct eficonfig_media_boo if (ret != EFI_SUCCESS) continue; + /* check whether the partition or disk have the default file */ + full_path = efi_dp_from_file(device_path, + "/EFI/BOOT/" BOOTEFI_NAME); + ret = EFI_CALL(efi_load_image(true, efi_root, full_path, NULL, + 0, &image_handle)); + if (ret != EFI_SUCCESS) + goto next; + ret = EFI_CALL(efi_unload_image(image_handle)); + if (ret != EFI_SUCCESS) + goto next; + ret = efi_disk_get_device_name(volume_handles[i], buf, BOOTMENU_DEVICE_NAME_MAX); if (ret != EFI_SUCCESS) - continue; + goto next; p = dev_name; utf8_utf16_strncpy(&p, buf, strlen(buf)); /* prefer to short form device path */ - short_dp = efi_dp_shorten(device_path); - if (short_dp) - device_path = short_dp; + short_dp = efi_dp_shorten(full_path); + device_path = short_dp ? short_dp : full_path; lo.label = dev_name; lo.attributes = LOAD_OPTION_ACTIVE; @@ -396,24 +407,29 @@ static efi_status_t efi_bootmgr_enumerate_boot_option(struct eficonfig_media_boo lo.file_path_length = efi_dp_size(device_path) + sizeof(END); /* * Set the dedicated guid to optional_data, it is used to identify - * the boot option that automatically generated by the bootmenu. + * the boot option that automatically generated by the efibootmgr. * efi_serialize_load_option() expects optional_data is null-terminated * utf8 string, so set the "1234567" string to allocate enough space * to store guid, instead of realloc the load_option. */ lo.optional_data = "1234567"; - opt[i].size = efi_serialize_load_option(&lo, (u8 **)&opt[i].lo); - if (!opt[i].size) { - ret = EFI_OUT_OF_RESOURCES; - goto out; + opt[num].size = efi_serialize_load_option(&lo, (u8 **)&opt[num].lo); + if (!opt[num].size) { + efi_free_pool(full_path); + return EFI_OUT_OF_RESOURCES; } /* set the guid */ - optional_data = (char *)opt[i].lo + (opt[i].size - u16_strsize(u"1234567")); + optional_data = (char *)opt[num].lo + (opt[num].size - u16_strsize(u"1234567")); memcpy(optional_data, &efi_guid_bootmenu_auto_generated, sizeof(efi_guid_t)); + num++; + +next: + efi_free_pool(full_path); } -out: - return ret; + *count = num; + + return EFI_SUCCESS; } /** @@ -642,7 +658,7 @@ efi_status_t efi_bootmgr_delete_boot_option(u16 boot_index) * efi_bootmgr_update_media_device_boot_option() - generate the media device boot option * * This function enumerates all devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL - * and generate the bootmenu entries. + * and create the boot option with default file if the file exists. * This function also provide the BOOT#### variable maintenance for * the media device entries. * - Automatically create the BOOT#### variable for the newly detected device, @@ -674,8 +690,7 @@ efi_status_t efi_bootmgr_update_media_device_boot_option(void) goto out; } - /* enumerate all devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL */ - ret = efi_bootmgr_enumerate_boot_option(opt, volume_handles, count); + ret = efi_bootmgr_enumerate_boot_option(opt, volume_handles, &count); if (ret != EFI_SUCCESS) goto out; -- 2.34.1