From: Ilias Apalodimas <ilias.apalodimas@linaro.org>
To: Masahisa Kojima <masahisa.kojima@linaro.org>
Cc: u-boot@lists.denx.de, Heinrich Schuchardt <xypron.glpk@gmx.de>,
Simon Glass <sjg@chromium.org>,
Takahiro Akashi <takahiro.akashi@linaro.org>,
Francois Ozog <francois.ozog@linaro.org>,
Mark Kettenis <mark.kettenis@xs4all.nl>,
Peng Fan <peng.fan@nxp.com>,
Jaehoon Chung <jh80.chung@samsung.com>,
Michal Simek <michal.simek@xilinx.com>,
Kory Maincent <kory.maincent@bootlin.com>,
Aswath Govindraju <a-govindraju@ti.com>,
Ovidiu Panait <ovidiu.panait@windriver.com>,
Ashok Reddy Soma <ashok.reddy.soma@xilinx.com>,
Franck LENORMAND <franck.lenormand@nxp.com>
Subject: Re: [PATCH v4 07/11] bootmenu: add UEFI and disto_boot entries
Date: Fri, 1 Apr 2022 09:08:46 +0300 [thread overview]
Message-ID: <YkaW7nyMBDa5pqti@hades> (raw)
In-Reply-To: <20220324135443.1571-8-masahisa.kojima@linaro.org>
Hi Kojima-san,
[...]
> + entry->title = u16_strdup(lo.label);
> + if (!entry->title) {
> + free(load_option);
> + free(entry);
We need to free bootorder as well
> + return -ENOMEM;
> + }
> + entry->command = strdup("bootefi bootmgr");
> + sprintf(entry->key, "%d", i);
> + entry->num = i;
> + entry->menu = menu;
> + entry->type = BOOTMENU_TYPE_UEFI_BOOT_OPTION;
> + entry->bootorder = bootorder[j];
> + entry->next = NULL;
> +
> + if (!iter)
> + menu->first = entry;
> + else
> + iter->next = entry;
> +
> + iter = entry;
> + i++;
> + }
> +
> + free(load_option);
> +
> + if (i == MAX_COUNT - 1)
> + break;
> + }
> +
> + free(bootorder);
> + *index = i;
> + *current = iter;
> +
> + return 1;
> +}
> +
> +static int prepare_distro_boot_entry(struct bootmenu_data *menu,
> + struct bootmenu_entry **current,
> + unsigned short int *index)
> +{
> + char *p;
> + int len;
> + char *token;
> + char *boot_targets;
> + unsigned short int i = *index;
> + struct bootmenu_entry *entry = NULL;
> + struct bootmenu_entry *iter = *current;
> +
> + /* list the distro boot "boot_targets" */
> + boot_targets = env_get("boot_targets");
> + if (!boot_targets)
> + return -ENOENT;
> +
> + len = strlen(boot_targets);
> + p = calloc(1, len + 1);
> + strlcpy(p, boot_targets, len);
> +
> + token = strtok(p, " ");
> +
> + do {
> + u16 *buf;
> + char *command;
> + int command_size;
> +
> + entry = malloc(sizeof(struct bootmenu_entry));
> + if (!entry)
> + return -ENOMEM;
> +
> + len = strlen(token);
> + buf = calloc(1, (len + 1) * sizeof(u16));
> + entry->title = buf;
> + if (!entry->title) {
> + free(entry);
> + return -ENOMEM;
> + }
> + utf8_utf16_strncpy(&buf, token, len);
> + sprintf(entry->key, "%d", i);
> + entry->num = i;
> + entry->menu = menu;
> +
> + command_size = sizeof("run bootcmd_") + len;
> + command = calloc(1, command_size);
> + if (!command) {
> + free(entry->title);
> + free(entry);
> + return -ENOMEM;
We need to free p as well
> + }
> + snprintf(command, command_size, "run bootcmd_%s", token);
> + entry->command = command;
> + entry->type = BOOTMENU_TYPE_DISTRO_BOOT;
> entry->next = NULL;
>
> if (!iter)
> @@ -341,10 +512,59 @@ static struct bootmenu_data *bootmenu_create(int delay)
> iter->next = entry;
>
> iter = entry;
> - ++i;
> + i++;
>
> if (i == MAX_COUNT - 1)
> break;
> +
> + token = strtok(NULL, " ");
> + } while (token);
> +
> + free(p);
> + *index = i;
> + *current = iter;
> +
> + return 1;
> +}
> +
> +static struct bootmenu_data *bootmenu_create(int delay)
> +{
> + int ret;
> + unsigned short int i = 0;
> + struct bootmenu_data *menu;
> + struct bootmenu_entry *iter = NULL;
> + struct bootmenu_entry *entry;
> +
> + char *default_str;
> +
> + menu = malloc(sizeof(struct bootmenu_data));
> + if (!menu)
> + return NULL;
> +
> + menu->delay = delay;
> + menu->active = 0;
> + menu->first = NULL;
> +
> + default_str = env_get("bootmenu_default");
> + if (default_str)
> + menu->active = (int)simple_strtol(default_str, NULL, 10);
> +
> + ret = prepare_bootmenu_entry(menu, &iter, &i);
> + if (ret < 0)
> + goto cleanup;
> +
> + if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) {
> + if (i < MAX_COUNT - 1) {
> + ret = prepare_uefi_bootorder_entry(menu, &iter, &i);
> + if (ret < 0 && ret != -ENOENT)
> + goto cleanup;
> + }
> + }
> +
> + if (i < MAX_COUNT - 1) {
> + ret = prepare_distro_boot_entry(menu, &iter, &i);
> + if (ret < 0 && ret != -ENOENT)
> + goto cleanup;
> }
>
> /* Add U-Boot console entry at the end */
> @@ -353,7 +573,12 @@ static struct bootmenu_data *bootmenu_create(int delay)
> if (!entry)
> goto cleanup;
>
> - entry->title = strdup("U-Boot console");
> + /* Add dummy entry if entering U-Boot console is disabled */
> + if (IS_ENABLED(CONFIG_CMD_BOOTMENU_ENTER_UBOOT_CONSOLE))
> + entry->title = u16_strdup(u"U-Boot console");
> + else
> + entry->title = u16_strdup(u"");
> +
> if (!entry->title) {
> free(entry);
> goto cleanup;
> @@ -370,6 +595,7 @@ static struct bootmenu_data *bootmenu_create(int delay)
>
> entry->num = i;
> entry->menu = menu;
> + entry->type = BOOTMENU_TYPE_NONE;
> entry->next = NULL;
>
> if (!iter)
> @@ -378,7 +604,7 @@ static struct bootmenu_data *bootmenu_create(int delay)
> iter->next = entry;
>
> iter = entry;
> - ++i;
> + i++;
> }
>
> menu->count = i;
> @@ -423,43 +649,73 @@ static void menu_display_statusline(struct menu *m)
> puts(ANSI_CLEAR_LINE);
> }
>
> -static void bootmenu_show(int delay)
> +static void handle_uefi_bootnext(void)
> {
> + u16 bootnext;
> + efi_status_t ret;
> + efi_uintn_t size;
> +
> + /* Initialize EFI drivers */
> + ret = efi_init_obj_list();
> + if (ret != EFI_SUCCESS) {
> + log_err("Error: Cannot initialize UEFI sub-system, r = %lu\n",
> + ret & ~EFI_ERROR_MASK);
> +
> + return;
> + }
> +
> + /* If UEFI BootNext variable is set, boot the BootNext load option */
> + size = sizeof(u16);
> + ret = efi_get_variable_int(u"BootNext",
> + &efi_global_variable_guid,
> + NULL, &size, &bootnext, NULL);
> + if (ret == EFI_SUCCESS)
> + /* BootNext does exist here, try to boot */
> + run_command("bootefi bootmgr", 0);
> +}
> +
> +static enum bootmenu_ret bootmenu_show(int delay)
> +{
> + int cmd_ret;
> int init = 0;
> void *choice = NULL;
> - char *title = NULL;
> + u16 *title = NULL;
> char *command = NULL;
> struct menu *menu;
> struct bootmenu_data *bootmenu;
> struct bootmenu_entry *iter;
> + efi_status_t efi_ret = EFI_SUCCESS;
> char *option, *sep;
>
> + if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR))
> + handle_uefi_bootnext();
> +
> /* If delay is 0 do not create menu, just run first entry */
> if (delay == 0) {
> option = bootmenu_getoption(0);
> if (!option) {
> puts("bootmenu option 0 was not found\n");
> - return;
> + return BOOTMENU_RET_FAIL;
> }
> sep = strchr(option, '=');
> if (!sep) {
> puts("bootmenu option 0 is invalid\n");
> - return;
> + return BOOTMENU_RET_FAIL;
> }
> - run_command(sep+1, 0);
> - return;
> + cmd_ret = run_command(sep + 1, 0);
> + return (cmd_ret == CMD_RET_SUCCESS ? BOOTMENU_RET_SUCCESS : BOOTMENU_RET_FAIL);
> }
>
> bootmenu = bootmenu_create(delay);
> if (!bootmenu)
> - return;
> + return BOOTMENU_RET_FAIL;
>
> menu = menu_create(NULL, bootmenu->delay, 1, menu_display_statusline,
> bootmenu_print_entry, bootmenu_choice_entry,
> bootmenu);
> if (!menu) {
> bootmenu_destroy(bootmenu);
> - return;
> + return BOOTMENU_RET_FAIL;
> }
>
> for (iter = bootmenu->first; iter; iter = iter->next) {
> @@ -478,8 +734,33 @@ static void bootmenu_show(int delay)
>
> if (menu_get_choice(menu, &choice) == 1) {
> iter = choice;
> - title = strdup(iter->title);
> + /* last entry is U-Boot console or Quit */
> + if (iter->num == iter->menu->count - 1) {
> + menu_destroy(menu);
> + bootmenu_destroy(bootmenu);
> + return BOOTMENU_RET_QUIT;
> + }
> +
> + title = u16_strdup(iter->title);
> command = strdup(iter->command);
> + } else {
> + goto cleanup;
> + }
> +
> + /*
> + * If the selected entry is UEFI BOOT####, set the BootNext variable.
> + * Then uefi bootmgr is invoked by the preset command in iter->command.
> + */
> + if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) {
> + if (iter->type == BOOTMENU_TYPE_UEFI_BOOT_OPTION) {
> + efi_ret = efi_set_variable_int(u"BootNext", &efi_global_variable_guid,
> + EFI_VARIABLE_NON_VOLATILE |
> + EFI_VARIABLE_BOOTSERVICE_ACCESS |
> + EFI_VARIABLE_RUNTIME_ACCESS,
> + sizeof(u16), &iter->bootorder, false);
> + if (efi_ret != EFI_SUCCESS)
> + goto cleanup;
> + }
> }
>
> cleanup:
> @@ -493,21 +774,47 @@ cleanup:
> }
>
> if (title && command) {
> - debug("Starting entry '%s'\n", title);
> + debug("Starting entry '%ls'\n", title);
> free(title);
> - run_command(command, 0);
> + if (efi_ret == EFI_SUCCESS)
> + cmd_ret = run_command(command, 0);
> free(command);
> }
>
> #ifdef CONFIG_POSTBOOTMENU
> run_command(CONFIG_POSTBOOTMENU, 0);
> #endif
> +
> + if (efi_ret == EFI_SUCCESS && cmd_ret == CMD_RET_SUCCESS)
> + return BOOTMENU_RET_SUCCESS;
> +
> + return BOOTMENU_RET_FAIL;
> }
>
> #ifdef CONFIG_AUTOBOOT_MENU_SHOW
> int menu_show(int bootdelay)
> {
> - bootmenu_show(bootdelay);
> + int ret;
> +
> + while (1) {
> + ret = bootmenu_show(bootdelay);
> + bootdelay = -1;
> + if (ret == BOOTMENU_RET_UPDATED)
> + continue;
> +
> + if (!IS_ENABLED(CONFIG_CMD_BOOTMENU_ENTER_UBOOT_CONSOLE)) {
> + if (ret == BOOTMENU_RET_QUIT) {
> + /* default boot process */
> + if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR))
> + run_command("bootefi bootmgr", 0);
> +
> + run_command("run bootcmd", 0);
> + }
> + } else {
> + break;
> + }
> + }
> +
> return -1; /* -1 - abort boot and run monitor code */
> }
> #endif
> --
> 2.17.1
>
Thanks
/Ilias
next prev parent reply other threads:[~2022-04-01 6:08 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-24 13:54 [PATCH v4 00/11] enable menu-driven boot device selection Masahisa Kojima
2022-03-24 13:54 ` [PATCH v4 01/11] bootmenu: fix menu API error handling Masahisa Kojima
2022-03-30 8:55 ` Ilias Apalodimas
2022-03-24 13:54 ` [PATCH v4 02/11] lib/charset: add u16_strlcat() function Masahisa Kojima
2022-04-02 7:14 ` Heinrich Schuchardt
2022-04-04 14:50 ` Masahisa Kojima
2022-04-16 7:32 ` Heinrich Schuchardt
2022-04-18 7:47 ` Masahisa Kojima
2022-04-28 7:45 ` Masahisa Kojima
2022-03-24 13:54 ` [PATCH v4 03/11] test: unit test for u16_strlcat() Masahisa Kojima
2022-04-02 7:47 ` Heinrich Schuchardt
2022-04-04 14:54 ` Masahisa Kojima
2022-03-24 13:54 ` [PATCH v4 04/11] menu: always show the menu regardless of the number of entry Masahisa Kojima
2022-04-02 7:56 ` Heinrich Schuchardt
2022-03-24 13:54 ` [PATCH v4 05/11] efi_loader: export efi_locate_device_handle() Masahisa Kojima
2022-04-01 5:43 ` Ilias Apalodimas
2022-03-24 13:54 ` [PATCH v4 06/11] efi_loader: bootmgr: add booting from removable media Masahisa Kojima
2022-03-30 19:13 ` Ilias Apalodimas
2022-03-31 0:51 ` Masahisa Kojima
2022-03-31 6:25 ` Ilias Apalodimas
2022-04-02 6:12 ` Heinrich Schuchardt
2022-04-04 6:48 ` Masahisa Kojima
2022-04-04 21:54 ` Heinrich Schuchardt
2022-03-24 13:54 ` [PATCH v4 07/11] bootmenu: add UEFI and disto_boot entries Masahisa Kojima
2022-04-01 6:08 ` Ilias Apalodimas [this message]
2022-04-02 6:33 ` Heinrich Schuchardt
2022-04-04 8:10 ` Masahisa Kojima
2022-03-24 13:54 ` [PATCH v4 08/11] bootmenu: factor out the user input handling Masahisa Kojima
2022-03-24 13:54 ` [PATCH v4 09/11] efi_loader: add menu-driven UEFI Boot Variable maintenance Masahisa Kojima
2022-03-31 8:31 ` Ilias Apalodimas
2022-04-14 9:25 ` Masahisa Kojima
2022-03-24 13:54 ` [PATCH v4 10/11] bootmenu: add removable media entries Masahisa Kojima
2022-03-31 8:48 ` Ilias Apalodimas
2022-03-31 10:18 ` Masahisa Kojima
2022-04-04 22:00 ` Heinrich Schuchardt
2022-03-24 13:54 ` [PATCH v4 11/11] doc:bootmenu: add UEFI boot variable and distro boot support Masahisa Kojima
2022-04-02 5:51 ` Heinrich Schuchardt
2022-03-25 1:20 ` [PATCH v4 00/11] enable menu-driven boot device selection Takahiro Akashi
2022-03-25 6:57 ` Masahisa Kojima
2022-04-02 5:48 ` Heinrich Schuchardt
2022-04-04 6:10 ` Masahisa Kojima
2022-04-16 6:46 ` Heinrich Schuchardt
2022-04-28 7:35 ` Masahisa Kojima
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=YkaW7nyMBDa5pqti@hades \
--to=ilias.apalodimas@linaro.org \
--cc=a-govindraju@ti.com \
--cc=ashok.reddy.soma@xilinx.com \
--cc=franck.lenormand@nxp.com \
--cc=francois.ozog@linaro.org \
--cc=jh80.chung@samsung.com \
--cc=kory.maincent@bootlin.com \
--cc=mark.kettenis@xs4all.nl \
--cc=masahisa.kojima@linaro.org \
--cc=michal.simek@xilinx.com \
--cc=ovidiu.panait@windriver.com \
--cc=peng.fan@nxp.com \
--cc=sjg@chromium.org \
--cc=takahiro.akashi@linaro.org \
--cc=u-boot@lists.denx.de \
--cc=xypron.glpk@gmx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.