Re: [PATCH v5 16/17] bootmenu: add removable media entries
Hi Heinrich, On Mon, 9 May 2022 at 22:01, Heinrich Schuchardt wrote: > > On 5/9/22 10:23, Masahisa Kojima wrote: > > On Fri, 29 Apr 2022 at 01:53, Heinrich Schuchardt > > wrote: > >> > >> On 4/28/22 10:09, Masahisa Kojima wrote: > >>> UEFI specification requires booting from removal media using > >>> a architecture-specific default image name such as BOOTAA64.EFI. > >>> This commit adds the removable media entries into bootmenu, > >>> so that user can select the removable media and boot with > >>> default image. > >>> > >>> The bootmenu automatically enumerates the possible bootable > >>> media devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL, > >>> add it as new UEFI boot option(BOOT) and update BootOrder > >>> variable. This automatically generated UEFI boot option > >>> has the dedicated guid in the optional_data to distinguish it from > >>> the UEFI boot option user adds manually. > >>> > >>> This commit also provides the BOOT variable maintenance feature. > >>> Depending on the system hardware setup, some devices > >>> may not exist at a later system boot, so bootmenu checks the > >>> available device in each bootmenu invocation and automatically > >>> removes the BOOT variable corrensponding to the non-existent > >>> media device. > >>> > >>> Signed-off-by: Masahisa Kojima > >>> --- > >>> Changes in v5: > >>> - Return EFI_SUCCESS if there is no BootOrder defined > >>> - correctly handle the case if no removable device found > >>> - use guid to identify the automatically generated entry by bootmenu > >>> > >>> Newly created in v4 > >>> > >>>cmd/bootmenu.c| 94 +++ > >>>include/efi_loader.h | 20 > >>>lib/efi_loader/efi_bootmenu_maintenance.c | 139 ++ > >>>3 files changed, 253 insertions(+) > >>> > >>> diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c > >>> index 860cb83182..970db3ee01 100644 > >>> --- a/cmd/bootmenu.c > >>> +++ b/cmd/bootmenu.c > >>> @@ -396,6 +396,89 @@ static int is_blk_device_available(char *token) > >>>return -ENODEV; > >>>} > >>> > >>> +/** > >>> + * prepare_media_device_entry() - generate the media device entries > >>> + * > >>> + * This function enumerates all devices supporting > >>> EFI_SIMPLE_FILE_SYSTEM_PROTOCOL > >>> + * and generate the bootmenu entries. > >>> + * This function also provide the BOOT variable maintenance for > >>> + * the media device entries. > >>> + * - Automatically create the BOOT variable for the newly detected > >>> device, > >>> + * this BOOT variable is distinguished by the special GUID > >>> + * stored in the EFI_LOAD_OPTION.optional_data > >>> + * - If the device is not attached to the system, the associated > >>> BOOT variable > >>> + * is automatically deleted. > >>> + * > >>> + * Return: status code > >>> + */ > >>> +static efi_status_t prepare_media_device_entry(void) > >>> +{ > >>> + u32 i; > >>> + efi_status_t ret; > >>> + efi_uintn_t count; > >>> + efi_handle_t *volume_handles = NULL; > >>> + struct efi_bootmenu_media_boot_option *opt = NULL; > >>> + > >>> + ret = efi_locate_handle_buffer_int(BY_PROTOCOL, > >>> &efi_simple_file_system_protocol_guid, > >>> +NULL, &count, (efi_handle_t > >>> **)&volume_handles); > >>> + if (ret != EFI_SUCCESS) > >>> + return ret; > >>> + > >>> + opt = calloc(count, sizeof(struct efi_bootmenu_media_boot_option)); > >>> + if (!opt) > >>> + goto out; > >>> + > >>> + /* enumerate all devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL > >>> */ > >>> + ret = efi_bootmenu_enumerate_boot_option(opt, volume_handles, > >>> count); > >>> + if (ret != EFI_SUCCESS) > >>> + goto out; > >>> + > >>> + /* > >>> + * 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_bootmenu_delete_invalid_boot_option(opt, count); > >>> + if (ret != EFI_SUCCESS) > >>> + goto out; > >>> + > >>> + /* add non-existent boot option */ > >>> + for (i = 0; i < count; i++) { > >>> + u32 boot_index; > >>> + u16 var_name[9]; > >>> + > >>> + if (!opt[i].exist) { > >>> + ret = efi_bootmenu_get_unused_bootoption(var_name, > >>> sizeof(var_name), > >>> + > >>> &boot_index); > >>> + if (ret != EFI_SUCCESS) > >>> + goto out; > >>> + > >>> + ret = efi_set_variable_int(var_name, > >>> &efi_global_variable_guid, > >>> + > >>> EFI_VARIABLE_NON_VOLATILE | > >>> +
Re: [PATCH v5 16/17] bootmenu: add removable media entries
On 5/9/22 10:23, Masahisa Kojima wrote: On Fri, 29 Apr 2022 at 01:53, Heinrich Schuchardt wrote: On 4/28/22 10:09, Masahisa Kojima wrote: UEFI specification requires booting from removal media using a architecture-specific default image name such as BOOTAA64.EFI. This commit adds the removable media entries into bootmenu, so that user can select the removable media and boot with default image. The bootmenu automatically enumerates the possible bootable media devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL, add it as new UEFI boot option(BOOT) and update BootOrder variable. This automatically generated UEFI boot option has the dedicated guid in the optional_data to distinguish it from the UEFI boot option user adds manually. This commit also provides the BOOT variable maintenance feature. Depending on the system hardware setup, some devices may not exist at a later system boot, so bootmenu checks the available device in each bootmenu invocation and automatically removes the BOOT variable corrensponding to the non-existent media device. Signed-off-by: Masahisa Kojima --- Changes in v5: - Return EFI_SUCCESS if there is no BootOrder defined - correctly handle the case if no removable device found - use guid to identify the automatically generated entry by bootmenu Newly created in v4 cmd/bootmenu.c| 94 +++ include/efi_loader.h | 20 lib/efi_loader/efi_bootmenu_maintenance.c | 139 ++ 3 files changed, 253 insertions(+) diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c index 860cb83182..970db3ee01 100644 --- a/cmd/bootmenu.c +++ b/cmd/bootmenu.c @@ -396,6 +396,89 @@ static int is_blk_device_available(char *token) return -ENODEV; } +/** + * prepare_media_device_entry() - generate the media device entries + * + * This function enumerates all devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL + * and generate the bootmenu entries. + * This function also provide the BOOT variable maintenance for + * the media device entries. + * - Automatically create the BOOT variable for the newly detected device, + * this BOOT variable is distinguished by the special GUID + * stored in the EFI_LOAD_OPTION.optional_data + * - If the device is not attached to the system, the associated BOOT variable + * is automatically deleted. + * + * Return: status code + */ +static efi_status_t prepare_media_device_entry(void) +{ + u32 i; + efi_status_t ret; + efi_uintn_t count; + efi_handle_t *volume_handles = NULL; + struct efi_bootmenu_media_boot_option *opt = NULL; + + ret = efi_locate_handle_buffer_int(BY_PROTOCOL, &efi_simple_file_system_protocol_guid, +NULL, &count, (efi_handle_t **)&volume_handles); + if (ret != EFI_SUCCESS) + return ret; + + opt = calloc(count, sizeof(struct efi_bootmenu_media_boot_option)); + if (!opt) + goto out; + + /* enumerate all devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL */ + ret = efi_bootmenu_enumerate_boot_option(opt, volume_handles, count); + if (ret != EFI_SUCCESS) + goto out; + + /* + * 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_bootmenu_delete_invalid_boot_option(opt, count); + if (ret != EFI_SUCCESS) + goto out; + + /* add non-existent boot option */ + for (i = 0; i < count; i++) { + u32 boot_index; + u16 var_name[9]; + + if (!opt[i].exist) { + ret = efi_bootmenu_get_unused_bootoption(var_name, sizeof(var_name), + &boot_index); + if (ret != EFI_SUCCESS) + goto out; + + ret = efi_set_variable_int(var_name, &efi_global_variable_guid, +EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | +EFI_VARIABLE_RUNTIME_ACCESS, +opt[i].size, opt[i].lo, false); + if (ret != EFI_SUCCESS) + goto out; + + ret = efi_bootmenu_append_bootorder(boot_index); + if (ret != EFI_SUCCESS) + goto out; + } + } + +out: + if (opt) { + for (i = 0; i < count; i++) + free(opt[i].lo); + } + free(opt); + efi_free_pool(volume_handles); + + return ret; +} + /** * prepare_distro_boot_entry() - generate the distro boot entries *
Re: [PATCH v5 16/17] bootmenu: add removable media entries
On Fri, 29 Apr 2022 at 01:53, Heinrich Schuchardt wrote: > > On 4/28/22 10:09, Masahisa Kojima wrote: > > UEFI specification requires booting from removal media using > > a architecture-specific default image name such as BOOTAA64.EFI. > > This commit adds the removable media entries into bootmenu, > > so that user can select the removable media and boot with > > default image. > > > > The bootmenu automatically enumerates the possible bootable > > media devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL, > > add it as new UEFI boot option(BOOT) and update BootOrder > > variable. This automatically generated UEFI boot option > > has the dedicated guid in the optional_data to distinguish it from > > the UEFI boot option user adds manually. > > > > This commit also provides the BOOT variable maintenance feature. > > Depending on the system hardware setup, some devices > > may not exist at a later system boot, so bootmenu checks the > > available device in each bootmenu invocation and automatically > > removes the BOOT variable corrensponding to the non-existent > > media device. > > > > Signed-off-by: Masahisa Kojima > > --- > > Changes in v5: > > - Return EFI_SUCCESS if there is no BootOrder defined > > - correctly handle the case if no removable device found > > - use guid to identify the automatically generated entry by bootmenu > > > > Newly created in v4 > > > > cmd/bootmenu.c| 94 +++ > > include/efi_loader.h | 20 > > lib/efi_loader/efi_bootmenu_maintenance.c | 139 ++ > > 3 files changed, 253 insertions(+) > > > > diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c > > index 860cb83182..970db3ee01 100644 > > --- a/cmd/bootmenu.c > > +++ b/cmd/bootmenu.c > > @@ -396,6 +396,89 @@ static int is_blk_device_available(char *token) > > return -ENODEV; > > } > > > > +/** > > + * prepare_media_device_entry() - generate the media device entries > > + * > > + * This function enumerates all devices supporting > > EFI_SIMPLE_FILE_SYSTEM_PROTOCOL > > + * and generate the bootmenu entries. > > + * This function also provide the BOOT variable maintenance for > > + * the media device entries. > > + * - Automatically create the BOOT variable for the newly detected > > device, > > + * this BOOT variable is distinguished by the special GUID > > + * stored in the EFI_LOAD_OPTION.optional_data > > + * - If the device is not attached to the system, the associated > > BOOT variable > > + * is automatically deleted. > > + * > > + * Return: status code > > + */ > > +static efi_status_t prepare_media_device_entry(void) > > +{ > > + u32 i; > > + efi_status_t ret; > > + efi_uintn_t count; > > + efi_handle_t *volume_handles = NULL; > > + struct efi_bootmenu_media_boot_option *opt = NULL; > > + > > + ret = efi_locate_handle_buffer_int(BY_PROTOCOL, > > &efi_simple_file_system_protocol_guid, > > +NULL, &count, (efi_handle_t > > **)&volume_handles); > > + if (ret != EFI_SUCCESS) > > + return ret; > > + > > + opt = calloc(count, sizeof(struct efi_bootmenu_media_boot_option)); > > + if (!opt) > > + goto out; > > + > > + /* enumerate all devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL */ > > + ret = efi_bootmenu_enumerate_boot_option(opt, volume_handles, count); > > + if (ret != EFI_SUCCESS) > > + goto out; > > + > > + /* > > + * 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_bootmenu_delete_invalid_boot_option(opt, count); > > + if (ret != EFI_SUCCESS) > > + goto out; > > + > > + /* add non-existent boot option */ > > + for (i = 0; i < count; i++) { > > + u32 boot_index; > > + u16 var_name[9]; > > + > > + if (!opt[i].exist) { > > + ret = efi_bootmenu_get_unused_bootoption(var_name, > > sizeof(var_name), > > + &boot_index); > > + if (ret != EFI_SUCCESS) > > + goto out; > > + > > + ret = efi_set_variable_int(var_name, > > &efi_global_variable_guid, > > +EFI_VARIABLE_NON_VOLATILE | > > + > > EFI_VARIABLE_BOOTSERVICE_ACCESS | > > + > > EFI_VARIABLE_RUNTIME_ACCESS, > > +opt[i].size, opt[i].lo, > > false); > > + if (ret != EFI_SUCCESS) > > + goto out; > > + > > + ret = efi_
Re: [PATCH v5 16/17] bootmenu: add removable media entries
On 4/28/22 10:09, Masahisa Kojima wrote: UEFI specification requires booting from removal media using a architecture-specific default image name such as BOOTAA64.EFI. This commit adds the removable media entries into bootmenu, so that user can select the removable media and boot with default image. The bootmenu automatically enumerates the possible bootable media devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL, add it as new UEFI boot option(BOOT) and update BootOrder variable. This automatically generated UEFI boot option has the dedicated guid in the optional_data to distinguish it from the UEFI boot option user adds manually. This commit also provides the BOOT variable maintenance feature. Depending on the system hardware setup, some devices may not exist at a later system boot, so bootmenu checks the available device in each bootmenu invocation and automatically removes the BOOT variable corrensponding to the non-existent media device. Signed-off-by: Masahisa Kojima --- Changes in v5: - Return EFI_SUCCESS if there is no BootOrder defined - correctly handle the case if no removable device found - use guid to identify the automatically generated entry by bootmenu Newly created in v4 cmd/bootmenu.c| 94 +++ include/efi_loader.h | 20 lib/efi_loader/efi_bootmenu_maintenance.c | 139 ++ 3 files changed, 253 insertions(+) diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c index 860cb83182..970db3ee01 100644 --- a/cmd/bootmenu.c +++ b/cmd/bootmenu.c @@ -396,6 +396,89 @@ static int is_blk_device_available(char *token) return -ENODEV; } +/** + * prepare_media_device_entry() - generate the media device entries + * + * This function enumerates all devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL + * and generate the bootmenu entries. + * This function also provide the BOOT variable maintenance for + * the media device entries. + * - Automatically create the BOOT variable for the newly detected device, + * this BOOT variable is distinguished by the special GUID + * stored in the EFI_LOAD_OPTION.optional_data + * - If the device is not attached to the system, the associated BOOT variable + * is automatically deleted. + * + * Return: status code + */ +static efi_status_t prepare_media_device_entry(void) +{ + u32 i; + efi_status_t ret; + efi_uintn_t count; + efi_handle_t *volume_handles = NULL; + struct efi_bootmenu_media_boot_option *opt = NULL; + + ret = efi_locate_handle_buffer_int(BY_PROTOCOL, &efi_simple_file_system_protocol_guid, + NULL, &count, (efi_handle_t **)&volume_handles); + if (ret != EFI_SUCCESS) + return ret; + + opt = calloc(count, sizeof(struct efi_bootmenu_media_boot_option)); + if (!opt) + goto out; + + /* enumerate all devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL */ + ret = efi_bootmenu_enumerate_boot_option(opt, volume_handles, count); + if (ret != EFI_SUCCESS) + goto out; + + /* +* 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_bootmenu_delete_invalid_boot_option(opt, count); + if (ret != EFI_SUCCESS) + goto out; + + /* add non-existent boot option */ + for (i = 0; i < count; i++) { + u32 boot_index; + u16 var_name[9]; + + if (!opt[i].exist) { + ret = efi_bootmenu_get_unused_bootoption(var_name, sizeof(var_name), +&boot_index); + if (ret != EFI_SUCCESS) + goto out; + + ret = efi_set_variable_int(var_name, &efi_global_variable_guid, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + opt[i].size, opt[i].lo, false); + if (ret != EFI_SUCCESS) + goto out; + + ret = efi_bootmenu_append_bootorder(boot_index); + if (ret != EFI_SUCCESS) + goto out; + } + } + +out: + if (opt) { + for (i = 0; i < count; i++) + free(opt[i].lo); + } + free(opt); + efi_free_pool(volume_handles); + + return ret; +} + /** * prepare_distro_boot_entry() - generate the distro boot entries *
[PATCH v5 16/17] bootmenu: add removable media entries
UEFI specification requires booting from removal media using a architecture-specific default image name such as BOOTAA64.EFI. This commit adds the removable media entries into bootmenu, so that user can select the removable media and boot with default image. The bootmenu automatically enumerates the possible bootable media devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL, add it as new UEFI boot option(BOOT) and update BootOrder variable. This automatically generated UEFI boot option has the dedicated guid in the optional_data to distinguish it from the UEFI boot option user adds manually. This commit also provides the BOOT variable maintenance feature. Depending on the system hardware setup, some devices may not exist at a later system boot, so bootmenu checks the available device in each bootmenu invocation and automatically removes the BOOT variable corrensponding to the non-existent media device. Signed-off-by: Masahisa Kojima --- Changes in v5: - Return EFI_SUCCESS if there is no BootOrder defined - correctly handle the case if no removable device found - use guid to identify the automatically generated entry by bootmenu Newly created in v4 cmd/bootmenu.c| 94 +++ include/efi_loader.h | 20 lib/efi_loader/efi_bootmenu_maintenance.c | 139 ++ 3 files changed, 253 insertions(+) diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c index 860cb83182..970db3ee01 100644 --- a/cmd/bootmenu.c +++ b/cmd/bootmenu.c @@ -396,6 +396,89 @@ static int is_blk_device_available(char *token) return -ENODEV; } +/** + * prepare_media_device_entry() - generate the media device entries + * + * This function enumerates all devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL + * and generate the bootmenu entries. + * This function also provide the BOOT variable maintenance for + * the media device entries. + * - Automatically create the BOOT variable for the newly detected device, + * this BOOT variable is distinguished by the special GUID + * stored in the EFI_LOAD_OPTION.optional_data + * - If the device is not attached to the system, the associated BOOT variable + * is automatically deleted. + * + * Return: status code + */ +static efi_status_t prepare_media_device_entry(void) +{ + u32 i; + efi_status_t ret; + efi_uintn_t count; + efi_handle_t *volume_handles = NULL; + struct efi_bootmenu_media_boot_option *opt = NULL; + + ret = efi_locate_handle_buffer_int(BY_PROTOCOL, &efi_simple_file_system_protocol_guid, + NULL, &count, (efi_handle_t **)&volume_handles); + if (ret != EFI_SUCCESS) + return ret; + + opt = calloc(count, sizeof(struct efi_bootmenu_media_boot_option)); + if (!opt) + goto out; + + /* enumerate all devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL */ + ret = efi_bootmenu_enumerate_boot_option(opt, volume_handles, count); + if (ret != EFI_SUCCESS) + goto out; + + /* +* 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_bootmenu_delete_invalid_boot_option(opt, count); + if (ret != EFI_SUCCESS) + goto out; + + /* add non-existent boot option */ + for (i = 0; i < count; i++) { + u32 boot_index; + u16 var_name[9]; + + if (!opt[i].exist) { + ret = efi_bootmenu_get_unused_bootoption(var_name, sizeof(var_name), +&boot_index); + if (ret != EFI_SUCCESS) + goto out; + + ret = efi_set_variable_int(var_name, &efi_global_variable_guid, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + opt[i].size, opt[i].lo, false); + if (ret != EFI_SUCCESS) + goto out; + + ret = efi_bootmenu_append_bootorder(boot_index); + if (ret != EFI_SUCCESS) + goto out; + } + } + +out: + if (opt) { + for (i = 0; i < count; i++) + free(opt[i].lo); + } + free(opt); + efi_free_pool(volume_handles); + + return ret; +} + /** * prepare_distro_boot_entry() - generate the distro boot entries * @@ -500,6 +583,7 @@ static int prepare_distro_boo