mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-20 20:04:46 +00:00
bootmenu: update bootmenu_entry structure
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. Signed-off-by: Masahisa Kojima <masahisa.kojima@linaro.org> Reviewed-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
This commit is contained in:
parent
4e65ca00f3
commit
a3d0aa87ac
2 changed files with 76 additions and 32 deletions
|
@ -353,6 +353,7 @@ source lib/efi_selftest/Kconfig
|
||||||
config CMD_BOOTMENU
|
config CMD_BOOTMENU
|
||||||
bool "bootmenu"
|
bool "bootmenu"
|
||||||
select MENU
|
select MENU
|
||||||
|
select CHARSET
|
||||||
help
|
help
|
||||||
Add an ANSI terminal boot menu command.
|
Add an ANSI terminal boot menu command.
|
||||||
|
|
||||||
|
|
107
cmd/bootmenu.c
107
cmd/bootmenu.c
|
@ -3,6 +3,7 @@
|
||||||
* (C) Copyright 2011-2013 Pali Rohár <pali@kernel.org>
|
* (C) Copyright 2011-2013 Pali Rohár <pali@kernel.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <charset.h>
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <command.h>
|
#include <command.h>
|
||||||
#include <ansi.h>
|
#include <ansi.h>
|
||||||
|
@ -24,11 +25,18 @@
|
||||||
*/
|
*/
|
||||||
#define MAX_ENV_SIZE (9 + 2 + 1)
|
#define MAX_ENV_SIZE (9 + 2 + 1)
|
||||||
|
|
||||||
|
enum boot_type {
|
||||||
|
BOOTMENU_TYPE_NONE = 0,
|
||||||
|
BOOTMENU_TYPE_BOOTMENU,
|
||||||
|
};
|
||||||
|
|
||||||
struct bootmenu_entry {
|
struct bootmenu_entry {
|
||||||
unsigned short int num; /* unique number 0 .. MAX_COUNT */
|
unsigned short int num; /* unique number 0 .. MAX_COUNT */
|
||||||
char key[3]; /* key identifier of number */
|
char key[3]; /* key identifier of number */
|
||||||
char *title; /* title of entry */
|
u16 *title; /* title of entry */
|
||||||
char *command; /* hush command 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_data *menu; /* this bootmenu */
|
||||||
struct bootmenu_entry *next; /* next menu entry (num+1) */
|
struct bootmenu_entry *next; /* next menu entry (num+1) */
|
||||||
};
|
};
|
||||||
|
@ -73,7 +81,7 @@ static void bootmenu_print_entry(void *data)
|
||||||
if (reverse)
|
if (reverse)
|
||||||
puts(ANSI_COLOR_REVERSE);
|
puts(ANSI_COLOR_REVERSE);
|
||||||
|
|
||||||
puts(entry->title);
|
printf("%ls", entry->title);
|
||||||
|
|
||||||
if (reverse)
|
if (reverse)
|
||||||
puts(ANSI_COLOR_RESET);
|
puts(ANSI_COLOR_RESET);
|
||||||
|
@ -269,31 +277,32 @@ static void bootmenu_destroy(struct bootmenu_data *menu)
|
||||||
free(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;
|
int len;
|
||||||
char *sep;
|
char *sep;
|
||||||
char *default_str;
|
const char *option;
|
||||||
struct bootmenu_entry *entry;
|
unsigned short int i = *index;
|
||||||
|
struct bootmenu_entry *entry = NULL;
|
||||||
menu = malloc(sizeof(struct bootmenu_data));
|
struct bootmenu_entry *iter = *current;
|
||||||
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);
|
|
||||||
|
|
||||||
while ((option = bootmenu_getoption(i))) {
|
while ((option = bootmenu_getoption(i))) {
|
||||||
|
u16 *buf;
|
||||||
|
|
||||||
sep = strchr(option, '=');
|
sep = strchr(option, '=');
|
||||||
if (!sep) {
|
if (!sep) {
|
||||||
printf("Invalid bootmenu entry: %s\n", option);
|
printf("Invalid bootmenu entry: %s\n", option);
|
||||||
|
@ -302,23 +311,23 @@ static struct bootmenu_data *bootmenu_create(int delay)
|
||||||
|
|
||||||
entry = malloc(sizeof(struct bootmenu_entry));
|
entry = malloc(sizeof(struct bootmenu_entry));
|
||||||
if (!entry)
|
if (!entry)
|
||||||
goto cleanup;
|
return -ENOMEM;
|
||||||
|
|
||||||
len = sep-option;
|
len = sep-option;
|
||||||
entry->title = malloc(len + 1);
|
buf = calloc(1, (len + 1) * sizeof(u16));
|
||||||
|
entry->title = buf;
|
||||||
if (!entry->title) {
|
if (!entry->title) {
|
||||||
free(entry);
|
free(entry);
|
||||||
goto cleanup;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
memcpy(entry->title, option, len);
|
utf8_utf16_strncpy(&buf, option, len);
|
||||||
entry->title[len] = 0;
|
|
||||||
|
|
||||||
len = strlen(sep + 1);
|
len = strlen(sep + 1);
|
||||||
entry->command = malloc(len + 1);
|
entry->command = malloc(len + 1);
|
||||||
if (!entry->command) {
|
if (!entry->command) {
|
||||||
free(entry->title);
|
free(entry->title);
|
||||||
free(entry);
|
free(entry);
|
||||||
goto cleanup;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
memcpy(entry->command, sep + 1, len);
|
memcpy(entry->command, sep + 1, len);
|
||||||
entry->command[len] = 0;
|
entry->command[len] = 0;
|
||||||
|
@ -327,6 +336,8 @@ static struct bootmenu_data *bootmenu_create(int delay)
|
||||||
|
|
||||||
entry->num = i;
|
entry->num = i;
|
||||||
entry->menu = menu;
|
entry->menu = menu;
|
||||||
|
entry->type = BOOTMENU_TYPE_BOOTMENU;
|
||||||
|
entry->bootorder = i;
|
||||||
entry->next = NULL;
|
entry->next = NULL;
|
||||||
|
|
||||||
if (!iter)
|
if (!iter)
|
||||||
|
@ -341,13 +352,44 @@ static struct bootmenu_data *bootmenu_create(int delay)
|
||||||
break;
|
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 */
|
/* Add U-Boot console entry at the end */
|
||||||
if (i <= MAX_COUNT - 1) {
|
if (i <= MAX_COUNT - 1) {
|
||||||
entry = malloc(sizeof(struct bootmenu_entry));
|
entry = malloc(sizeof(struct bootmenu_entry));
|
||||||
if (!entry)
|
if (!entry)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
entry->title = strdup("U-Boot console");
|
entry->title = u16_strdup(u"U-Boot console");
|
||||||
if (!entry->title) {
|
if (!entry->title) {
|
||||||
free(entry);
|
free(entry);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
@ -364,6 +406,7 @@ static struct bootmenu_data *bootmenu_create(int delay)
|
||||||
|
|
||||||
entry->num = i;
|
entry->num = i;
|
||||||
entry->menu = menu;
|
entry->menu = menu;
|
||||||
|
entry->type = BOOTMENU_TYPE_NONE;
|
||||||
entry->next = NULL;
|
entry->next = NULL;
|
||||||
|
|
||||||
if (!iter)
|
if (!iter)
|
||||||
|
@ -421,7 +464,7 @@ static void bootmenu_show(int delay)
|
||||||
{
|
{
|
||||||
int init = 0;
|
int init = 0;
|
||||||
void *choice = NULL;
|
void *choice = NULL;
|
||||||
char *title = NULL;
|
u16 *title = NULL;
|
||||||
char *command = NULL;
|
char *command = NULL;
|
||||||
struct menu *menu;
|
struct menu *menu;
|
||||||
struct bootmenu_data *bootmenu;
|
struct bootmenu_data *bootmenu;
|
||||||
|
@ -472,7 +515,7 @@ static void bootmenu_show(int delay)
|
||||||
|
|
||||||
if (menu_get_choice(menu, &choice) == 1) {
|
if (menu_get_choice(menu, &choice) == 1) {
|
||||||
iter = choice;
|
iter = choice;
|
||||||
title = strdup(iter->title);
|
title = u16_strdup(iter->title);
|
||||||
command = strdup(iter->command);
|
command = strdup(iter->command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -487,7 +530,7 @@ cleanup:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (title && command) {
|
if (title && command) {
|
||||||
debug("Starting entry '%s'\n", title);
|
debug("Starting entry '%ls'\n", title);
|
||||||
free(title);
|
free(title);
|
||||||
run_command(command, 0);
|
run_command(command, 0);
|
||||||
free(command);
|
free(command);
|
||||||
|
|
Loading…
Add table
Reference in a new issue