[PATCH v5 08/17] bootmenu: update bootmenu_entry structure
Heinrich Schuchardt
xypron.glpk at gmx.de
Sun May 1 22:54:38 CEST 2022
On 4/29/22 21:51, Heinrich Schuchardt wrote:
> 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);
This "bootmen_%02d" strings conveys not information of interest. Please
remove this hunk.
>> + 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.
I have already provided a patch with this.
Best regards
Heinrich
>
> 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