Re: [PATCH v5 13/17] efi_loader: menu-driven addition of UEFI boot option
On 5/9/22 11:27, Masahisa Kojima wrote: On Sat, 7 May 2022 at 03:16, Heinrich Schuchardt wrote: Am 6. Mai 2022 20:10:58 MESZ schrieb Mark Kettenis : Date: Fri, 6 May 2022 19:30:51 +0200 From: Heinrich Schuchardt On 4/30/22 14:49, Heinrich Schuchardt wrote: On 4/29/22 12:56, Heinrich Schuchardt wrote: On 4/28/22 18:33, Heinrich Schuchardt wrote: On 4/28/22 10:09, Masahisa Kojima wrote: This commit supports the menu-driven UEFI boot option addition. User can select the block device volume having efi_simple_file_system_protocol and select the file corresponding to the Boot variable. Then user enter the label of the BOOT variable in utf8. Signed-off-by: Masahisa Kojima This patch creates unexpected behavior: In the console I entered: setenv bootmenu_0 foo=echo foo setenv bootmenu_1 bar=echo bar bootmenu 20 Nothing here relates to UEFI but the menu shows: foo bar UEFI Boot Manager Maintenance Quit Please, don't show 'UEFI Boot Manager Maintenance' if we are not in the boot manager. Not sure what you mean with this. The "bootefi bootmgr" command simply looks at EFI variables and immediately exits if "BootOrder" isn't set. So the EFI varaibles need to be modified beforehands. Do you mean that 'UEFI Boot Manager Maintenance' should only be included in the menu if any "Boot" EFI variables exist (either because they have been explicitly set or because we have generated them for the "removable media" device paths)? The bootmenu command can be used in many contexts. Not all are related to booting. I am still not sure the meaning of "don't show 'UEFI Boot Manager Maintenance' if we are not in the boot manager." What do you mean "in the boot manager"? The bootmenu command is used to show a generic menu. It should only show the menu items selected via the bootmenu_* variables or parameters of the bootmenu command. With CONFIG_AUTOBOOT_MENU_SHOW=y a special menu is shown instead of the normal console countdown. Here you can show auto-generated entries. Best regards Heinrich The bootmenu already supports to enumerate the UEFI boot options, so it is some kind of boot manager. Thanks, Masahisa Kojima
Re: [PATCH v5 13/17] efi_loader: menu-driven addition of UEFI boot option
On Sat, 7 May 2022 at 03:16, Heinrich Schuchardt wrote: > > > > Am 6. Mai 2022 20:10:58 MESZ schrieb Mark Kettenis : > >> Date: Fri, 6 May 2022 19:30:51 +0200 > >> From: Heinrich Schuchardt > >> > >> On 4/30/22 14:49, Heinrich Schuchardt wrote: > >> > On 4/29/22 12:56, Heinrich Schuchardt wrote: > >> >> On 4/28/22 18:33, Heinrich Schuchardt wrote: > >> >>> On 4/28/22 10:09, Masahisa Kojima wrote: > >> This commit supports the menu-driven UEFI boot option addition. > >> User can select the block device volume having > >> efi_simple_file_system_protocol and select the file corresponding > >> to the Boot variable. Then user enter the label of the BOOT > >> variable in utf8. > >> > >> Signed-off-by: Masahisa Kojima > >> > >> This patch creates unexpected behavior: > >> > >> In the console I entered: > >> > >> setenv bootmenu_0 foo=echo foo > >> setenv bootmenu_1 bar=echo bar > >> bootmenu 20 > >> > >> Nothing here relates to UEFI but the menu shows: > >> > >>foo > >>bar > >>UEFI Boot Manager Maintenance > >>Quit > >> > >> Please, don't show 'UEFI Boot Manager Maintenance' if we are not in the > >> boot manager. > > > >Not sure what you mean with this. The "bootefi bootmgr" command > >simply looks at EFI variables and immediately exits if "BootOrder" > >isn't set. So the EFI varaibles need to be modified beforehands. > > > >Do you mean that 'UEFI Boot Manager Maintenance' should only be > >included in the menu if any "Boot" EFI variables exist (either > >because they have been explicitly set or because we have generated > >them for the "removable media" device paths)? > > > The bootmenu command can be used in many contexts. Not all are related to > booting. I am still not sure the meaning of "don't show 'UEFI Boot Manager Maintenance' if we are not in the boot manager." What do you mean "in the boot manager"? The bootmenu already supports to enumerate the UEFI boot options, so it is some kind of boot manager. Thanks, Masahisa Kojima
Re: [PATCH v5 13/17] efi_loader: menu-driven addition of UEFI boot option
Am 6. Mai 2022 20:10:58 MESZ schrieb Mark Kettenis : >> Date: Fri, 6 May 2022 19:30:51 +0200 >> From: Heinrich Schuchardt >> >> On 4/30/22 14:49, Heinrich Schuchardt wrote: >> > On 4/29/22 12:56, Heinrich Schuchardt wrote: >> >> On 4/28/22 18:33, Heinrich Schuchardt wrote: >> >>> On 4/28/22 10:09, Masahisa Kojima wrote: >> This commit supports the menu-driven UEFI boot option addition. >> User can select the block device volume having >> efi_simple_file_system_protocol and select the file corresponding >> to the Boot variable. Then user enter the label of the BOOT >> variable in utf8. >> >> Signed-off-by: Masahisa Kojima >> >> This patch creates unexpected behavior: >> >> In the console I entered: >> >> setenv bootmenu_0 foo=echo foo >> setenv bootmenu_1 bar=echo bar >> bootmenu 20 >> >> Nothing here relates to UEFI but the menu shows: >> >>foo >>bar >>UEFI Boot Manager Maintenance >>Quit >> >> Please, don't show 'UEFI Boot Manager Maintenance' if we are not in the >> boot manager. > >Not sure what you mean with this. The "bootefi bootmgr" command >simply looks at EFI variables and immediately exits if "BootOrder" >isn't set. So the EFI varaibles need to be modified beforehands. > >Do you mean that 'UEFI Boot Manager Maintenance' should only be >included in the menu if any "Boot" EFI variables exist (either >because they have been explicitly set or because we have generated >them for the "removable media" device paths)? The bootmenu command can be used in many contexts. Not all are related to booting.
Re: [PATCH v5 13/17] efi_loader: menu-driven addition of UEFI boot option
> Date: Fri, 6 May 2022 19:30:51 +0200 > From: Heinrich Schuchardt > > On 4/30/22 14:49, Heinrich Schuchardt wrote: > > On 4/29/22 12:56, Heinrich Schuchardt wrote: > >> On 4/28/22 18:33, Heinrich Schuchardt wrote: > >>> On 4/28/22 10:09, Masahisa Kojima wrote: > This commit supports the menu-driven UEFI boot option addition. > User can select the block device volume having > efi_simple_file_system_protocol and select the file corresponding > to the Boot variable. Then user enter the label of the BOOT > variable in utf8. > > Signed-off-by: Masahisa Kojima > > This patch creates unexpected behavior: > > In the console I entered: > > setenv bootmenu_0 foo=echo foo > setenv bootmenu_1 bar=echo bar > bootmenu 20 > > Nothing here relates to UEFI but the menu shows: > >foo >bar >UEFI Boot Manager Maintenance >Quit > > Please, don't show 'UEFI Boot Manager Maintenance' if we are not in the > boot manager. Not sure what you mean with this. The "bootefi bootmgr" command simply looks at EFI variables and immediately exits if "BootOrder" isn't set. So the EFI varaibles need to be modified beforehands. Do you mean that 'UEFI Boot Manager Maintenance' should only be included in the menu if any "Boot" EFI variables exist (either because they have been explicitly set or because we have generated them for the "removable media" device paths)?
Re: [PATCH v5 13/17] efi_loader: menu-driven addition of UEFI boot option
On 4/30/22 14:49, Heinrich Schuchardt wrote: On 4/29/22 12:56, Heinrich Schuchardt wrote: On 4/28/22 18:33, Heinrich Schuchardt wrote: On 4/28/22 10:09, Masahisa Kojima wrote: This commit supports the menu-driven UEFI boot option addition. User can select the block device volume having efi_simple_file_system_protocol and select the file corresponding to the Boot variable. Then user enter the label of the BOOT variable in utf8. Signed-off-by: Masahisa Kojima This patch creates unexpected behavior: In the console I entered: setenv bootmenu_0 foo=echo foo setenv bootmenu_1 bar=echo bar bootmenu 20 Nothing here relates to UEFI but the menu shows: foo bar UEFI Boot Manager Maintenance Quit Please, don't show 'UEFI Boot Manager Maintenance' if we are not in the boot manager. I have already merged most of the prior patches in the series. Please, consider this when resubmitting. Best regards Heinrich --- Changes in v5: - remove forward declarations - add const qualifier for menu items - fix the possible unaligned access for directory info access - split into three commit 1)add boot option 2) delete boot option 3)change boot order This commit is 1)add boot option. - fix file name buffer allocation size, it should be EFI_BOOTMENU_FILE_PATH_MAX * sizeof(u16) - fix wrong size checking for file selection Chanes in v4: - UEFI boot option maintenance menu is integrated into bootmenu - display the simplified volume name(e.g. usb0:1, nvme1:2) for the volume selection - instead of extending lib/efi_loader/efi_bootmgr.c, newly create lib/efi_loader/efi_bootmenu_maintenance.c and implement boot variable maintenance into it. Changes in RFC v3: not included in v3 series Changes in RFC v2: - enable utf8 user input for boot option name - create lib/efi_loader/efi_console.c::efi_console_get_u16_string() for utf8 user input handling - use u16_strlcat instead of u16_strcat - remove the EFI_CALLs, and newly create or expose the following xxx_int() functions. efi_locate_handle_buffer_int(), efi_open_volume_int(), efi_file_open_int(), efi_file_close_int(), efi_file_read_int() and efi_file_setpos_int(). Note that EFI_CALLs still exist for EFI_DEVICE_PATH_TO_TEXT_PROTOCOL and EFI_SIMPLE_TEXT_INPUT/OUTPUT_PROTOCOL - use efi_search_protocol() instead of calling locate_protocol() to get the device_path_to_text_protocol interface. - remove unnecessary puts(ANSI_CLEAR_LINE), this patch is still depends on puts(ANSI_CLEAR_CONSOLE) - skip SetVariable() if the bootorder is not changed cmd/bootmenu.c | 69 +- include/efi_loader.h | 37 + lib/efi_loader/Makefile | 1 + lib/efi_loader/efi_bootmenu_maintenance.c | 862 ++ lib/efi_loader/efi_boottime.c | 52 +- lib/efi_loader/efi_console.c | 81 ++ lib/efi_loader/efi_disk.c | 11 + lib/efi_loader/efi_file.c | 75 +- 8 files changed, 1133 insertions(+), 55 deletions(-) create mode 100644 lib/efi_loader/efi_bootmenu_maintenance.c diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c index eb23afdd41..860cb83182 100644 --- a/cmd/bootmenu.c +++ b/cmd/bootmenu.c @@ -21,6 +21,8 @@ /* maximum bootmenu entries */ #define MAX_COUNT 99 +#define STATIC_ENTRY 2 +#define MAX_DYNAMIC_ENTRY (MAX_COUNT - STATIC_ENTRY) /* maximal size of bootmenu env * 9 = strlen("bootmenu_") @@ -41,10 +43,11 @@ enum boot_type { BOOTMENU_TYPE_BOOTMENU, BOOTMENU_TYPE_UEFI_BOOT_OPTION, BOOTMENU_TYPE_DISTRO_BOOT, + BOOTMENU_TYPE_UEFI_MAINTENANCE, }; struct bootmenu_entry { - unsigned short int num; /* unique number 0 .. MAX_COUNT */ + unsigned short int num; /* unique number 0 .. MAX_DYNAMIC_ENTRY */ char key[3]; /* key identifier of number */ u16 *title; /* title of entry */ char *command; /* hush command of entry */ @@ -58,7 +61,7 @@ static char *bootmenu_getoption(unsigned short int n) { char name[MAX_ENV_SIZE]; - if (n > MAX_COUNT) + if (n > MAX_DYNAMIC_ENTRY) return NULL; sprintf(name, "bootmenu_%d", n); @@ -229,7 +232,7 @@ static int prepare_bootmenu_entry(struct bootmenu_data *menu, iter = entry; ++i; - if (i == MAX_COUNT - 1) + if (i == MAX_DYNAMIC_ENTRY) break; } @@ -317,7 +320,7 @@ static int prepare_uefi_bootorder_entry(struct bootmenu_data *menu, free(load_option); - if (i == MAX_COUNT - 1) + if (i == MAX_DYNAMIC_ENTRY) break; } @@ -481,7 +484,7 @@ static int prepare_distro_boot_entry(struct bootmenu_data *menu, iter = entry; i++; - if (i == MAX_COUNT - 1) + if (i == MAX_DYNAMIC_ENTRY) break; token = strtok(NULL, " "); @@ -520,19 +523,56 @@ static
Re: [PATCH v5 13/17] efi_loader: menu-driven addition of UEFI boot option
On 4/29/22 12:56, Heinrich Schuchardt wrote: On 4/28/22 18:33, Heinrich Schuchardt wrote: On 4/28/22 10:09, Masahisa Kojima wrote: This commit supports the menu-driven UEFI boot option addition. User can select the block device volume having efi_simple_file_system_protocol and select the file corresponding to the Boot variable. Then user enter the label of the BOOT variable in utf8. Signed-off-by: Masahisa Kojima --- Changes in v5: - remove forward declarations - add const qualifier for menu items - fix the possible unaligned access for directory info access - split into three commit 1)add boot option 2) delete boot option 3)change boot order This commit is 1)add boot option. - fix file name buffer allocation size, it should be EFI_BOOTMENU_FILE_PATH_MAX * sizeof(u16) - fix wrong size checking for file selection Chanes in v4: - UEFI boot option maintenance menu is integrated into bootmenu - display the simplified volume name(e.g. usb0:1, nvme1:2) for the volume selection - instead of extending lib/efi_loader/efi_bootmgr.c, newly create lib/efi_loader/efi_bootmenu_maintenance.c and implement boot variable maintenance into it. Changes in RFC v3: not included in v3 series Changes in RFC v2: - enable utf8 user input for boot option name - create lib/efi_loader/efi_console.c::efi_console_get_u16_string() for utf8 user input handling - use u16_strlcat instead of u16_strcat - remove the EFI_CALLs, and newly create or expose the following xxx_int() functions. efi_locate_handle_buffer_int(), efi_open_volume_int(), efi_file_open_int(), efi_file_close_int(), efi_file_read_int() and efi_file_setpos_int(). Note that EFI_CALLs still exist for EFI_DEVICE_PATH_TO_TEXT_PROTOCOL and EFI_SIMPLE_TEXT_INPUT/OUTPUT_PROTOCOL - use efi_search_protocol() instead of calling locate_protocol() to get the device_path_to_text_protocol interface. - remove unnecessary puts(ANSI_CLEAR_LINE), this patch is still depends on puts(ANSI_CLEAR_CONSOLE) - skip SetVariable() if the bootorder is not changed cmd/bootmenu.c | 69 +- include/efi_loader.h | 37 + lib/efi_loader/Makefile | 1 + lib/efi_loader/efi_bootmenu_maintenance.c | 862 ++ lib/efi_loader/efi_boottime.c | 52 +- lib/efi_loader/efi_console.c | 81 ++ lib/efi_loader/efi_disk.c | 11 + lib/efi_loader/efi_file.c | 75 +- 8 files changed, 1133 insertions(+), 55 deletions(-) create mode 100644 lib/efi_loader/efi_bootmenu_maintenance.c diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c index eb23afdd41..860cb83182 100644 --- a/cmd/bootmenu.c +++ b/cmd/bootmenu.c @@ -21,6 +21,8 @@ /* maximum bootmenu entries */ #define MAX_COUNT 99 +#define STATIC_ENTRY 2 +#define MAX_DYNAMIC_ENTRY (MAX_COUNT - STATIC_ENTRY) /* maximal size of bootmenu env * 9 = strlen("bootmenu_") @@ -41,10 +43,11 @@ enum boot_type { BOOTMENU_TYPE_BOOTMENU, BOOTMENU_TYPE_UEFI_BOOT_OPTION, BOOTMENU_TYPE_DISTRO_BOOT, + BOOTMENU_TYPE_UEFI_MAINTENANCE, }; struct bootmenu_entry { - unsigned short int num; /* unique number 0 .. MAX_COUNT */ + unsigned short int num; /* unique number 0 .. MAX_DYNAMIC_ENTRY */ char key[3]; /* key identifier of number */ u16 *title; /* title of entry */ char *command; /* hush command of entry */ @@ -58,7 +61,7 @@ static char *bootmenu_getoption(unsigned short int n) { char name[MAX_ENV_SIZE]; - if (n > MAX_COUNT) + if (n > MAX_DYNAMIC_ENTRY) return NULL; sprintf(name, "bootmenu_%d", n); @@ -229,7 +232,7 @@ static int prepare_bootmenu_entry(struct bootmenu_data *menu, iter = entry; ++i; - if (i == MAX_COUNT - 1) + if (i == MAX_DYNAMIC_ENTRY) break; } @@ -317,7 +320,7 @@ static int prepare_uefi_bootorder_entry(struct bootmenu_data *menu, free(load_option); - if (i == MAX_COUNT - 1) + if (i == MAX_DYNAMIC_ENTRY) break; } @@ -481,7 +484,7 @@ static int prepare_distro_boot_entry(struct bootmenu_data *menu, iter = entry; i++; - if (i == MAX_COUNT - 1) + if (i == MAX_DYNAMIC_ENTRY) break; token = strtok(NULL, " "); @@ -520,19 +523,56 @@ static struct bootmenu_data *bootmenu_create(int delay) goto cleanup; if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) { - if (i < MAX_COUNT - 1) { + if (i < MAX_DYNAMIC_ENTRY) { ret = prepare_uefi_bootorder_entry(menu, , ); if (ret < 0 && ret != -ENOENT) goto cleanup; } } - if (i < MAX_COUNT - 1) { + if (i < MAX_DYNAMIC_ENTRY) { ret = prepare_distro_boot_entry(menu, , ); if (ret < 0 && ret != -ENOENT) goto
Re: [PATCH v5 13/17] efi_loader: menu-driven addition of UEFI boot option
On 4/28/22 18:33, Heinrich Schuchardt wrote: On 4/28/22 10:09, Masahisa Kojima wrote: This commit supports the menu-driven UEFI boot option addition. User can select the block device volume having efi_simple_file_system_protocol and select the file corresponding to the Boot variable. Then user enter the label of the BOOT variable in utf8. Signed-off-by: Masahisa Kojima --- Changes in v5: - remove forward declarations - add const qualifier for menu items - fix the possible unaligned access for directory info access - split into three commit 1)add boot option 2) delete boot option 3)change boot order This commit is 1)add boot option. - fix file name buffer allocation size, it should be EFI_BOOTMENU_FILE_PATH_MAX * sizeof(u16) - fix wrong size checking for file selection Chanes in v4: - UEFI boot option maintenance menu is integrated into bootmenu - display the simplified volume name(e.g. usb0:1, nvme1:2) for the volume selection - instead of extending lib/efi_loader/efi_bootmgr.c, newly create lib/efi_loader/efi_bootmenu_maintenance.c and implement boot variable maintenance into it. Changes in RFC v3: not included in v3 series Changes in RFC v2: - enable utf8 user input for boot option name - create lib/efi_loader/efi_console.c::efi_console_get_u16_string() for utf8 user input handling - use u16_strlcat instead of u16_strcat - remove the EFI_CALLs, and newly create or expose the following xxx_int() functions. efi_locate_handle_buffer_int(), efi_open_volume_int(), efi_file_open_int(), efi_file_close_int(), efi_file_read_int() and efi_file_setpos_int(). Note that EFI_CALLs still exist for EFI_DEVICE_PATH_TO_TEXT_PROTOCOL and EFI_SIMPLE_TEXT_INPUT/OUTPUT_PROTOCOL - use efi_search_protocol() instead of calling locate_protocol() to get the device_path_to_text_protocol interface. - remove unnecessary puts(ANSI_CLEAR_LINE), this patch is still depends on puts(ANSI_CLEAR_CONSOLE) - skip SetVariable() if the bootorder is not changed cmd/bootmenu.c | 69 +- include/efi_loader.h | 37 + lib/efi_loader/Makefile | 1 + lib/efi_loader/efi_bootmenu_maintenance.c | 862 ++ lib/efi_loader/efi_boottime.c | 52 +- lib/efi_loader/efi_console.c | 81 ++ lib/efi_loader/efi_disk.c | 11 + lib/efi_loader/efi_file.c | 75 +- 8 files changed, 1133 insertions(+), 55 deletions(-) create mode 100644 lib/efi_loader/efi_bootmenu_maintenance.c diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c index eb23afdd41..860cb83182 100644 --- a/cmd/bootmenu.c +++ b/cmd/bootmenu.c @@ -21,6 +21,8 @@ /* maximum bootmenu entries */ #define MAX_COUNT 99 +#define STATIC_ENTRY 2 +#define MAX_DYNAMIC_ENTRY (MAX_COUNT - STATIC_ENTRY) /* maximal size of bootmenu env * 9 = strlen("bootmenu_") @@ -41,10 +43,11 @@ enum boot_type { BOOTMENU_TYPE_BOOTMENU, BOOTMENU_TYPE_UEFI_BOOT_OPTION, BOOTMENU_TYPE_DISTRO_BOOT, + BOOTMENU_TYPE_UEFI_MAINTENANCE, }; struct bootmenu_entry { - unsigned short int num; /* unique number 0 .. MAX_COUNT */ + unsigned short int num; /* unique number 0 .. MAX_DYNAMIC_ENTRY */ char key[3]; /* key identifier of number */ u16 *title; /* title of entry */ char *command; /* hush command of entry */ @@ -58,7 +61,7 @@ static char *bootmenu_getoption(unsigned short int n) { char name[MAX_ENV_SIZE]; - if (n > MAX_COUNT) + if (n > MAX_DYNAMIC_ENTRY) return NULL; sprintf(name, "bootmenu_%d", n); @@ -229,7 +232,7 @@ static int prepare_bootmenu_entry(struct bootmenu_data *menu, iter = entry; ++i; - if (i == MAX_COUNT - 1) + if (i == MAX_DYNAMIC_ENTRY) break; } @@ -317,7 +320,7 @@ static int prepare_uefi_bootorder_entry(struct bootmenu_data *menu, free(load_option); - if (i == MAX_COUNT - 1) + if (i == MAX_DYNAMIC_ENTRY) break; } @@ -481,7 +484,7 @@ static int prepare_distro_boot_entry(struct bootmenu_data *menu, iter = entry; i++; - if (i == MAX_COUNT - 1) + if (i == MAX_DYNAMIC_ENTRY) break; token = strtok(NULL, " "); @@ -520,19 +523,56 @@ static struct bootmenu_data *bootmenu_create(int delay) goto cleanup; if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) { - if (i < MAX_COUNT - 1) { + if (i < MAX_DYNAMIC_ENTRY) { ret = prepare_uefi_bootorder_entry(menu, , ); if (ret < 0 && ret != -ENOENT) goto cleanup; } } - if (i < MAX_COUNT - 1) { + if (i < MAX_DYNAMIC_ENTRY) { ret = prepare_distro_boot_entry(menu, , ); if (ret < 0 && ret != -ENOENT) goto cleanup; } + if
Re: [PATCH v5 13/17] efi_loader: menu-driven addition of UEFI boot option
On 4/28/22 10:09, Masahisa Kojima wrote: This commit supports the menu-driven UEFI boot option addition. User can select the block device volume having efi_simple_file_system_protocol and select the file corresponding to the Boot variable. Then user enter the label of the BOOT variable in utf8. Signed-off-by: Masahisa Kojima --- Changes in v5: - remove forward declarations - add const qualifier for menu items - fix the possible unaligned access for directory info access - split into three commit 1)add boot option 2) delete boot option 3)change boot order This commit is 1)add boot option. - fix file name buffer allocation size, it should be EFI_BOOTMENU_FILE_PATH_MAX * sizeof(u16) - fix wrong size checking for file selection Chanes in v4: - UEFI boot option maintenance menu is integrated into bootmenu - display the simplified volume name(e.g. usb0:1, nvme1:2) for the volume selection - instead of extending lib/efi_loader/efi_bootmgr.c, newly create lib/efi_loader/efi_bootmenu_maintenance.c and implement boot variable maintenance into it. Changes in RFC v3: not included in v3 series Changes in RFC v2: - enable utf8 user input for boot option name - create lib/efi_loader/efi_console.c::efi_console_get_u16_string() for utf8 user input handling - use u16_strlcat instead of u16_strcat - remove the EFI_CALLs, and newly create or expose the following xxx_int() functions. efi_locate_handle_buffer_int(), efi_open_volume_int(), efi_file_open_int(), efi_file_close_int(), efi_file_read_int() and efi_file_setpos_int(). Note that EFI_CALLs still exist for EFI_DEVICE_PATH_TO_TEXT_PROTOCOL and EFI_SIMPLE_TEXT_INPUT/OUTPUT_PROTOCOL - use efi_search_protocol() instead of calling locate_protocol() to get the device_path_to_text_protocol interface. - remove unnecessary puts(ANSI_CLEAR_LINE), this patch is still depends on puts(ANSI_CLEAR_CONSOLE) - skip SetVariable() if the bootorder is not changed cmd/bootmenu.c| 69 +- include/efi_loader.h | 37 + lib/efi_loader/Makefile | 1 + lib/efi_loader/efi_bootmenu_maintenance.c | 862 ++ lib/efi_loader/efi_boottime.c | 52 +- lib/efi_loader/efi_console.c | 81 ++ lib/efi_loader/efi_disk.c | 11 + lib/efi_loader/efi_file.c | 75 +- 8 files changed, 1133 insertions(+), 55 deletions(-) create mode 100644 lib/efi_loader/efi_bootmenu_maintenance.c diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c index eb23afdd41..860cb83182 100644 --- a/cmd/bootmenu.c +++ b/cmd/bootmenu.c @@ -21,6 +21,8 @@ /* maximum bootmenu entries */ #define MAX_COUNT 99 +#define STATIC_ENTRY 2 +#define MAX_DYNAMIC_ENTRY (MAX_COUNT - STATIC_ENTRY) /* maximal size of bootmenu env * 9 = strlen("bootmenu_") @@ -41,10 +43,11 @@ enum boot_type { BOOTMENU_TYPE_BOOTMENU, BOOTMENU_TYPE_UEFI_BOOT_OPTION, BOOTMENU_TYPE_DISTRO_BOOT, + BOOTMENU_TYPE_UEFI_MAINTENANCE, }; struct bootmenu_entry { - unsigned short int num; /* unique number 0 .. MAX_COUNT */ + unsigned short int num; /* unique number 0 .. MAX_DYNAMIC_ENTRY */ char key[3];/* key identifier of number */ u16 *title; /* title of entry */ char *command; /* hush command of entry */ @@ -58,7 +61,7 @@ static char *bootmenu_getoption(unsigned short int n) { char name[MAX_ENV_SIZE]; - if (n > MAX_COUNT) + if (n > MAX_DYNAMIC_ENTRY) return NULL; sprintf(name, "bootmenu_%d", n); @@ -229,7 +232,7 @@ static int prepare_bootmenu_entry(struct bootmenu_data *menu, iter = entry; ++i; - if (i == MAX_COUNT - 1) + if (i == MAX_DYNAMIC_ENTRY) break; } @@ -317,7 +320,7 @@ static int prepare_uefi_bootorder_entry(struct bootmenu_data *menu, free(load_option); - if (i == MAX_COUNT - 1) + if (i == MAX_DYNAMIC_ENTRY) break; } @@ -481,7 +484,7 @@ static int prepare_distro_boot_entry(struct bootmenu_data *menu, iter = entry; i++; - if (i == MAX_COUNT - 1) + if (i == MAX_DYNAMIC_ENTRY) break; token = strtok(NULL, " "); @@ -520,19 +523,56 @@ static struct bootmenu_data *bootmenu_create(int delay) goto cleanup; if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) { - if (i < MAX_COUNT - 1) { + if (i < MAX_DYNAMIC_ENTRY) { ret = prepare_uefi_bootorder_entry(menu, , ); if (ret < 0 && ret != -ENOENT) goto cleanup; } } - if (i < MAX_COUNT - 1) { +
[PATCH v5 13/17] efi_loader: menu-driven addition of UEFI boot option
This commit supports the menu-driven UEFI boot option addition. User can select the block device volume having efi_simple_file_system_protocol and select the file corresponding to the Boot variable. Then user enter the label of the BOOT variable in utf8. Signed-off-by: Masahisa Kojima --- Changes in v5: - remove forward declarations - add const qualifier for menu items - fix the possible unaligned access for directory info access - split into three commit 1)add boot option 2) delete boot option 3)change boot order This commit is 1)add boot option. - fix file name buffer allocation size, it should be EFI_BOOTMENU_FILE_PATH_MAX * sizeof(u16) - fix wrong size checking for file selection Chanes in v4: - UEFI boot option maintenance menu is integrated into bootmenu - display the simplified volume name(e.g. usb0:1, nvme1:2) for the volume selection - instead of extending lib/efi_loader/efi_bootmgr.c, newly create lib/efi_loader/efi_bootmenu_maintenance.c and implement boot variable maintenance into it. Changes in RFC v3: not included in v3 series Changes in RFC v2: - enable utf8 user input for boot option name - create lib/efi_loader/efi_console.c::efi_console_get_u16_string() for utf8 user input handling - use u16_strlcat instead of u16_strcat - remove the EFI_CALLs, and newly create or expose the following xxx_int() functions. efi_locate_handle_buffer_int(), efi_open_volume_int(), efi_file_open_int(), efi_file_close_int(), efi_file_read_int() and efi_file_setpos_int(). Note that EFI_CALLs still exist for EFI_DEVICE_PATH_TO_TEXT_PROTOCOL and EFI_SIMPLE_TEXT_INPUT/OUTPUT_PROTOCOL - use efi_search_protocol() instead of calling locate_protocol() to get the device_path_to_text_protocol interface. - remove unnecessary puts(ANSI_CLEAR_LINE), this patch is still depends on puts(ANSI_CLEAR_CONSOLE) - skip SetVariable() if the bootorder is not changed cmd/bootmenu.c| 69 +- include/efi_loader.h | 37 + lib/efi_loader/Makefile | 1 + lib/efi_loader/efi_bootmenu_maintenance.c | 862 ++ lib/efi_loader/efi_boottime.c | 52 +- lib/efi_loader/efi_console.c | 81 ++ lib/efi_loader/efi_disk.c | 11 + lib/efi_loader/efi_file.c | 75 +- 8 files changed, 1133 insertions(+), 55 deletions(-) create mode 100644 lib/efi_loader/efi_bootmenu_maintenance.c diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c index eb23afdd41..860cb83182 100644 --- a/cmd/bootmenu.c +++ b/cmd/bootmenu.c @@ -21,6 +21,8 @@ /* maximum bootmenu entries */ #define MAX_COUNT 99 +#define STATIC_ENTRY 2 +#define MAX_DYNAMIC_ENTRY (MAX_COUNT - STATIC_ENTRY) /* maximal size of bootmenu env * 9 = strlen("bootmenu_") @@ -41,10 +43,11 @@ enum boot_type { BOOTMENU_TYPE_BOOTMENU, BOOTMENU_TYPE_UEFI_BOOT_OPTION, BOOTMENU_TYPE_DISTRO_BOOT, + BOOTMENU_TYPE_UEFI_MAINTENANCE, }; struct bootmenu_entry { - unsigned short int num; /* unique number 0 .. MAX_COUNT */ + unsigned short int num; /* unique number 0 .. MAX_DYNAMIC_ENTRY */ char key[3];/* key identifier of number */ u16 *title; /* title of entry */ char *command; /* hush command of entry */ @@ -58,7 +61,7 @@ static char *bootmenu_getoption(unsigned short int n) { char name[MAX_ENV_SIZE]; - if (n > MAX_COUNT) + if (n > MAX_DYNAMIC_ENTRY) return NULL; sprintf(name, "bootmenu_%d", n); @@ -229,7 +232,7 @@ static int prepare_bootmenu_entry(struct bootmenu_data *menu, iter = entry; ++i; - if (i == MAX_COUNT - 1) + if (i == MAX_DYNAMIC_ENTRY) break; } @@ -317,7 +320,7 @@ static int prepare_uefi_bootorder_entry(struct bootmenu_data *menu, free(load_option); - if (i == MAX_COUNT - 1) + if (i == MAX_DYNAMIC_ENTRY) break; } @@ -481,7 +484,7 @@ static int prepare_distro_boot_entry(struct bootmenu_data *menu, iter = entry; i++; - if (i == MAX_COUNT - 1) + if (i == MAX_DYNAMIC_ENTRY) break; token = strtok(NULL, " "); @@ -520,19 +523,56 @@ static struct bootmenu_data *bootmenu_create(int delay) goto cleanup; if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) { - if (i < MAX_COUNT - 1) { + if (i < MAX_DYNAMIC_ENTRY) { ret = prepare_uefi_bootorder_entry(menu, , ); if (ret < 0 && ret != -ENOENT) goto cleanup; } } - if (i < MAX_COUNT - 1) { + if (i < MAX_DYNAMIC_ENTRY) { ret =