@@ -584,7 +584,6 @@ static efi_status_t try_load_from_media(struct efi_device_path *file_path,
efi_status_t ret = EFI_SUCCESS;
struct efi_device_path *rem, *dp = NULL;
struct efi_device_path *final_dp = file_path;
-
h = efi_dp_find_obj(file_path, &efi_block_io_guid, &rem);
if (h) {
if (rem->type == DEVICE_PATH_TYPE_END) {
@@ -788,15 +787,19 @@ error:
* efi_bootmgr_enumerate_boot_option() - enumerate the possible bootable media
*
* @opt: pointer to the media boot option structure
+ * @index: index of the opt array to store the boot option
* @handles: pointer to the efi handles
* @count: number of efi handle
+ * @removable: flag to parse removable only
* Return: status code
*/
static efi_status_t efi_bootmgr_enumerate_boot_option(struct eficonfig_media_boot_option *opt,
+ efi_uintn_t index,
efi_handle_t *handles,
- efi_uintn_t *count)
+ efi_uintn_t *count,
+ bool removable)
{
- u32 i, num = 0;
+ u32 i, num = index;
struct efi_handler *handler;
efi_status_t ret = EFI_SUCCESS;
@@ -810,12 +813,20 @@ static efi_status_t efi_bootmgr_enumerate_boot_option(struct eficonfig_media_boo
struct efi_device_path *short_dp;
struct efi_block_io *blkio;
+ if (num >= *count) {
+ ret = EFI_INVALID_PARAMETER;
+ goto out;
+ }
+
ret = efi_search_protocol(handles[i], &efi_block_io_guid, &handler);
blkio = handler->protocol_interface;
if (blkio->media->logical_partition)
continue;
+ if (removable != (blkio->media->removable_media != 0))
+ continue;
+
ret = efi_search_protocol(handles[i], &efi_guid_device_path, &handler);
if (ret != EFI_SUCCESS)
continue;
@@ -1105,7 +1116,7 @@ efi_status_t efi_bootmgr_update_media_device_boot_option(void)
{
u32 i;
efi_status_t ret;
- efi_uintn_t count;
+ efi_uintn_t count, num, total;
efi_handle_t *handles = NULL;
struct eficonfig_media_boot_option *opt = NULL;
@@ -1122,22 +1133,32 @@ efi_status_t efi_bootmgr_update_media_device_boot_option(void)
goto out;
}
- ret = efi_bootmgr_enumerate_boot_option(opt, handles, &count);
+ /* parse removable block io followed by fixed block io */
+ num = count;
+ ret = efi_bootmgr_enumerate_boot_option(opt, 0, handles, &num, true);
if (ret != EFI_SUCCESS)
goto out;
+ total = num;
+ num = count;
+ ret = efi_bootmgr_enumerate_boot_option(opt, total, handles, &num, false);
+ if (ret != EFI_SUCCESS)
+ goto out;
+
+ total = num;
+
/*
* System hardware configuration may vary depending on the user setup.
* The boot option is automatically added by the bootmenu.
* If the device is not attached to the system, the boot option needs
* to be deleted.
*/
- ret = efi_bootmgr_delete_invalid_boot_option(opt, count);
+ ret = efi_bootmgr_delete_invalid_boot_option(opt, total);
if (ret != EFI_SUCCESS)
goto out;
/* add non-existent boot option */
- for (i = 0; i < count; i++) {
+ for (i = 0; i < total; i++) {
u32 boot_index;
u16 var_name[9];
@@ -1166,7 +1187,7 @@ efi_status_t efi_bootmgr_update_media_device_boot_option(void)
out:
if (opt) {
- for (i = 0; i < count; i++)
+ for (i = 0; i < total; i++)
free(opt[i].lo);
}
free(opt);
This commit auto-generates the boot option for removable block io devices followed by fixed block io devices. This is what EDK II reference implementation does. Signed-off-by: Masahisa Kojima <masahisa.kojima@linaro.org> --- lib/efi_loader/efi_bootmgr.c | 37 ++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-)