Skip to content

Commit 3fa53b9

Browse files
committed
bootstd: Add a return code to bootflow menu
Return an error when the user does not select an OS, so we know whether to boot or not. Move calling of bootflow_menu_run() into a separate function so we can call it from other places. Expand the test to cover these cases. Add some documentation also, while we are here. Signed-off-by: Simon Glass <[email protected]>
1 parent baea7ec commit 3fa53b9

File tree

3 files changed

+123
-12
lines changed

3 files changed

+123
-12
lines changed

cmd/bootflow.c

+41-12
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,44 @@ static void show_footer(int count, int num_valid)
8989
num_valid);
9090
}
9191

92+
/**
93+
* bootflow_handle_menu() - Handle running the menu and updating cur bootflow
94+
*
95+
* This shows the menu, allows the user to select something and then prints
96+
* what happened
97+
*
98+
* @std: bootstd information
99+
* @text_mode: true to run the menu in text mode
100+
* @bflowp: Returns selected bootflow, on success
101+
* Return: 0 on success (a bootflow was selected), -EAGAIN if nothing was
102+
* chosen, other -ve value on other error
103+
*/
104+
__maybe_unused static int bootflow_handle_menu(struct bootstd_priv *std,
105+
bool text_mode,
106+
struct bootflow **bflowp)
107+
{
108+
struct bootflow *bflow;
109+
int ret;
110+
111+
ret = bootflow_menu_run(std, text_mode, &bflow);
112+
if (ret) {
113+
if (ret == -EAGAIN) {
114+
printf("Nothing chosen\n");
115+
std->cur_bootflow = NULL;
116+
} else {
117+
printf("Menu failed (err=%d)\n", ret);
118+
}
119+
120+
return ret;
121+
}
122+
123+
printf("Selected: %s\n", bflow->os_name ? bflow->os_name : bflow->name);
124+
std->cur_bootflow = bflow;
125+
*bflowp = bflow;
126+
127+
return 0;
128+
}
129+
92130
static int do_bootflow_scan(struct cmd_tbl *cmdtp, int flag, int argc,
93131
char *const argv[])
94132
{
@@ -455,18 +493,9 @@ static int do_bootflow_menu(struct cmd_tbl *cmdtp, int flag, int argc,
455493
if (ret)
456494
return CMD_RET_FAILURE;
457495

458-
ret = bootflow_menu_run(std, text_mode, &bflow);
459-
if (ret) {
460-
if (ret == -EAGAIN)
461-
printf("Nothing chosen\n");
462-
else {
463-
printf("Menu failed (err=%d)\n", ret);
464-
return CMD_RET_FAILURE;
465-
}
466-
}
467-
468-
printf("Selected: %s\n", bflow->os_name ? bflow->os_name : bflow->name);
469-
std->cur_bootflow = bflow;
496+
ret = bootflow_handle_menu(std, text_mode, &bflow);
497+
if (ret)
498+
return CMD_RET_FAILURE;
470499

471500
return 0;
472501
}

doc/usage/cmd/bootflow.rst

+67
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Synopis
1515
bootflow read
1616
bootflow boot
1717
bootflow cmdline [set|get|clear|delete|auto] <param> [<value>]
18+
bootfloe menu [-t]
1819

1920
Description
2021
-----------
@@ -24,6 +25,9 @@ locate bootflows, list them and boot them.
2425

2526
See :doc:`../../develop/bootstd` for more information.
2627

28+
Note that `CONFIG_BOOTSTD_FULL` (which enables `CONFIG_CMD_BOOTFLOW_FULL) must
29+
be enabled to obtain full functionality with this command. Otherwise, it only
30+
supports `bootflow scan` which scans and boots the first available bootflow.
2731

2832
bootflow scan
2933
~~~~~~~~~~~~~
@@ -247,6 +251,16 @@ can be used to set the early console (or console) to a suitable value so that
247251
output appears on the serial port. This is only supported by the 16550 serial
248252
driver so far.
249253

254+
bootflow menu
255+
~~~~~~~~~~~~~
256+
257+
This shows a menu with available bootflows. The user can select a particular
258+
bootflow, which then becomes the current one.
259+
260+
The `-t` flag requests a text menu. Otherwise, if a display is available, a
261+
graphical menu is shown.
262+
263+
250264
Example
251265
-------
252266

@@ -658,6 +672,56 @@ Now the buffer can be accessed::
658672
77b7e4e0: 320fc000 08e8ba0f c031300f b8d0000f ...2.....01.....
659673
77b7e4f0: 00000020 6ad8000f 00858d10 50000002 ......j.......P
660674

675+
This shows using a text menu to boot an OS::
676+
677+
=> bootflow scan
678+
=> bootfl list
679+
=> bootfl menu -t
680+
U-Boot : Boot Menu
681+
682+
UP and DOWN to choose, ENTER to select
683+
684+
> 0 mmc1 mmc1.bootdev.whole
685+
1 mmc1 Fedora-Workstation-armhfp-31-1.9 (5.3.7-301.fc31.armv7hl)
686+
2 mmc1 mmc1.bootdev.part_1
687+
3 mmc4 mmc4.bootdev.whole
688+
4 mmc4 Armbian
689+
5 mmc4 mmc4.bootdev.part_1
690+
6 mmc5 mmc5.bootdev.whole
691+
7 mmc5 ChromeOS
692+
8 mmc5 ChromeOS
693+
U-Boot : Boot Menu
694+
695+
UP and DOWN to choose, ENTER to select
696+
697+
0 mmc1 mmc1.bootdev.whole
698+
> 1 mmc1 Fedora-Workstation-armhfp-31-1.9 (5.3.7-301.fc31.armv7hl)
699+
2 mmc1 mmc1.bootdev.part_1
700+
3 mmc4 mmc4.bootdev.whole
701+
4 mmc4 Armbian
702+
5 mmc4 mmc4.bootdev.part_1
703+
6 mmc5 mmc5.bootdev.whole
704+
7 mmc5 ChromeOS
705+
8 mmc5 ChromeOS
706+
U-Boot : Boot Menu
707+
708+
Selected: Fedora-Workstation-armhfp-31-1.9 (5.3.7-301.fc31.armv7hl)
709+
=> bootfl boot
710+
** Booting bootflow 'mmc1.bootdev.part_1' with extlinux
711+
Ignoring unknown command: ui
712+
Ignoring malformed menu command: autoboot
713+
Ignoring malformed menu command: hidden
714+
Ignoring unknown command: totaltimeout
715+
Fedora-Workstation-armhfp-31-1.9 Boot Options.
716+
1: Fedora-Workstation-armhfp-31-1.9 (5.3.7-301.fc31.armv7hl)
717+
Enter choice: 1
718+
1: Fedora-Workstation-armhfp-31-1.9 (5.3.7-301.fc31.armv7hl)
719+
Retrieving file: /vmlinuz-5.3.7-301.fc31.armv7hl
720+
Retrieving file: /initramfs-5.3.7-301.fc31.armv7hl.img
721+
append: ro root=UUID=9732b35b-4cd5-458b-9b91-80f7047e0b8a rhgb quiet LANG=en_US.UTF-8 cma=192MB cma=256MB
722+
Retrieving file: /dtb-5.3.7-301.fc31.armv7hl/sandbox.dtb
723+
...
724+
661725

662726
Return value
663727
------------
@@ -667,6 +731,9 @@ return to U-Boot. If something about the U-Boot processing fails, then the
667731
return value $? is 1. If the boot succeeds but for some reason the Operating
668732
System returns, then $? is 0, indicating success.
669733

734+
For `bootflow menu` the return value is $? is 0 (true) if an option was choses,
735+
else 1.
736+
670737
For other subcommands, the return value $? is always 0 (true).
671738

672739

test/boot/bootflow.c

+15
Original file line numberDiff line numberDiff line change
@@ -604,8 +604,12 @@ static int scan_mmc4_bootdev(struct unit_test_state *uts)
604604
/* Check 'bootflow menu' to select a bootflow */
605605
static int bootflow_cmd_menu(struct unit_test_state *uts)
606606
{
607+
struct bootstd_priv *std;
607608
char prev[3];
608609

610+
/* get access to the current bootflow */
611+
ut_assertok(bootstd_get_priv(&std));
612+
609613
ut_assertok(scan_mmc4_bootdev(uts));
610614

611615
/* Add keypresses to move to and select the second one in the list */
@@ -616,6 +620,17 @@ static int bootflow_cmd_menu(struct unit_test_state *uts)
616620

617621
ut_assertok(run_command("bootflow menu", 0));
618622
ut_assert_nextline("Selected: Armbian");
623+
ut_assertnonnull(std->cur_bootflow);
624+
ut_assert_console_end();
625+
626+
/* Check not selecting anything */
627+
prev[0] = '\e';
628+
prev[1] = '\0';
629+
ut_asserteq(1, console_in_puts(prev));
630+
631+
ut_asserteq(1, run_command("bootflow menu", 0));
632+
ut_assertnull(std->cur_bootflow);
633+
ut_assert_nextline("Nothing chosen");
619634
ut_assert_console_end();
620635

621636
return 0;

0 commit comments

Comments
 (0)