On Mon, 16 Oct 2023 at 21:46, Heinrich Schuchardt <xypron.g...@gmx.de> wrote: > > On 16.10.23 14:31, Ilias Apalodimas wrote: > > Hi Heinrich, > > > > On Mon, 16 Oct 2023 at 10:06, Heinrich Schuchardt <xypron.g...@gmx.de> > > wrote: > >> > >> > >> > >> Am 16. Oktober 2023 08:45:21 MESZ schrieb Masahisa Kojima > >> <masahisa.koj...@linaro.org>: > >>> 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. > >> > >> I don't directly see the user benefit. > > > > The user can add an HTTP boot option now and the installer will > > automatically start. That would allow products to ship with a single > > boot option provisioned and run an installer on first boot > > This commit is not about HTTP. It changes how boot options for block > devices are created. > > > > >> > >> Reading all file systems will increase the boot time. Shouldn't we avoid > >> this? > > > > Any idea what would be an alternative? But when we added the > > automatic boot options we said we should avoid dynamic scanning and > > store results in a file. This is doing a similar thing. The only > > difference is that it mounts the iso image before adding the boot > > option. > > The alternative is to keep showing boot options for block devices even > if there is no BOOTxxxx.EFI file. > > > > >> > >> What does EDK II do? > > > > No Idea :) > > > On my workstation I get generated boot options > > Boot0001* UEFI:CD/DVD Drive BBS(129,,0x0) > Boot0003* UEFI:Removable Device BBS(130,,0x0) > Boot0004* UEFI:Network Device BBS(131,,0x0) > > without any media inserted and without any PXE server available.
It is just information about how the EDK2 works. When I attach the Fedora installation media on EDK2(OVMF), the automatically generated boot option is as follows. UEFI QEMU HARDDISK QM00001 : PciRoot(0x0)/Pci(0x1,0x1)/Ata(Primary,Master,0x0) When this boot option is selected, Fedora installer automatically starts. So EDK II is searching the default file on the fly. Thanks, Masahisa Kojima > > Best regards > > Heinrich > > > > > Thanks > > /Ilias > >> > >> Does the UEFI specification warrant this change? > >> > >> Best regards > >> > >> Heinrich > >> > >>> > >>> Signed-off-by: Masahisa Kojima <masahisa.koj...@linaro.org> > >>> --- > >>> lib/efi_loader/efi_bootmgr.c | 86 ++++++++++++++++++++++++++---------- > >>> 1 file changed, 63 insertions(+), 23 deletions(-) > >>> > >>> diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c > >>> index a40762c74c..c8cf1c5506 100644 > >>> --- a/lib/efi_loader/efi_bootmgr.c > >>> +++ b/lib/efi_loader/efi_bootmgr.c > >>> @@ -355,40 +355,70 @@ 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, *dp, *fp; > >>> struct efi_device_path *short_dp; > >>> + struct efi_file_handle *root, *f; > >>> + struct efi_simple_file_system_protocol *file_system; > >>> + u16 *default_file_path = NULL; > >>> > >>> - ret = efi_search_protocol(volume_handles[i], > >>> &efi_guid_device_path, &handler); > >>> + ret = efi_search_protocol(volume_handles[i], > >>> + &efi_guid_device_path, &handler); > >>> if (ret != EFI_SUCCESS) > >>> continue; > >>> - ret = efi_protocol_open(handler, (void **)&device_path, > >>> - efi_root, NULL, > >>> EFI_OPEN_PROTOCOL_GET_PROTOCOL); > >>> + > >>> + device_path = handler->protocol_interface; > >>> + full_path = efi_dp_from_file(device_path, > >>> + "/EFI/BOOT/" BOOTEFI_NAME); > >>> + > >>> + /* check whether the partition or disk have the default > >>> file */ > >>> + ret = efi_dp_split_file_path(full_path, &dp, &fp); > >>> + if (ret != EFI_SUCCESS || !fp) > >>> + goto next_entry; > >>> + > >>> + default_file_path = efi_dp_str(fp); > >>> + if (!default_file_path) > >>> + goto next_entry; > >>> + > >>> + ret = efi_search_protocol(volume_handles[i], > >>> + > >>> &efi_simple_file_system_protocol_guid, > >>> + &handler); > >>> if (ret != EFI_SUCCESS) > >>> - continue; > >>> + goto next_entry; > >>> + > >>> + file_system = handler->protocol_interface; > >>> + ret = EFI_CALL(file_system->open_volume(file_system, > >>> &root)); > >>> + if (ret != EFI_SUCCESS) > >>> + goto next_entry; > >>> + > >>> + ret = EFI_CALL(root->open(root, &f, default_file_path, > >>> + EFI_FILE_MODE_READ, 0)); > >>> + if (ret != EFI_SUCCESS) > >>> + goto next_entry; > >>> + > >>> + EFI_CALL(f->close(f)); > >>> > >>> ret = efi_disk_get_device_name(volume_handles[i], buf, > >>> BOOTMENU_DEVICE_NAME_MAX); > >>> if (ret != EFI_SUCCESS) > >>> - continue; > >>> + goto next_entry; > >>> > >>> 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 +426,35 @@ 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); > >>> + efi_free_pool(dp); > >>> + efi_free_pool(fp); > >>> + efi_free_pool(default_file_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_entry: > >>> + efi_free_pool(full_path); > >>> + efi_free_pool(dp); > >>> + efi_free_pool(fp); > >>> + efi_free_pool(default_file_path); > >>> } > >>> > >>> -out: > >>> - return ret; > >>> + *count = num; > >>> + > >>> + return EFI_SUCCESS; > >>> } > >>> > >>> /** > >>> @@ -642,7 +683,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 +715,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; > >>> >