Re: [RFC PATCH v3 2/2] bootmenu: add UEFI and disto_boot entries

2022-03-09 Thread Ilias Apalodimas
[...]

> > > + 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

2022-03-09 Thread Masahisa Kojima
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

2022-03-09 Thread Masahisa Kojima
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

2022-03-09 Thread Takahiro Akashi
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

2022-03-09 Thread Takahiro Akashi
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

2022-03-09 Thread Ilias Apalodimas
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";
>