[openwrt/openwrt] uboot-mediatek: replace bootmenu shortkey patch with better version

LEDE Commits lede-commits at lists.infradead.org
Tue May 27 08:56:40 PDT 2025


ansuel pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/aa8ca6ed4fe480c248883ce96ee95dcad89e7c60

commit aa8ca6ed4fe480c248883ce96ee95dcad89e7c60
Author: Christian Marangi <ansuelsmth at gmail.com>
AuthorDate: Sun May 25 23:56:14 2025 +0200

    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 at gmail.com>
---
 ...nu-add-ability-to-select-item-by-shortkey.patch | 206 ----------------
 ...menu-permit-to-select-bootmenu-entry-with.patch | 261 +++++++++++++++++++++
 .../patches/211-cmd-bootmenu-custom-title.patch    |   6 +-
 .../patches/463-add-snr-snr-cpe-ax2.patch          |   1 -
 4 files changed, 264 insertions(+), 210 deletions(-)

diff --git a/package/boot/uboot-mediatek/patches/100-16-cmd-bootmenu-add-ability-to-select-item-by-shortkey.patch b/package/boot/uboot-mediatek/patches/100-16-cmd-bootmenu-add-ability-to-select-item-by-shortkey.patch
deleted file mode 100644
index 7daae5c484..0000000000
--- a/package/boot/uboot-mediatek/patches/100-16-cmd-bootmenu-add-ability-to-select-item-by-shortkey.patch
+++ /dev/null
@@ -1,206 +0,0 @@
-From 5a15437610e8e8c68dc347845a83d0cbad80ca08 Mon Sep 17 00:00:00 2001
-From: Weijie Gao <weijie.gao at 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 at 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,
- 
diff --git a/package/boot/uboot-mediatek/patches/170-cmd-bootmenu-permit-to-select-bootmenu-entry-with.patch b/package/boot/uboot-mediatek/patches/170-cmd-bootmenu-permit-to-select-bootmenu-entry-with.patch
new file mode 100644
index 0000000000..b5da35aa96
--- /dev/null
+++ b/package/boot/uboot-mediatek/patches/170-cmd-bootmenu-permit-to-select-bootmenu-entry-with.patch
@@ -0,0 +1,261 @@
+From 16fd9af92b7ed93ece62fa8d1bef341455d773cf Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth at 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 at mediatek.com>
+Signed-off-by: Christian Marangi <ansuelsmth at 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,
diff --git a/package/boot/uboot-mediatek/patches/211-cmd-bootmenu-custom-title.patch b/package/boot/uboot-mediatek/patches/211-cmd-bootmenu-custom-title.patch
index 1c1071bafc..fff020ce0b 100644
--- a/package/boot/uboot-mediatek/patches/211-cmd-bootmenu-custom-title.patch
+++ b/package/boot/uboot-mediatek/patches/211-cmd-bootmenu-custom-title.patch
@@ -1,6 +1,6 @@
 --- a/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);
  	puts(ANSI_CLEAR_LINE);
  	printf(ANSI_CURSOR_POSITION, 2, 3);
@@ -13,7 +13,7 @@
  	puts(ANSI_CLEAR_LINE_TO_END);
  	printf(ANSI_CURSOR_POSITION, 3, 1);
  	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;
  	}
  
@@ -23,7 +23,7 @@
  			goto cleanup;
 --- a/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 count;			/* total count of menu entries */
  	struct bootmenu_entry *first;	/* first menu entry */
diff --git a/package/boot/uboot-mediatek/patches/463-add-snr-snr-cpe-ax2.patch b/package/boot/uboot-mediatek/patches/463-add-snr-snr-cpe-ax2.patch
index f26beb78fc..5602f46474 100644
--- a/package/boot/uboot-mediatek/patches/463-add-snr-snr-cpe-ax2.patch
+++ b/package/boot/uboot-mediatek/patches/463-add-snr-snr-cpe-ax2.patch
@@ -347,4 +347,3 @@
 +_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
 +_bootmenu_update_title=setenv _bootmenu_update_title ; setenv bootmenu_title "$bootmenu_title       $ver"
-




More information about the lede-commits mailing list