Re: [RFC PATCH v3 2/2] bootmenu: add UEFI and disto_boot entries
[...] > > > + command = calloc(1, command_size); > > > + if (!command) { > > > + free(entry->title); > > > + free(load_option); > > > + free(entry); > > > + goto cleanup; > > > + } > > > + snprintf(command, command_size, "bootefi bootindex > > > %X", bootorder[j]); > > > + entry->command = command; > > > + sprintf(entry->key, "%d", i); > > > + entry->num = i; > > > + entry->menu = menu; > > > + entry->type = BOOT_TYPE_UEFI; > > > + entry->bootorder = bootorder[j]; > > > + entry->next = NULL; > > > + > > > + if (!iter) > > > + menu->first = entry; > > > + else > > > + iter->next = entry; > > > + > > > + iter = entry; > > > + ++i; > > > + } > > > + > > > + if (i == MAX_COUNT - 1) > > > + break; > > > + } > > > + free(bootorder); > > > +} > > > + > > > +bootmgr: > > > > Why do we need an entire menu entry if the bootorder is not defined? > > Currently there's no logic in the efibootmgr to look for the standard > > filenames in the ESP (eg bootarm.efi, bootaa64.efi etc) if no boot option > > is defined. Instead this is implement in distro_bootcmd. > > In this version, newly added command "bootefi bootindex " is called > if the user selects one of the "Boot" option, and "bootefi bootindex" > does not handle "BootNext". That's why I think the menu entry simply > call "bootefi bootmgr" is required. > Anyway, I will modify to set "BootNext" and call "bootefi bootmgr" if > the user selects a "Boot" option. > > I think we need to consider the case that "BootNext" is already set > when bootmenu comes up. > In this case, bootmenu must automatically try to boot the load option > of "BootNext" without any user interaction. Good point. Especially if we fix setvariable at runtime for specific boards, capsuleupdates will need this > > > > > I was thinking of something along the lines of: > > 1. bootmenu comes up > > 2. We read all the Boot variables that are defined and add them on the > >menu > > 2a. If the user doesn't explicitly choose a boot option we run 'bootefi > > bootmgr' > > 2b. If the user does select a different option we set BootNext and still > > run 'bootefi bootmgr' > > 3. If there's not Boot option defined, we should in the future add the > >functionality of searching for bootaa64.efi etc in ESP and still just > >launch the efi bootmgr > > Thank you very much for summarizing. > I would like to update as follows. > > 1. bootmenu comes up > 2. If the BootNext is already defined, try to boot with BootNext > without showing bootmenu > 3. We read the BootOrder, then read Boot with the order specified > by BootOrder and add it on the menu (UEFI spec requires to honor the > priorities set in BootOrder variable) > 3a. If the user doesn't explicitly choose a boot option we run 'bootefi > bootmgr' > 3b. If the user does select a different option we set BootNext and still > run 'bootefi bootmgr' > 4. If there's not Boot option defined, we should in the future add the >functionality of searching for bootaa64.efi etc in ESP and still just >launch the efi bootmgr > 4a. If "bootefi bootmgr" returns, run U-Boot "bootcmd" environment variable. > Yep, that looks correct > > > > > + /* Add UEFI Boot Manager entry if available */ > > > + if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) { [...] > > > + free(entry); > > > + goto cleanup; > > > + } > > > > Any idea of how we'll tackle that? We could export the efibootmgr > > functions that deal with this and use them on the edit menu ? > > I guess you are referring the RFC patch[*1] I sent before? > If yes, yes I will reuse them. Yes > Or do you mean the "efidebug" command? > > [*1] > https://lore.kernel.org/u-boot/20220225013257.15674-5-masahisa.koj...@linaro.org/ > > > > > > + > > > + sprintf(entry->key, "%d", i); > > > + > > > + entry->num = i; > > > + entry->menu = menu; > > > + entry->type = BOOT_TYPE_NONE; > > > + entry->next = NULL; > > > + > > > + if (!iter) > > > + menu->first = entry; > > > + else > > > + iter->next = entry; > > > + > > > + iter = entry; > > > + ++i; > > > } > > > > > > /* Add U-Boot console entry at the end */ > > > @@ -353,7 +602,7 @@ static struct bootmenu_data *bootmenu_create(int > > > delay) > > > if (!entry) > > >
Re: [RFC PATCH v3 2/2] bootmenu: add UEFI and disto_boot entries
On Thu, 10 Mar 2022 at 11:42, Takahiro Akashi wrote: > > On Thu, Mar 10, 2022 at 10:50:57AM +0900, Takahiro Akashi wrote: > > On Wed, Mar 09, 2022 at 04:34:42PM +0200, Ilias Apalodimas wrote: > > > Hi Kojima-san > > > > > > On Tue, Mar 08, 2022 at 11:07:45PM +0900, Masahisa Kojima wrote: > > > > This commit adds the UEFI related menu entries and > > > > distro_boot entries into the bootmenu. > > > > > > > > For UEFI, user can select which UEFI "Boot" option > > > > to execute, call UEFI bootmgr and UEFI boot variable > > > > maintenance menu. UEFI bootmgr entry is required to > > > > correctly handle "BootNext" variable. > > > > > > Hmm why? (some more info further down) > > > > > > > > > > > For distro_boot, user can select the boot device > > > > included in "boot_targets" u-boot environment variable. > > > > > > > > The menu example is as follows. > > > > > > > > *** U-Boot Boot Menu *** > > > > > > > > Boot 1. kernel (bootmenu_0) > > > > Boot 2. kernel (bootmenu_1) > > > > Reset board (bootmenu_2) > > > > debian (BOOT) > > > > ubuntu (BOOT0001) > > > > UEFI Boot Manager > > > > usb0 > > > > scsi0 > > > > virtio0 > > > > dhcp > > > > UEFI Boot Manager Maintenance > > > > U-Boot console > > > > > > > > Press UP/DOWN to move, ENTER to select, ESC/CTRL+C to quit > > > > > > > > Signed-off-by: Masahisa Kojima > > > > --- > > > > Changes in v3: > > > > - newly created > > > > > > > > cmd/bootmenu.c | 268 +++-- > > > > 1 file changed, 259 insertions(+), 9 deletions(-) > > > > > > > > diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c > > > > index 409ef9a848..a8dc50dcaa 100644 > > > > --- a/cmd/bootmenu.c > > > > +++ b/cmd/bootmenu.c > > > > @@ -3,9 +3,12 @@ > > > > * (C) Copyright 2011-2013 Pali Rohár > > > > */ > > > > > > > > +#include > > > > #include > > > > #include > > > > #include > > > > +#include > > > > +#include > > > > #include > > > > #include > > > > #include > > > > @@ -24,11 +27,20 @@ > > > > */ > > > > #define MAX_ENV_SIZE (9 + 2 + 1) > > > > > > > > +enum boot_type { > > > > + BOOT_TYPE_NONE = 0, > > > > + BOOT_TYPE_BOOTMENU, > > > > + BOOT_TYPE_UEFI, > > > > + BOOT_TYPE_DISTRO_BOOT, > > > > +}; > > > > + > > > > struct bootmenu_entry { > > > > unsigned short int num; /* unique number 0 .. MAX_COUNT */ > > > > char key[3];/* key identifier of number */ > > > > - char *title;/* title of entry */ > > > > + u16 *title; /* title of entry */ > > > > char *command; /* hush command of entry */ > > > > + enum boot_type type; > > > > + u16 bootorder; > > > > struct bootmenu_data *menu; /* this bootmenu */ > > > > struct bootmenu_entry *next;/* next menu entry (num+1) */ > > > > }; > > > > @@ -75,7 +87,12 @@ static void bootmenu_print_entry(void *data) > > > > if (reverse) > > > > puts(ANSI_COLOR_REVERSE); > > > > > > > > - puts(entry->title); > > > > + if (entry->type == BOOT_TYPE_BOOTMENU) > > > > + printf("%ls (bootmenu_%d)", entry->title, entry->bootorder); > > > > + else if (entry->type == BOOT_TYPE_UEFI) > > > > + printf("%ls (BOOT%04X)", entry->title, entry->bootorder); > > > > + else > > > > + printf("%ls", entry->title); > > > > > > > > if (reverse) > > > > puts(ANSI_COLOR_RESET); > > > > @@ -87,6 +104,10 @@ static void bootmenu_autoboot_loop(struct > > > > bootmenu_data *menu, > > > > int i, c; > > > > > > > > if (menu->delay > 0) { > > > > + /* flush input */ > > > > + while (tstc()) > > > > + getchar(); > > > > + > > > > printf(ANSI_CURSOR_POSITION, menu->count + 5, 1); > > > > printf(" Hit any key to stop autoboot: %2d ", menu->delay); > > > > } > > > > @@ -300,6 +321,8 @@ static struct bootmenu_data *bootmenu_create(int > > > > delay) > > > > menu->active = (int)simple_strtol(default_str, NULL, 10); > > > > > > > > while ((option = bootmenu_getoption(i))) { > > > > + u16 *buf; > > > > + > > > > sep = strchr(option, '='); > > > > if (!sep) { > > > > printf("Invalid bootmenu entry: %s\n", option); > > > > @@ -311,13 +334,13 @@ static struct bootmenu_data *bootmenu_create(int > > > > delay) > > > > goto cleanup; > > > > > > > > len = sep-option; > > > > - entry->title = malloc(len + 1); > > > > + buf = calloc(1, (len + 1) * sizeof(u16)); > > > > + entry->title = buf; > > > > if (!entry->title) { > > > > free(entry); > > > > goto cleanup; > > > > } > > > > - memcpy(entry->title, option, len); > > > > - entry->title[len] = 0; > > > > + utf8_utf16_strncpy(, option, len); > > > > > > > > len = strlen(sep + 1); > > > > entry->command =
Re: [RFC PATCH v3 2/2] bootmenu: add UEFI and disto_boot entries
Hi Ilias, On Wed, 9 Mar 2022 at 23:34, Ilias Apalodimas wrote: > > Hi Kojima-san > > On Tue, Mar 08, 2022 at 11:07:45PM +0900, Masahisa Kojima wrote: > > This commit adds the UEFI related menu entries and > > distro_boot entries into the bootmenu. > > > > For UEFI, user can select which UEFI "Boot" option > > to execute, call UEFI bootmgr and UEFI boot variable > > maintenance menu. UEFI bootmgr entry is required to > > correctly handle "BootNext" variable. > > Hmm why? (some more info further down) > > > > > For distro_boot, user can select the boot device > > included in "boot_targets" u-boot environment variable. > > > > The menu example is as follows. > > > > *** U-Boot Boot Menu *** > > > > Boot 1. kernel (bootmenu_0) > > Boot 2. kernel (bootmenu_1) > > Reset board (bootmenu_2) > > debian (BOOT) > > ubuntu (BOOT0001) > > UEFI Boot Manager > > usb0 > > scsi0 > > virtio0 > > dhcp > > UEFI Boot Manager Maintenance > > U-Boot console > > > > Press UP/DOWN to move, ENTER to select, ESC/CTRL+C to quit > > > > Signed-off-by: Masahisa Kojima > > --- > > Changes in v3: > > - newly created > > > > cmd/bootmenu.c | 268 +++-- > > 1 file changed, 259 insertions(+), 9 deletions(-) > > > > diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c > > index 409ef9a848..a8dc50dcaa 100644 > > --- a/cmd/bootmenu.c > > +++ b/cmd/bootmenu.c > > @@ -3,9 +3,12 @@ > > * (C) Copyright 2011-2013 Pali Rohár > > */ > > > > +#include > > #include > > #include > > #include > > +#include > > +#include > > #include > > #include > > #include > > @@ -24,11 +27,20 @@ > > */ > > #define MAX_ENV_SIZE (9 + 2 + 1) > > > > +enum boot_type { > > + BOOT_TYPE_NONE = 0, > > + BOOT_TYPE_BOOTMENU, > > + BOOT_TYPE_UEFI, > > + BOOT_TYPE_DISTRO_BOOT, > > +}; > > + > > struct bootmenu_entry { > > unsigned short int num; /* unique number 0 .. MAX_COUNT */ > > char key[3];/* key identifier of number */ > > - char *title;/* title of entry */ > > + u16 *title; /* title of entry */ > > char *command; /* hush command of entry */ > > + enum boot_type type; > > + u16 bootorder; > > struct bootmenu_data *menu; /* this bootmenu */ > > struct bootmenu_entry *next;/* next menu entry (num+1) */ > > }; > > @@ -75,7 +87,12 @@ static void bootmenu_print_entry(void *data) > > if (reverse) > > puts(ANSI_COLOR_REVERSE); > > > > - puts(entry->title); > > + if (entry->type == BOOT_TYPE_BOOTMENU) > > + printf("%ls (bootmenu_%d)", entry->title, entry->bootorder); > > + else if (entry->type == BOOT_TYPE_UEFI) > > + printf("%ls (BOOT%04X)", entry->title, entry->bootorder); > > + else > > + printf("%ls", entry->title); > > > > if (reverse) > > puts(ANSI_COLOR_RESET); > > @@ -87,6 +104,10 @@ static void bootmenu_autoboot_loop(struct bootmenu_data > > *menu, > > int i, c; > > > > if (menu->delay > 0) { > > + /* flush input */ > > + while (tstc()) > > + getchar(); > > + > > printf(ANSI_CURSOR_POSITION, menu->count + 5, 1); > > printf(" Hit any key to stop autoboot: %2d ", menu->delay); > > } > > @@ -300,6 +321,8 @@ static struct bootmenu_data *bootmenu_create(int delay) > > menu->active = (int)simple_strtol(default_str, NULL, 10); > > > > while ((option = bootmenu_getoption(i))) { > > + u16 *buf; > > + > > sep = strchr(option, '='); > > if (!sep) { > > printf("Invalid bootmenu entry: %s\n", option); > > @@ -311,13 +334,13 @@ static struct bootmenu_data *bootmenu_create(int > > delay) > > goto cleanup; > > > > len = sep-option; > > - entry->title = malloc(len + 1); > > + buf = calloc(1, (len + 1) * sizeof(u16)); > > + entry->title = buf; > > if (!entry->title) { > > free(entry); > > goto cleanup; > > } > > - memcpy(entry->title, option, len); > > - entry->title[len] = 0; > > + utf8_utf16_strncpy(, option, len); > > > > len = strlen(sep + 1); > > entry->command = malloc(len + 1); > > @@ -333,6 +356,190 @@ static struct bootmenu_data *bootmenu_create(int > > delay) > > > > entry->num = i; > > entry->menu = menu; > > + entry->type = BOOT_TYPE_BOOTMENU; > > + entry->bootorder = i; > > + entry->next = NULL; > > + > > + if (!iter) > > + menu->first = entry; > > + else > > + iter->next = entry; > > + > > +
Re: [RFC PATCH v3 2/2] bootmenu: add UEFI and disto_boot entries
On Thu, Mar 10, 2022 at 10:50:57AM +0900, Takahiro Akashi wrote: > On Wed, Mar 09, 2022 at 04:34:42PM +0200, Ilias Apalodimas wrote: > > Hi Kojima-san > > > > On Tue, Mar 08, 2022 at 11:07:45PM +0900, Masahisa Kojima wrote: > > > This commit adds the UEFI related menu entries and > > > distro_boot entries into the bootmenu. > > > > > > For UEFI, user can select which UEFI "Boot" option > > > to execute, call UEFI bootmgr and UEFI boot variable > > > maintenance menu. UEFI bootmgr entry is required to > > > correctly handle "BootNext" variable. > > > > Hmm why? (some more info further down) > > > > > > > > For distro_boot, user can select the boot device > > > included in "boot_targets" u-boot environment variable. > > > > > > The menu example is as follows. > > > > > > *** U-Boot Boot Menu *** > > > > > > Boot 1. kernel (bootmenu_0) > > > Boot 2. kernel (bootmenu_1) > > > Reset board (bootmenu_2) > > > debian (BOOT) > > > ubuntu (BOOT0001) > > > UEFI Boot Manager > > > usb0 > > > scsi0 > > > virtio0 > > > dhcp > > > UEFI Boot Manager Maintenance > > > U-Boot console > > > > > > Press UP/DOWN to move, ENTER to select, ESC/CTRL+C to quit > > > > > > Signed-off-by: Masahisa Kojima > > > --- > > > Changes in v3: > > > - newly created > > > > > > cmd/bootmenu.c | 268 +++-- > > > 1 file changed, 259 insertions(+), 9 deletions(-) > > > > > > diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c > > > index 409ef9a848..a8dc50dcaa 100644 > > > --- a/cmd/bootmenu.c > > > +++ b/cmd/bootmenu.c > > > @@ -3,9 +3,12 @@ > > > * (C) Copyright 2011-2013 Pali Rohár > > > */ > > > > > > +#include > > > #include > > > #include > > > #include > > > +#include > > > +#include > > > #include > > > #include > > > #include > > > @@ -24,11 +27,20 @@ > > > */ > > > #define MAX_ENV_SIZE (9 + 2 + 1) > > > > > > +enum boot_type { > > > + BOOT_TYPE_NONE = 0, > > > + BOOT_TYPE_BOOTMENU, > > > + BOOT_TYPE_UEFI, > > > + BOOT_TYPE_DISTRO_BOOT, > > > +}; > > > + > > > struct bootmenu_entry { > > > unsigned short int num; /* unique number 0 .. MAX_COUNT */ > > > char key[3];/* key identifier of number */ > > > - char *title;/* title of entry */ > > > + u16 *title; /* title of entry */ > > > char *command; /* hush command of entry */ > > > + enum boot_type type; > > > + u16 bootorder; > > > struct bootmenu_data *menu; /* this bootmenu */ > > > struct bootmenu_entry *next;/* next menu entry (num+1) */ > > > }; > > > @@ -75,7 +87,12 @@ static void bootmenu_print_entry(void *data) > > > if (reverse) > > > puts(ANSI_COLOR_REVERSE); > > > > > > - puts(entry->title); > > > + if (entry->type == BOOT_TYPE_BOOTMENU) > > > + printf("%ls (bootmenu_%d)", entry->title, entry->bootorder); > > > + else if (entry->type == BOOT_TYPE_UEFI) > > > + printf("%ls (BOOT%04X)", entry->title, entry->bootorder); > > > + else > > > + printf("%ls", entry->title); > > > > > > if (reverse) > > > puts(ANSI_COLOR_RESET); > > > @@ -87,6 +104,10 @@ static void bootmenu_autoboot_loop(struct > > > bootmenu_data *menu, > > > int i, c; > > > > > > if (menu->delay > 0) { > > > + /* flush input */ > > > + while (tstc()) > > > + getchar(); > > > + > > > printf(ANSI_CURSOR_POSITION, menu->count + 5, 1); > > > printf(" Hit any key to stop autoboot: %2d ", menu->delay); > > > } > > > @@ -300,6 +321,8 @@ static struct bootmenu_data *bootmenu_create(int > > > delay) > > > menu->active = (int)simple_strtol(default_str, NULL, 10); > > > > > > while ((option = bootmenu_getoption(i))) { > > > + u16 *buf; > > > + > > > sep = strchr(option, '='); > > > if (!sep) { > > > printf("Invalid bootmenu entry: %s\n", option); > > > @@ -311,13 +334,13 @@ static struct bootmenu_data *bootmenu_create(int > > > delay) > > > goto cleanup; > > > > > > len = sep-option; > > > - entry->title = malloc(len + 1); > > > + buf = calloc(1, (len + 1) * sizeof(u16)); > > > + entry->title = buf; > > > if (!entry->title) { > > > free(entry); > > > goto cleanup; > > > } > > > - memcpy(entry->title, option, len); > > > - entry->title[len] = 0; > > > + utf8_utf16_strncpy(, option, len); > > > > > > len = strlen(sep + 1); > > > entry->command = malloc(len + 1); > > > @@ -333,6 +356,190 @@ static struct bootmenu_data *bootmenu_create(int > > > delay) > > > > > > entry->num = i; > > > entry->menu = menu; > > > + entry->type = BOOT_TYPE_BOOTMENU; > > > + entry->bootorder = i; > > > + entry->next = NULL;
Re: [RFC PATCH v3 2/2] bootmenu: add UEFI and disto_boot entries
On Wed, Mar 09, 2022 at 04:34:42PM +0200, Ilias Apalodimas wrote: > Hi Kojima-san > > On Tue, Mar 08, 2022 at 11:07:45PM +0900, Masahisa Kojima wrote: > > This commit adds the UEFI related menu entries and > > distro_boot entries into the bootmenu. > > > > For UEFI, user can select which UEFI "Boot" option > > to execute, call UEFI bootmgr and UEFI boot variable > > maintenance menu. UEFI bootmgr entry is required to > > correctly handle "BootNext" variable. > > Hmm why? (some more info further down) > > > > > For distro_boot, user can select the boot device > > included in "boot_targets" u-boot environment variable. > > > > The menu example is as follows. > > > > *** U-Boot Boot Menu *** > > > > Boot 1. kernel (bootmenu_0) > > Boot 2. kernel (bootmenu_1) > > Reset board (bootmenu_2) > > debian (BOOT) > > ubuntu (BOOT0001) > > UEFI Boot Manager > > usb0 > > scsi0 > > virtio0 > > dhcp > > UEFI Boot Manager Maintenance > > U-Boot console > > > > Press UP/DOWN to move, ENTER to select, ESC/CTRL+C to quit > > > > Signed-off-by: Masahisa Kojima > > --- > > Changes in v3: > > - newly created > > > > cmd/bootmenu.c | 268 +++-- > > 1 file changed, 259 insertions(+), 9 deletions(-) > > > > diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c > > index 409ef9a848..a8dc50dcaa 100644 > > --- a/cmd/bootmenu.c > > +++ b/cmd/bootmenu.c > > @@ -3,9 +3,12 @@ > > * (C) Copyright 2011-2013 Pali Rohár > > */ > > > > +#include > > #include > > #include > > #include > > +#include > > +#include > > #include > > #include > > #include > > @@ -24,11 +27,20 @@ > > */ > > #define MAX_ENV_SIZE (9 + 2 + 1) > > > > +enum boot_type { > > + BOOT_TYPE_NONE = 0, > > + BOOT_TYPE_BOOTMENU, > > + BOOT_TYPE_UEFI, > > + BOOT_TYPE_DISTRO_BOOT, > > +}; > > + > > struct bootmenu_entry { > > unsigned short int num; /* unique number 0 .. MAX_COUNT */ > > char key[3];/* key identifier of number */ > > - char *title;/* title of entry */ > > + u16 *title; /* title of entry */ > > char *command; /* hush command of entry */ > > + enum boot_type type; > > + u16 bootorder; > > struct bootmenu_data *menu; /* this bootmenu */ > > struct bootmenu_entry *next;/* next menu entry (num+1) */ > > }; > > @@ -75,7 +87,12 @@ static void bootmenu_print_entry(void *data) > > if (reverse) > > puts(ANSI_COLOR_REVERSE); > > > > - puts(entry->title); > > + if (entry->type == BOOT_TYPE_BOOTMENU) > > + printf("%ls (bootmenu_%d)", entry->title, entry->bootorder); > > + else if (entry->type == BOOT_TYPE_UEFI) > > + printf("%ls (BOOT%04X)", entry->title, entry->bootorder); > > + else > > + printf("%ls", entry->title); > > > > if (reverse) > > puts(ANSI_COLOR_RESET); > > @@ -87,6 +104,10 @@ static void bootmenu_autoboot_loop(struct bootmenu_data > > *menu, > > int i, c; > > > > if (menu->delay > 0) { > > + /* flush input */ > > + while (tstc()) > > + getchar(); > > + > > printf(ANSI_CURSOR_POSITION, menu->count + 5, 1); > > printf(" Hit any key to stop autoboot: %2d ", menu->delay); > > } > > @@ -300,6 +321,8 @@ static struct bootmenu_data *bootmenu_create(int delay) > > menu->active = (int)simple_strtol(default_str, NULL, 10); > > > > while ((option = bootmenu_getoption(i))) { > > + u16 *buf; > > + > > sep = strchr(option, '='); > > if (!sep) { > > printf("Invalid bootmenu entry: %s\n", option); > > @@ -311,13 +334,13 @@ static struct bootmenu_data *bootmenu_create(int > > delay) > > goto cleanup; > > > > len = sep-option; > > - entry->title = malloc(len + 1); > > + buf = calloc(1, (len + 1) * sizeof(u16)); > > + entry->title = buf; > > if (!entry->title) { > > free(entry); > > goto cleanup; > > } > > - memcpy(entry->title, option, len); > > - entry->title[len] = 0; > > + utf8_utf16_strncpy(, option, len); > > > > len = strlen(sep + 1); > > entry->command = malloc(len + 1); > > @@ -333,6 +356,190 @@ static struct bootmenu_data *bootmenu_create(int > > delay) > > > > entry->num = i; > > entry->menu = menu; > > + entry->type = BOOT_TYPE_BOOTMENU; > > + entry->bootorder = i; > > + entry->next = NULL; > > + > > + if (!iter) > > + menu->first = entry; > > + else > > + iter->next = entry; > > + > > + iter = entry; > > + ++i; > > + > > + if (i == MAX_COUNT - 1)
Re: [RFC PATCH v3 2/2] bootmenu: add UEFI and disto_boot entries
Hi Kojima-san On Tue, Mar 08, 2022 at 11:07:45PM +0900, Masahisa Kojima wrote: > This commit adds the UEFI related menu entries and > distro_boot entries into the bootmenu. > > For UEFI, user can select which UEFI "Boot" option > to execute, call UEFI bootmgr and UEFI boot variable > maintenance menu. UEFI bootmgr entry is required to > correctly handle "BootNext" variable. Hmm why? (some more info further down) > > For distro_boot, user can select the boot device > included in "boot_targets" u-boot environment variable. > > The menu example is as follows. > > *** U-Boot Boot Menu *** > > Boot 1. kernel (bootmenu_0) > Boot 2. kernel (bootmenu_1) > Reset board (bootmenu_2) > debian (BOOT) > ubuntu (BOOT0001) > UEFI Boot Manager > usb0 > scsi0 > virtio0 > dhcp > UEFI Boot Manager Maintenance > U-Boot console > > Press UP/DOWN to move, ENTER to select, ESC/CTRL+C to quit > > Signed-off-by: Masahisa Kojima > --- > Changes in v3: > - newly created > > cmd/bootmenu.c | 268 +++-- > 1 file changed, 259 insertions(+), 9 deletions(-) > > diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c > index 409ef9a848..a8dc50dcaa 100644 > --- a/cmd/bootmenu.c > +++ b/cmd/bootmenu.c > @@ -3,9 +3,12 @@ > * (C) Copyright 2011-2013 Pali Rohár > */ > > +#include > #include > #include > #include > +#include > +#include > #include > #include > #include > @@ -24,11 +27,20 @@ > */ > #define MAX_ENV_SIZE (9 + 2 + 1) > > +enum boot_type { > + BOOT_TYPE_NONE = 0, > + BOOT_TYPE_BOOTMENU, > + BOOT_TYPE_UEFI, > + BOOT_TYPE_DISTRO_BOOT, > +}; > + > struct bootmenu_entry { > unsigned short int num; /* unique number 0 .. MAX_COUNT */ > char key[3];/* key identifier of number */ > - char *title;/* title of entry */ > + u16 *title; /* title of entry */ > char *command; /* hush command of entry */ > + enum boot_type type; > + u16 bootorder; > struct bootmenu_data *menu; /* this bootmenu */ > struct bootmenu_entry *next;/* next menu entry (num+1) */ > }; > @@ -75,7 +87,12 @@ static void bootmenu_print_entry(void *data) > if (reverse) > puts(ANSI_COLOR_REVERSE); > > - puts(entry->title); > + if (entry->type == BOOT_TYPE_BOOTMENU) > + printf("%ls (bootmenu_%d)", entry->title, entry->bootorder); > + else if (entry->type == BOOT_TYPE_UEFI) > + printf("%ls (BOOT%04X)", entry->title, entry->bootorder); > + else > + printf("%ls", entry->title); > > if (reverse) > puts(ANSI_COLOR_RESET); > @@ -87,6 +104,10 @@ static void bootmenu_autoboot_loop(struct bootmenu_data > *menu, > int i, c; > > if (menu->delay > 0) { > + /* flush input */ > + while (tstc()) > + getchar(); > + > printf(ANSI_CURSOR_POSITION, menu->count + 5, 1); > printf(" Hit any key to stop autoboot: %2d ", menu->delay); > } > @@ -300,6 +321,8 @@ static struct bootmenu_data *bootmenu_create(int delay) > menu->active = (int)simple_strtol(default_str, NULL, 10); > > while ((option = bootmenu_getoption(i))) { > + u16 *buf; > + > sep = strchr(option, '='); > if (!sep) { > printf("Invalid bootmenu entry: %s\n", option); > @@ -311,13 +334,13 @@ static struct bootmenu_data *bootmenu_create(int delay) > goto cleanup; > > len = sep-option; > - entry->title = malloc(len + 1); > + buf = calloc(1, (len + 1) * sizeof(u16)); > + entry->title = buf; > if (!entry->title) { > free(entry); > goto cleanup; > } > - memcpy(entry->title, option, len); > - entry->title[len] = 0; > + utf8_utf16_strncpy(, option, len); > > len = strlen(sep + 1); > entry->command = malloc(len + 1); > @@ -333,6 +356,190 @@ static struct bootmenu_data *bootmenu_create(int delay) > > entry->num = i; > entry->menu = menu; > + entry->type = BOOT_TYPE_BOOTMENU; > + entry->bootorder = i; > + entry->next = NULL; > + > + if (!iter) > + menu->first = entry; > + else > + iter->next = entry; > + > + iter = entry; > + ++i; > + > + if (i == MAX_COUNT - 1) > + break; > + } > + > +{ > + u16 *bootorder; > + efi_status_t ret; > + unsigned short j; > + efi_uintn_t num, size; > + void *load_option; > + struct efi_load_option lo; > + u16 varname[] = u"Boot"; >