uboot-mediatek: replace bootmenu shortkey patch with better version

Replace bootmenu shortmenu mediatek patch with a better version proposed
upstream that implement a more clean implementation.

Also the mediatek patch seems to be bugged and with lots of bootmenu
elements it's gets very bugged and unusable.

Refresh any affected patch.

Upstream-Status: Submitted [https://lore.kernel.org/u-boot/20250525134407.3760-1-ansuelsmth@gmail.com/]
Link: https://github.com/openwrt/openwrt/pull/18919
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
This commit is contained in:
Christian Marangi 2025-05-25 23:56:14 +02:00
parent 0c6f9665f2
commit aa8ca6ed4f
No known key found for this signature in database
GPG key ID: AC001D09ADBFEAD7
4 changed files with 264 additions and 210 deletions

View file

@ -1,206 +0,0 @@
From 5a15437610e8e8c68dc347845a83d0cbad80ca08 Mon Sep 17 00:00:00 2001
From: Weijie Gao <weijie.gao@mediatek.com>
Date: Tue, 19 Jan 2021 10:58:48 +0800
Subject: [PATCH 51/71] cmd: bootmenu: add ability to select item by shortkey
Add ability to use shortkey to select item for bootmenu command
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
cmd/bootmenu.c | 28 +++++++++++++++++++++++---
common/menu.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++
include/cli.h | 2 ++
include/menu.h | 3 +++
4 files changed, 84 insertions(+), 3 deletions(-)
--- a/cmd/bootmenu.c
+++ b/cmd/bootmenu.c
@@ -114,6 +114,8 @@ static char *bootmenu_choice_entry(void
++menu->active;
/* no menu key selected, regenerate menu */
return NULL;
+ case BKEY_CHOICE:
+ menu->active = cch->choice;
case BKEY_SELECT:
iter = menu->first;
for (i = 0; i < menu->active; ++i)
@@ -182,6 +184,9 @@ static int prepare_bootmenu_entry(struct
unsigned short int i = *index;
struct bootmenu_entry *entry = NULL;
struct bootmenu_entry *iter = *current;
+ char *choice_option;
+ char choice_char;
+ int len;
while ((option = bootmenu_getoption(i))) {
@@ -196,11 +201,28 @@ static int prepare_bootmenu_entry(struct
if (!entry)
return -ENOMEM;
- entry->title = strndup(option, sep - option);
+ /* Add BKEY_CHOICE support: '%c. %s\0' : len --> len + 4 */
+ len = sep - option + 4;
+
+ choice_option = malloc(len);
+ if (!choice_option) {
+ free(entry->title);
+ free(entry);
+ return -ENOMEM;
+ }
+
+ if (!get_choice_char(i, &choice_char))
+ len = snprintf(choice_option, len, "%c. %s", choice_char, option);
+ else
+ len = snprintf(choice_option, len, " %s", option);
+
+ entry->title = strndup(choice_option, len);
+
if (!entry->title) {
free(entry);
return -ENOMEM;
}
+ free(choice_option);
entry->command = strdup(sep + 1);
if (!entry->command) {
@@ -382,9 +404,9 @@ static struct bootmenu_data *bootmenu_cr
/* Add Quit entry if exiting bootmenu is disabled */
if (!IS_ENABLED(CONFIG_BOOTMENU_DISABLE_UBOOT_CONSOLE))
- entry->title = strdup("Exit");
+ entry->title = strdup("0. Exit");
else
- entry->title = strdup("Quit");
+ entry->title = strdup("0. Quit");
if (!entry->title) {
free(entry);
--- a/common/menu.c
+++ b/common/menu.c
@@ -8,6 +8,7 @@
#include <cli.h>
#include <malloc.h>
#include <errno.h>
+#include <linux/ctype.h>
#include <linux/delay.h>
#include <linux/list.h>
#include <watchdog.h>
@@ -49,6 +50,33 @@ struct menu {
int item_cnt;
};
+const char choice_chars[] = {
+ '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
+ 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
+ 'u', 'v', 'w', 'x', 'y', 'z'
+};
+
+static int find_choice(char choice)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(choice_chars); i++)
+ if (tolower(choice) == choice_chars[i])
+ return i;
+
+ return -1;
+}
+
+int get_choice_char(int index, char *result)
+{
+ if (index < ARRAY_SIZE(choice_chars))
+ *result = choice_chars[index];
+ else
+ return -1;
+ return 0;
+}
+
/*
* An iterator function for menu items. callback will be called for each item
* in m, with m, a pointer to the item, and extra being passed to callback. If
@@ -441,6 +469,7 @@ enum bootmenu_key bootmenu_autoboot_loop
{
enum bootmenu_key key = BKEY_NONE;
int i, c;
+ int choice;
while (menu->delay > 0) {
if (ansi)
@@ -458,6 +487,18 @@ enum bootmenu_key bootmenu_autoboot_loop
menu->delay = -1;
c = getchar();
+ choice = find_choice(c);
+ if ((choice >= 0 &&
+ choice < menu->count - 1)) {
+ cch->choice = choice;
+ key = BKEY_CHOICE;
+ break;
+ } else if (c == '0') {
+ cch->choice = menu->count - 1;
+ key = BKEY_CHOICE;
+ break;
+ }
+
ichar = cli_ch_process(cch, c);
switch (ichar) {
@@ -537,6 +578,7 @@ enum bootmenu_key bootmenu_loop(struct b
{
enum bootmenu_key key;
int c, errchar = 0;
+ int choice;
c = cli_ch_process(cch, 0);
if (!c) {
@@ -548,6 +590,18 @@ enum bootmenu_key bootmenu_loop(struct b
}
if (!c) {
c = getchar();
+
+ choice = find_choice(c);
+ if ((choice >= 0 &&
+ choice < menu->count - 1)) {
+ cch->choice = choice;
+ return BKEY_CHOICE;
+
+ } else if (c == '0') {
+ cch->choice = menu->count - 1;
+ return BKEY_CHOICE;
+ }
+
c = cli_ch_process(cch, c);
}
}
--- a/include/cli.h
+++ b/include/cli.h
@@ -23,6 +23,8 @@ struct cli_ch_state {
char esc_save[8];
int emit_upto;
bool emitting;
+ /* mediatek bootmenu choice feature */
+ char choice;
};
/**
--- a/include/menu.h
+++ b/include/menu.h
@@ -37,6 +37,8 @@ int menu_default_choice(struct menu *m,
*/
int menu_show(int bootdelay);
+int get_choice_char(int index, char *result);
+
struct bootmenu_data {
int delay; /* delay for autoboot */
int active; /* active menu entry */
@@ -51,6 +53,7 @@ enum bootmenu_key {
BKEY_UP,
BKEY_DOWN,
BKEY_SELECT,
+ BKEY_CHOICE,
BKEY_QUIT,
BKEY_SAVE,

View file

@ -0,0 +1,261 @@
From 16fd9af92b7ed93ece62fa8d1bef341455d773cf Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Sat, 24 May 2025 23:23:53 +0200
Subject: [PATCH v2] cmd: bootmenu: permit to select bootmenu entry with a
shortcut
Permit to select a bootmenu entry with a key shortcut. This is
especially useful in production or testing scenario to automate flashing
procedure or testing procedure.
The boot entry are changed to append the shortcut key to it.
Example:
1. Run default boot command.
2. Boot system via TFTP.
3. Boot production system from NAND.
4. Boot recovery system from NAND.
5. Load production system via TFTP then write to NAND.
6. Load recovery system via TFTP then write to NAND.
7. Load BL31+U-Boot FIP via TFTP then write to NAND.
8. Load BL2 preloader via TFTP then write to NAND.
9. Reboot.
a. Reset all settings to factory defaults.
0. Exit
0 is always reserved for Exit to console.
On pressing the keyboard key 2, the bootmenu entry 2 is selected and
executed.
Up to 34 key shortcut (0 excluded as reserved) are supported from 1-9
and a-z.
If a shortcut key not present in the bootmenu list is pressed, it is
simply ignored and eventually the autoboot is interrupted.
Capital A-Z are converted to lower a-z and the related option is
selected.
Suggested-by: Weijie Gao <weijie.gao@mediatek.com>
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
Changes v2:
- Fix spelling mistake
- Fix case with '0'
cmd/bootmenu.c | 41 ++++++++++++++++++++++++++++++++++++++---
common/menu.c | 44 ++++++++++++++++++++++++++++++++++++++++++--
include/cli.h | 2 ++
include/menu.h | 3 +++
4 files changed, 85 insertions(+), 5 deletions(-)
--- a/cmd/bootmenu.c
+++ b/cmd/bootmenu.c
@@ -114,6 +114,14 @@ static char *bootmenu_choice_entry(void
++menu->active;
/* no menu key selected, regenerate menu */
return NULL;
+ case BKEY_SHORTCUT:
+ /* invalid shortcut, regenerate menu */
+ if (cch->shortcut_key >= menu->count - 1)
+ return NULL;
+ /* shortcut_key value for Exit is is -1 */
+ menu->active = cch->shortcut_key < 0 ? menu->count - 1 :
+ cch->shortcut_key;
+ fallthrough;
case BKEY_SELECT:
iter = menu->first;
for (i = 0; i < menu->active; ++i)
@@ -161,6 +169,21 @@ static void bootmenu_destroy(struct boot
free(menu);
}
+static char bootmenu_entry_shortcut_key(int index)
+{
+ switch (index) {
+ /* 1-9 shortcut key (0 reserved) */
+ case 0 ... 8:
+ return '1' + index;
+ /* a-z shortcut key */
+ case 9 ... 34:
+ return 'a' + index - 9;
+ /* We support shortcut for up to 34 options (0 reserved) */
+ default:
+ return -ENOENT;
+ }
+}
+
/**
* prepare_bootmenu_entry() - generate the bootmenu_xx entries
*
@@ -184,6 +207,8 @@ static int prepare_bootmenu_entry(struct
struct bootmenu_entry *iter = *current;
while ((option = bootmenu_getoption(i))) {
+ char shortcut_key;
+ int len;
/* bootmenu_[num] format is "[title]=[commands]" */
sep = strchr(option, '=');
@@ -196,12 +221,22 @@ static int prepare_bootmenu_entry(struct
if (!entry)
return -ENOMEM;
- entry->title = strndup(option, sep - option);
+ /* Add shotcut key option: %c. %s\0 */
+ len = sep - option + 4;
+
+ entry->title = malloc(len);
if (!entry->title) {
free(entry);
return -ENOMEM;
}
+ shortcut_key = bootmenu_entry_shortcut_key(i);
+ /* Use emtpy space if entry doesn't support shortcut key */
+ snprintf(entry->title, len, "%c%c %s",
+ shortcut_key > 0 ? shortcut_key : ' ',
+ shortcut_key > 0 ? '.' : ' ',
+ option);
+
entry->command = strdup(sep + 1);
if (!entry->command) {
free(entry->title);
@@ -382,9 +417,9 @@ static struct bootmenu_data *bootmenu_cr
/* Add Quit entry if exiting bootmenu is disabled */
if (!IS_ENABLED(CONFIG_BOOTMENU_DISABLE_UBOOT_CONSOLE))
- entry->title = strdup("Exit");
+ entry->title = strdup("0. Exit");
else
- entry->title = strdup("Quit");
+ entry->title = strdup("0. Quit");
if (!entry->title) {
free(entry);
--- a/common/menu.c
+++ b/common/menu.c
@@ -8,6 +8,7 @@
#include <cli.h>
#include <malloc.h>
#include <errno.h>
+#include <linux/ctype.h>
#include <linux/delay.h>
#include <linux/list.h>
#include <watchdog.h>
@@ -436,6 +437,29 @@ int menu_destroy(struct menu *m)
return 1;
}
+static int bootmenu_conv_shortcut_key(struct bootmenu_data *menu, int ichar)
+{
+ int shortcut_key;
+
+ ichar = tolower(ichar);
+ switch (ichar) {
+ /* a-z for bootmenu entry > 9 */
+ case 'a' ... 'z':
+ shortcut_key = ichar - 'a' + 9;
+ break;
+ /* 1-9 for bootmenu entry <= 9 */
+ case '1' ... '9':
+ shortcut_key = ichar - '1';
+ break;
+ /* Reserve 0 for last option (aka Exit) */
+ case '0':
+ default:
+ return -1;
+ }
+
+ return shortcut_key;
+}
+
enum bootmenu_key bootmenu_autoboot_loop(struct bootmenu_data *menu,
struct cli_ch_state *cch)
{
@@ -443,12 +467,12 @@ enum bootmenu_key bootmenu_autoboot_loop
int i, c;
while (menu->delay > 0) {
+ int ichar;
+
if (ansi)
printf(ANSI_CURSOR_POSITION, menu->count + 5, 3);
printf("Hit any key to stop autoboot: %d ", menu->delay);
for (i = 0; i < 100; ++i) {
- int ichar;
-
if (!tstc()) {
schedule();
mdelay(10);
@@ -470,6 +494,11 @@ enum bootmenu_key bootmenu_autoboot_loop
case 0x3: /* ^C */
key = BKEY_QUIT;
break;
+ case 'A' ... 'Z':
+ case 'a' ... 'z':
+ case '0' ... '9':
+ key = BKEY_SHORTCUT;
+ break;
default:
key = BKEY_NONE;
break;
@@ -477,6 +506,9 @@ enum bootmenu_key bootmenu_autoboot_loop
break;
}
+ if (key == BKEY_SHORTCUT)
+ cch->shortcut_key = bootmenu_conv_shortcut_key(menu, ichar);
+
if (menu->delay < 0)
break;
@@ -524,6 +556,11 @@ enum bootmenu_key bootmenu_conv_key(int
case ' ':
key = BKEY_SPACE;
break;
+ case 'A' ... 'Z':
+ case 'a' ... 'z':
+ case '0' ... '9':
+ key = BKEY_SHORTCUT;
+ break;
default:
key = BKEY_NONE;
break;
@@ -554,5 +591,8 @@ enum bootmenu_key bootmenu_loop(struct b
key = bootmenu_conv_key(c);
+ if (key == BKEY_SHORTCUT)
+ cch->shortcut_key = bootmenu_conv_shortcut_key(menu, c);
+
return key;
}
--- a/include/cli.h
+++ b/include/cli.h
@@ -17,12 +17,14 @@
* @esc_save: Escape characters collected so far
* @emit_upto: Next index to emit from esc_save
* @emitting: true if emitting from esc_save
+ * @shortcut_key: Selected shortcut option index
*/
struct cli_ch_state {
int esc_len;
char esc_save[8];
int emit_upto;
bool emitting;
+ int shortcut_key;
};
/**
--- a/include/menu.h
+++ b/include/menu.h
@@ -54,6 +54,9 @@ enum bootmenu_key {
BKEY_QUIT,
BKEY_SAVE,
+ /* shortcut key to select menu option directly */
+ BKEY_SHORTCUT,
+
/* 'extra' keys, which are used by menus but not cedit */
BKEY_PLUS,
BKEY_MINUS,

View file

@ -1,6 +1,6 @@
--- a/cmd/bootmenu.c --- a/cmd/bootmenu.c
+++ b/cmd/bootmenu.c +++ b/cmd/bootmenu.c
@@ -463,7 +463,11 @@ static void menu_display_statusline(stru @@ -476,7 +476,11 @@ static void menu_display_statusline(stru
printf(ANSI_CURSOR_POSITION, 1, 1); printf(ANSI_CURSOR_POSITION, 1, 1);
puts(ANSI_CLEAR_LINE); puts(ANSI_CLEAR_LINE);
printf(ANSI_CURSOR_POSITION, 2, 3); printf(ANSI_CURSOR_POSITION, 2, 3);
@ -13,7 +13,7 @@
puts(ANSI_CLEAR_LINE_TO_END); puts(ANSI_CLEAR_LINE_TO_END);
printf(ANSI_CURSOR_POSITION, 3, 1); printf(ANSI_CURSOR_POSITION, 3, 1);
puts(ANSI_CLEAR_LINE); puts(ANSI_CLEAR_LINE);
@@ -548,6 +552,7 @@ static enum bootmenu_ret bootmenu_show(i @@ -561,6 +565,7 @@ static enum bootmenu_ret bootmenu_show(i
return BOOTMENU_RET_FAIL; return BOOTMENU_RET_FAIL;
} }
@ -23,7 +23,7 @@
goto cleanup; goto cleanup;
--- a/include/menu.h --- a/include/menu.h
+++ b/include/menu.h +++ b/include/menu.h
@@ -45,6 +45,7 @@ struct bootmenu_data { @@ -43,6 +43,7 @@ struct bootmenu_data {
int last_active; /* last active menu entry */ int last_active; /* last active menu entry */
int count; /* total count of menu entries */ int count; /* total count of menu entries */
struct bootmenu_entry *first; /* first menu entry */ struct bootmenu_entry *first; /* first menu entry */

View file

@ -347,4 +347,3 @@
+_firstboot=setenv _firstboot ; run ethaddr_factory ; run _switch_to_menu ; run _init_env ; run boot_first +_firstboot=setenv _firstboot ; run ethaddr_factory ; run _switch_to_menu ; run _init_env ; run boot_first
+_switch_to_menu=setenv _switch_to_menu ; setenv bootdelay 3 ; setenv bootmenu_delay 3 ; setenv bootmenu_0 $bootmenu_0d ; setenv bootmenu_0d ; run _bootmenu_update_title +_switch_to_menu=setenv _switch_to_menu ; setenv bootdelay 3 ; setenv bootmenu_delay 3 ; setenv bootmenu_0 $bootmenu_0d ; setenv bootmenu_0d ; run _bootmenu_update_title
+_bootmenu_update_title=setenv _bootmenu_update_title ; setenv bootmenu_title "$bootmenu_title $ver" +_bootmenu_update_title=setenv _bootmenu_update_title ; setenv bootmenu_title "$bootmenu_title $ver"