[PATCH v5 08/17] bootmenu: update bootmenu_entry structure
Heinrich Schuchardt
xypron.glpk at gmx.de
Fri Apr 29 21:51:31 CEST 2022
On 4/28/22 10:09, Masahisa Kojima wrote:
> This is a preparation for succeeding addition of uefi boot
> and distro boot menu entries into bootmenu.
> The bootmenu_entry title is updated to u16 string because
> uefi use u16 string. This commit also factors out the function
> to prepare the entries generated by "bootmenu_x" U-Boot environment
> variable.
>
> This commit also updates the bootmenu entry title.
> The entry derived from "bootmenu_x" U-Boot environment variable
> has the "bootmenu_xx" prefix as below.
>
> *** U-Boot Boot Menu ***
>
> bootmenu_00 : Boot 1. kernel
> bootmenu_01 : Boot 2. kernel
> bootmenu_02 : Reset board
>
> Signed-off-by: Masahisa Kojima <masahisa.kojima at linaro.org>
> ---
> Changes in v5:
> - split into the separate patch
> - add function description comment
>
> cmd/bootmenu.c | 110 +++++++++++++++++++++++++++++++++++--------------
> 1 file changed, 78 insertions(+), 32 deletions(-)
>
> diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c
> index 9a32a18b19..15ad621c9f 100644
> --- a/cmd/bootmenu.c
> +++ b/cmd/bootmenu.c
> @@ -3,6 +3,7 @@
> * (C) Copyright 2011-2013 Pali Rohár <pali at kernel.org>
> */
>
> +#include <charset.h>
> #include <common.h>
> #include <command.h>
> #include <ansi.h>
> @@ -24,11 +25,18 @@
> */
> #define MAX_ENV_SIZE (9 + 2 + 1)
>
> +enum boot_type {
> + BOOTMENU_TYPE_NONE = 0,
> + BOOTMENU_TYPE_BOOTMENU,
> +};
> +
> 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; /* boot type of entry */
> + u16 bootorder; /* order for each boot type */
> struct bootmenu_data *menu; /* this bootmenu */
> struct bootmenu_entry *next; /* next menu entry (num+1) */
> };
> @@ -75,7 +83,10 @@ static void bootmenu_print_entry(void *data)
> if (reverse)
> puts(ANSI_COLOR_REVERSE);
>
> - puts(entry->title);
> + if (entry->type == BOOTMENU_TYPE_BOOTMENU)
> + printf("bootmenu_%02d : %ls", entry->bootorder, entry->title);
> + else
> + printf("%ls", entry->title);
>
> if (reverse)
> puts(ANSI_COLOR_RESET);
> @@ -279,31 +290,32 @@ static void bootmenu_destroy(struct bootmenu_data *menu)
> free(menu);
> }
>
> -static struct bootmenu_data *bootmenu_create(int delay)
> +/**
> + * prepare_bootmenu_entry() - generate the bootmenu_xx entries
> + *
> + * This function read the "bootmenu_x" U-Boot environment variable
> + * and generate the bootmenu entries.
> + *
> + * @menu: pointer to the bootmenu structure
> + * @current: pointer to the last bootmenu entry list
> + * @index: pointer to the index of the last bootmenu entry,
> + * the number of bootmenu entry is added by this function
> + * Return: 1 on success, negative value on error
> + */
> +static int prepare_bootmenu_entry(struct bootmenu_data *menu,
> + struct bootmenu_entry **current,
> + unsigned short int *index)
> {
> - unsigned short int i = 0;
> - const char *option;
> - struct bootmenu_data *menu;
> - struct bootmenu_entry *iter = NULL;
> -
> int len;
> char *sep;
> - char *default_str;
> - struct bootmenu_entry *entry;
> -
> - 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);
> + const char *option;
> + unsigned short int i = *index;
> + struct bootmenu_entry *entry = NULL;
> + struct bootmenu_entry *iter = *current;
>
> while ((option = bootmenu_getoption(i))) {
> + u16 *buf;
> +
> sep = strchr(option, '=');
> if (!sep) {
> printf("Invalid bootmenu entry: %s\n", option);
> @@ -312,23 +324,23 @@ static struct bootmenu_data *bootmenu_create(int delay)
>
> entry = malloc(sizeof(struct bootmenu_entry));
> if (!entry)
> - goto cleanup;
> + return -ENOMEM;
>
> 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;
> + return -ENOMEM;
> }
> - memcpy(entry->title, option, len);
> - entry->title[len] = 0;
> + utf8_utf16_strncpy(&buf, option, len);
>
> len = strlen(sep + 1);
> entry->command = malloc(len + 1);
> if (!entry->command) {
> free(entry->title);
> free(entry);
> - goto cleanup;
> + return -ENOMEM;
> }
> memcpy(entry->command, sep + 1, len);
> entry->command[len] = 0;
> @@ -337,6 +349,8 @@ static struct bootmenu_data *bootmenu_create(int delay)
>
> entry->num = i;
> entry->menu = menu;
> + entry->type = BOOTMENU_TYPE_BOOTMENU;
> + entry->bootorder = i;
> entry->next = NULL;
>
> if (!iter)
> @@ -351,13 +365,44 @@ static struct bootmenu_data *bootmenu_create(int delay)
> break;
> }
>
> + *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;
> +
> /* Add U-Boot console entry at the end */
> if (i <= MAX_COUNT - 1) {
> entry = malloc(sizeof(struct bootmenu_entry));
> if (!entry)
> goto cleanup;
>
> - entry->title = strdup("U-Boot console");
> + entry->title = u16_strdup(u"U-Boot console");
> if (!entry->title) {
> free(entry);
> goto cleanup;
> @@ -374,6 +419,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)
> @@ -431,7 +477,7 @@ static void bootmenu_show(int delay)
> {
> int init = 0;
> void *choice = NULL;
> - char *title = NULL;
> + u16 *title = NULL;
> char *command = NULL;
> struct menu *menu;
> struct bootmenu_data *bootmenu;
> @@ -482,7 +528,7 @@ static void bootmenu_show(int delay)
>
> if (menu_get_choice(menu, &choice) == 1) {
> iter = choice;
> - title = strdup(iter->title);
> + title = u16_strdup(iter->title);
We must still be able to use the bootmenu command outside of the UEFI
sub-system. There wide strings will not be used.
We need a testcase for this.
Best regards
Heinrich
> command = strdup(iter->command);
> }
>
> @@ -497,7 +543,7 @@ cleanup:
> }
>
> if (title && command) {
> - debug("Starting entry '%s'\n", title);
> + debug("Starting entry '%ls'\n", title);
> free(title);
> run_command(command, 0);
> free(command);
More information about the U-Boot
mailing list