[U-Boot] [PATCH 0/6] Adjust command macros to allow smaller U-Boot size

A large chunk of U-Boot's executable size is the code to process and execute commands. This is reasonable, since commands and scripts are an important part of U-Boot's feature set and provide much of its flexibility.
However, for some applications only a very limited set of commands is required. Where image size is important, it is desirable to be able to easily remove unwanted code.
This series introduces a new board_run_command() function which can be used to run a small subset of commands as required by the board (typically load and bootm), thus allowing the rest of the commands to be automatically and reliably dropped from the image using toolchain dead code elimination.
Tests on snow (ARMv7) show this reduces image size dramatically, more than just undefining all the commands:
text data bss dec hex filename before: 356359 12550 300056 668965 a3525 b/snow/u-boot with all commands undefined: 155336 5402 8624 169362 29592 b/snow/u-boot with this series: 123177 2958 1544 127679 1f2bf b/snow/u-boot
The difference is more pronounced the more effort is put into reducing the image size. For example, removing additional subsystem options yields:
text data bss dec hex filename with all commands undefined and most subsystems: 86479 4186 7480 98145 17f61 b/snow/u-boot with this series: 52395 1818 228 54441 d4a9 b/snow/u-boot
Further, it is possible to enable some of the split-use options like CONFIG_CMD_USB, and get USB support without the unwanted command overhead (it would be better if USB had a separate option for the command and the USB stack, but that is not the case, and a few other features have a similar problem).
U-Boot can then become a really minimal boot loader, with only the required functions available. Simply undefining various unwanted commands in the board config is not as effective, and is much more time-consuming to figure out. Apart from the cost of the parsing code, the commands necessarily provide a lot options and features which are not required by many boards.
In particular, with this series, it is possible to run a minimal U-Boot within the SRAM of a modern SoC, providing the benefits of the full U-Boot environment with the small size of SPL. This helps to bridge the gap somewhat. A key difference between U-Boot and SPL is the inclusion of the command parser, and this small size of SPL is a key reason why some boards currently use 'falcon mode', where only SPL is used to boot a kernel.
This series has a fairly small impact on the source code, changing command.h and a fairly small change to each list of subcommands (there are about 19 such sites in U-Boot).
Note: some effort was expended in trying to obtain the same result with just linker code elimination. However this did not work, since the linker would not eliminate some transitively-called functions like do_fdt() even when callers are removed.
Simon Glass (6): Add an info word to commands Refactor command macros so they can compile to nothing Add CONFIG_CMDLINE to allow removal of all commands main: Exclude getline code when CONFIG_CMDLINE is not defined main: Process FDT options even without CONFIG_BOOTDELAY sandbox: Add board_run_command() function
README | 8 +++ arch/x86/cpu/u-boot.lds | 4 ++ board/inka4x0/inkadiag.c | 12 ++-- board/intercontrol/digsy_mtc/cmd_mtc.c | 20 +++---- board/sandbox/sandbox/sandbox.c | 10 ++++ common/cmd_bmp.c | 8 +-- common/cmd_bootm.c | 39 ++++++++----- common/cmd_bootstage.c | 10 ++-- common/cmd_cbfs.c | 3 +- common/cmd_clk.c | 6 +- common/cmd_demo.c | 10 ++-- common/cmd_help.c | 4 ++ common/cmd_i2c.c | 34 +++++------ common/cmd_nvedit.c | 42 +++++++------- common/cmd_onenand.c | 23 ++++---- common/cmd_pxe.c | 6 +- common/cmd_sandbox.c | 14 ++--- common/cmd_sound.c | 8 +-- common/cmd_spl.c | 14 ++--- common/cmd_tpm.c | 52 ++++++++--------- common/command.c | 12 +++- common/main.c | 101 ++++++++++++++++++++++---------- drivers/gpio/pca953x.c | 14 ++--- drivers/gpio/tca642x.c | 14 ++--- drivers/misc/ds4510.c | 24 ++++---- include/command.h | 102 ++++++++++++++++++++++++++++----- include/config_defaults.h | 2 + include/config_fallbacks.h | 7 +++ test/dm/cmd_dm.c | 10 ++-- 29 files changed, 392 insertions(+), 221 deletions(-)

In cmd_bootm.c the function pointer is misused as a flags word. It is better to add a flag word to each command, so that bootm can avoid this hack.
To avoid increasing the size of the U-Boot binary, we can re-use the existing 'repeatable' flag, which only needs a single bit.
Signed-off-by: Simon Glass sjg@chromium.org ---
common/cmd_bootm.c | 35 ++++++++++++++++++++++------------- common/cmd_nvedit.c | 10 +++++----- common/command.c | 3 ++- include/command.h | 41 +++++++++++++++++++++++++++++++---------- 4 files changed, 60 insertions(+), 29 deletions(-)
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 9751edc..14d504b 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -522,19 +522,28 @@ static int do_bootm_standalone(int flag, int argc, char * const argv[], /* we overload the cmd field with our state machine info instead of a * function pointer */ static cmd_tbl_t cmd_bootm_sub[] = { - U_BOOT_CMD_MKENT(start, 0, 1, (void *)BOOTM_STATE_START, "", ""), - U_BOOT_CMD_MKENT(loados, 0, 1, (void *)BOOTM_STATE_LOADOS, "", ""), + U_BOOT_CMD_MKENT_COMPLETE(start, 0, 1, cmd_dummy, "", "", NULL, + BOOTM_STATE_START), + U_BOOT_CMD_MKENT_COMPLETE(loados, 0, 1, cmd_dummy, "", "", NULL, + BOOTM_STATE_LOADOS), #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH - U_BOOT_CMD_MKENT(ramdisk, 0, 1, (void *)BOOTM_STATE_RAMDISK, "", ""), + U_BOOT_CMD_MKENT_COMPLETE(ramdisk, 0, 1, cmd_dummy, "", "", NULL, + BOOTM_STATE_RAMDISK), #endif #ifdef CONFIG_OF_LIBFDT - U_BOOT_CMD_MKENT(fdt, 0, 1, (void *)BOOTM_STATE_FDT, "", ""), -#endif - U_BOOT_CMD_MKENT(cmdline, 0, 1, (void *)BOOTM_STATE_OS_CMDLINE, "", ""), - U_BOOT_CMD_MKENT(bdt, 0, 1, (void *)BOOTM_STATE_OS_BD_T, "", ""), - U_BOOT_CMD_MKENT(prep, 0, 1, (void *)BOOTM_STATE_OS_PREP, "", ""), - U_BOOT_CMD_MKENT(fake, 0, 1, (void *)BOOTM_STATE_OS_FAKE_GO, "", ""), - U_BOOT_CMD_MKENT(go, 0, 1, (void *)BOOTM_STATE_OS_GO, "", ""), + U_BOOT_CMD_MKENT_COMPLETE(fdt, 0, 1, cmd_dummy, "", "", NULL, + BOOTM_STATE_FDT), +#endif + U_BOOT_CMD_MKENT_COMPLETE(cmdline, 0, 1, cmd_dummy, "", "", NULL, + BOOTM_STATE_OS_CMDLINE), + U_BOOT_CMD_MKENT_COMPLETE(bdt, 0, 1, cmd_dummy, "", "", NULL, + BOOTM_STATE_OS_BD_T), + U_BOOT_CMD_MKENT_COMPLETE(prep, 0, 1, cmd_dummy, "", "", NULL, + BOOTM_STATE_OS_PREP), + U_BOOT_CMD_MKENT_COMPLETE(fake, 0, 1, cmd_dummy, "", "", NULL, + BOOTM_STATE_OS_FAKE_GO), + U_BOOT_CMD_MKENT_COMPLETE(go, 0, 1, cmd_dummy, "", "", NULL, + BOOTM_STATE_OS_GO), };
static int boot_selected_os(int argc, char * const argv[], int state, @@ -752,9 +761,7 @@ static int do_bootm_subcommand(cmd_tbl_t *cmdtp, int flag, int argc, argc--; argv++;
if (c) { - state = (long)c->cmd; - if (state == BOOTM_STATE_START) - state |= BOOTM_STATE_FINDOS | BOOTM_STATE_FINDOTHER; + state = cmd_get_info(c); } else { /* Unrecognized command */ return CMD_RET_USAGE; @@ -765,6 +772,8 @@ static int do_bootm_subcommand(cmd_tbl_t *cmdtp, int flag, int argc, return CMD_RET_USAGE; }
+ if (state == BOOTM_STATE_START) + state |= BOOTM_STATE_FINDOS | BOOTM_STATE_FINDOTHER; ret = do_bootm_states(cmdtp, flag, argc, argv, state, &images, 0);
return ret; diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c index c53601c..a09263c 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -1201,7 +1201,7 @@ U_BOOT_CMD_COMPLETE( "edit environment variable", "name\n" " - edit environment variable 'name'", - var_complete + var_complete, 0 ); #endif
@@ -1211,7 +1211,7 @@ U_BOOT_CMD_COMPLETE( "[-a]\n - print [all] values of all environment variables\n" "printenv name ...\n" " - print value of environment variable 'name'", - var_complete + var_complete, 0 );
#ifdef CONFIG_CMD_GREPENV @@ -1229,7 +1229,7 @@ U_BOOT_CMD_COMPLETE( #endif " "-n": search variable names; "-v": search values;\n" " "-b": search both names and values (default)", - var_complete + var_complete, 0 ); #endif
@@ -1240,7 +1240,7 @@ U_BOOT_CMD_COMPLETE( " - [forcibly] set environment variable 'name' to 'value ...'\n" "setenv [-f] name\n" " - [forcibly] delete environment variable 'name'", - var_complete + var_complete, 0 );
#if defined(CONFIG_CMD_ASKENV) @@ -1259,7 +1259,7 @@ U_BOOT_CMD_COMPLETE( "run commands in an environment variable", "var [...]\n" " - run the commands in the environment variable(s) 'var'", - var_complete + var_complete, 0 ); #endif #endif /* CONFIG_SPL_BUILD */ diff --git a/common/command.c b/common/command.c index 746b7e3..35c9d71 100644 --- a/common/command.c +++ b/common/command.c @@ -536,7 +536,8 @@ enum command_ret_t cmd_process(int flag, int argc, char * const argv[], rc = cmd_call(cmdtp, flag, argc, argv); if (ticks) *ticks = get_timer(*ticks); - *repeatable &= cmdtp->repeatable; + if (!(cmdtp->info & CMD_INFO_REPEATABLE)) + *repeatable = 0; } if (rc == CMD_RET_USAGE) rc = cmd_usage(cmdtp); diff --git a/include/command.h b/include/command.h index d3f700f..53ec853 100644 --- a/include/command.h +++ b/include/command.h @@ -24,6 +24,12 @@ #endif
#ifndef __ASSEMBLY__ +enum { + CMD_INFO_MASK = 0xffffff, /* user data */ + CMD_INFO_REPEATABLE_SHIFT = 24, /* commaand is repeatable */ + CMD_INFO_REPEATABLE = 1U << CMD_INFO_REPEATABLE_SHIFT, +}; + /* * Monitor Command Table */ @@ -31,7 +37,7 @@ struct cmd_tbl_s { char *name; /* Command Name */ int maxargs; /* maximum number of arguments */ - int repeatable; /* autorepeat allowed? */ + int info; /* CMD_INFO_... flags */ /* Implementation function */ int (*cmd)(struct cmd_tbl_s *, int, int, char * const []); char *usage; /* Usage message (short) */ @@ -46,6 +52,12 @@ struct cmd_tbl_s {
typedef struct cmd_tbl_s cmd_tbl_t;
+/* Returns the info word for a command */ +static inline int cmd_get_info(struct cmd_tbl_s *cmd) +{ + return cmd->info & CMD_INFO_MASK; +} +
#if defined(CONFIG_CMD_RUN) extern int do_run(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); @@ -141,8 +153,6 @@ enum command_ret_t { int cmd_process(int flag, int argc, char * const argv[], int *repeatable, unsigned long *ticks);
-#endif /* __ASSEMBLY__ */ - /* * Command Flags: */ @@ -161,24 +171,35 @@ int cmd_process(int flag, int argc, char * const argv[], #endif
#define U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd, \ - _usage, _help, _comp) \ - { #_name, _maxargs, _rep, _cmd, _usage, \ - _CMD_HELP(_help) _CMD_COMPLETE(_comp) } + _usage, _help, _comp, _info) \ + { #_name, _maxargs, (_rep) << CMD_INFO_REPEATABLE_SHIFT | (_info), \ + _cmd, _usage, _CMD_HELP(_help) _CMD_COMPLETE(_comp) }
#define U_BOOT_CMD_MKENT(_name, _maxargs, _rep, _cmd, _usage, _help) \ U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd, \ - _usage, _help, NULL) + _usage, _help, NULL, 0)
-#define U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, _comp) \ +#define U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, \ + _comp, _info) \ ll_entry_declare(cmd_tbl_t, _name, cmd) = \ U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd, \ - _usage, _help, _comp); + _usage, _help, _comp, _info);
#define U_BOOT_CMD(_name, _maxargs, _rep, _cmd, _usage, _help) \ - U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, NULL) + U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, \ + NULL, 0)
#if defined(CONFIG_NEEDS_MANUAL_RELOC) void fixup_cmdtable(cmd_tbl_t *cmdtp, int size); #endif
+/* Dummy command for use in U_BOOT_CMD_MKENT() when none is needed */ +static inline int cmd_dummy(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + return 0; +} + +#endif /* __ASSEMBLY__ */ + #endif /* __COMMAND_H */

Commands are declared entirely within a macro, like this:
U_BOOT_CMD(...);
Sub-commands are not the same. At present the U_BOOT_CMD_MKENT() macro is used within an array declaration, but the array itself is not handled by macros. We have this:
static cmd_tbl_t table[] = { U_BOOT_CMD_MKENT(...), U_BOOT_CMD_MKENT(...), };
There are two problems with this. The first is that it requires knowledge of the command type (a minor issue). The second is that it is not possible to make sub-commands compile to nothing if we want to.
Introduce a new syntax which matches U_BOOT_CMD() as follows:
U_BOOT_SUBCMD_START U_BOOT_CMD_MKENT(...) U_BOOT_CMD_MKENT(...) U_BOOT_SUBCMD_END
Note that the U_BOOT_CMD_MKENT() lines no longer have a comma at the end. It would be possible to put a semicolon after U_BOOT_SUBCMD_END, but it seems syntactically odd to do so.
Signed-off-by: Simon Glass sjg@chromium.org ---
board/inka4x0/inkadiag.c | 12 ++++---- board/intercontrol/digsy_mtc/cmd_mtc.c | 20 ++++++------- common/cmd_bmp.c | 8 +++--- common/cmd_bootm.c | 22 +++++++------- common/cmd_bootstage.c | 10 +++---- common/cmd_clk.c | 6 ++-- common/cmd_demo.c | 10 +++---- common/cmd_i2c.c | 34 +++++++++++----------- common/cmd_nvedit.c | 32 ++++++++++----------- common/cmd_onenand.c | 23 ++++++++------- common/cmd_pxe.c | 6 ++-- common/cmd_sandbox.c | 14 ++++----- common/cmd_sound.c | 8 +++--- common/cmd_spl.c | 14 ++++----- common/cmd_tpm.c | 52 +++++++++++++++++----------------- drivers/gpio/pca953x.c | 14 ++++----- drivers/gpio/tca642x.c | 14 ++++----- drivers/misc/ds4510.c | 24 ++++++++-------- include/command.h | 37 +++++++++++++++++++----- test/dm/cmd_dm.c | 10 +++---- 20 files changed, 197 insertions(+), 173 deletions(-)
diff --git a/board/inka4x0/inkadiag.c b/board/inka4x0/inkadiag.c index 0bd12ec..56978b4 100644 --- a/board/inka4x0/inkadiag.c +++ b/board/inka4x0/inkadiag.c @@ -416,17 +416,17 @@ static int do_inkadiag_buzzer(cmd_tbl_t *cmdtp, int flag, int argc,
static int do_inkadiag_help(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
-cmd_tbl_t cmd_inkadiag_sub[] = { +U_BOOT_SUBCMD_START(cmd_inkadiag_sub) U_BOOT_CMD_MKENT(io, 1, 1, do_inkadiag_io, "read digital input", - "<drawer1|drawer2|other> [value] - get or set specified signal"), + "<drawer1|drawer2|other> [value] - get or set specified signal") U_BOOT_CMD_MKENT(serial, 4, 1, do_inkadiag_serial, "test serial port", "<num> <mode> <baudrate> <msg> - test uart num [0..11] in mode\n" - "and baudrate with msg"), + "and baudrate with msg") U_BOOT_CMD_MKENT(buzzer, 2, 1, do_inkadiag_buzzer, "activate buzzer", - "<period> <freq> - turn buzzer on for period ms with freq hz"), + "<period> <freq> - turn buzzer on for period ms with freq hz") U_BOOT_CMD_MKENT(help, 4, 1, do_inkadiag_help, "get help", - "[command] - get help for command"), -}; + "[command] - get help for command") +U_BOOT_SUBCMD_END
static int do_inkadiag_help(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { diff --git a/board/intercontrol/digsy_mtc/cmd_mtc.c b/board/intercontrol/digsy_mtc/cmd_mtc.c index f17ec55..1138a7a 100644 --- a/board/intercontrol/digsy_mtc/cmd_mtc.c +++ b/board/intercontrol/digsy_mtc/cmd_mtc.c @@ -292,32 +292,32 @@ static int do_mtc_state(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[
static int do_mtc_help(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
-cmd_tbl_t cmd_mtc_sub[] = { +U_BOOT_SUBCMD_START(cmd_mtc_sub) U_BOOT_CMD_MKENT(led, 3, 1, do_mtc_led, "set state of leds", "[ledname] [state] [blink]\n" " - lednames: diag can1 can2 can3 can4 usbpwr usbbusy user1 user2\n" " - state: off red green orange\n" - " - blink: blink interval in 100ms steps (1 - 10; 0 = static)\n"), + " - blink: blink interval in 100ms steps (1 - 10; 0 = static)\n") U_BOOT_CMD_MKENT(key, 0, 1, do_mtc_key, - "returns state of user key", ""), + "returns state of user key", "") U_BOOT_CMD_MKENT(version, 0, 1, do_mtc_version, - "returns firmware version of supervisor uC", ""), + "returns firmware version of supervisor uC", "") U_BOOT_CMD_MKENT(appreg, 1, 1, do_mtc_appreg, "reads or writes appreg value and stores in environment " "variable 'appreg'", - "[value] - value (1 - 255) to write to appreg"), + "[value] - value (1 - 255) to write to appreg") U_BOOT_CMD_MKENT(digin, 1, 1, do_mtc_digin, "returns state of digital input", - "<channel_num> - get state of digital input (1 or 2)\n"), + "<channel_num> - get state of digital input (1 or 2)\n") U_BOOT_CMD_MKENT(digout, 2, 1, do_mtc_digout, "sets digital outputs", - "<on|off> <on|off>- set state of digital output 1 and 2\n"), + "<on|off> <on|off>- set state of digital output 1 and 2\n") U_BOOT_CMD_MKENT(state, 0, 1, do_mtc_state, - "displays state", ""), + "displays state", "") U_BOOT_CMD_MKENT(help, 4, 1, do_mtc_help, "get help", - "[command] - get help for command\n"), -}; + "[command] - get help for command\n") +U_BOOT_SUBCMD_END
static int do_mtc_help(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { diff --git a/common/cmd_bmp.c b/common/cmd_bmp.c index cc904c2..aa650c9 100644 --- a/common/cmd_bmp.c +++ b/common/cmd_bmp.c @@ -131,10 +131,10 @@ static int do_bmp_display(cmd_tbl_t * cmdtp, int flag, int argc, char * const ar return (bmp_display(addr, x, y)); }
-static cmd_tbl_t cmd_bmp_sub[] = { - U_BOOT_CMD_MKENT(info, 3, 0, do_bmp_info, "", ""), - U_BOOT_CMD_MKENT(display, 5, 0, do_bmp_display, "", ""), -}; +U_BOOT_SUBCMD_START(cmd_bmp_sub) + U_BOOT_CMD_MKENT(info, 3, 0, do_bmp_info, "", "") + U_BOOT_CMD_MKENT(display, 5, 0, do_bmp_display, "", "") +U_BOOT_SUBCMD_END
#ifdef CONFIG_NEEDS_MANUAL_RELOC void bmp_reloc(void) { diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 14d504b..093f1b8 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -521,30 +521,30 @@ static int do_bootm_standalone(int flag, int argc, char * const argv[],
/* we overload the cmd field with our state machine info instead of a * function pointer */ -static cmd_tbl_t cmd_bootm_sub[] = { +U_BOOT_SUBCMD_START(cmd_bootm_sub) U_BOOT_CMD_MKENT_COMPLETE(start, 0, 1, cmd_dummy, "", "", NULL, - BOOTM_STATE_START), + BOOTM_STATE_START) U_BOOT_CMD_MKENT_COMPLETE(loados, 0, 1, cmd_dummy, "", "", NULL, - BOOTM_STATE_LOADOS), + BOOTM_STATE_LOADOS) #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH U_BOOT_CMD_MKENT_COMPLETE(ramdisk, 0, 1, cmd_dummy, "", "", NULL, - BOOTM_STATE_RAMDISK), + BOOTM_STATE_RAMDISK) #endif #ifdef CONFIG_OF_LIBFDT U_BOOT_CMD_MKENT_COMPLETE(fdt, 0, 1, cmd_dummy, "", "", NULL, - BOOTM_STATE_FDT), + BOOTM_STATE_FDT) #endif U_BOOT_CMD_MKENT_COMPLETE(cmdline, 0, 1, cmd_dummy, "", "", NULL, - BOOTM_STATE_OS_CMDLINE), + BOOTM_STATE_OS_CMDLINE) U_BOOT_CMD_MKENT_COMPLETE(bdt, 0, 1, cmd_dummy, "", "", NULL, - BOOTM_STATE_OS_BD_T), + BOOTM_STATE_OS_BD_T) U_BOOT_CMD_MKENT_COMPLETE(prep, 0, 1, cmd_dummy, "", "", NULL, - BOOTM_STATE_OS_PREP), + BOOTM_STATE_OS_PREP) U_BOOT_CMD_MKENT_COMPLETE(fake, 0, 1, cmd_dummy, "", "", NULL, - BOOTM_STATE_OS_FAKE_GO), + BOOTM_STATE_OS_FAKE_GO) U_BOOT_CMD_MKENT_COMPLETE(go, 0, 1, cmd_dummy, "", "", NULL, - BOOTM_STATE_OS_GO), -}; + BOOTM_STATE_OS_GO) +U_BOOT_SUBCMD_END
static int boot_selected_os(int argc, char * const argv[], int state, bootm_headers_t *images, boot_os_fn *boot_fn) diff --git a/common/cmd_bootstage.c b/common/cmd_bootstage.c index 106894a..a6ea703 100644 --- a/common/cmd_bootstage.c +++ b/common/cmd_bootstage.c @@ -63,11 +63,11 @@ static int do_bootstage_stash(cmd_tbl_t *cmdtp, int flag, int argc, return 0; }
-static cmd_tbl_t cmd_bootstage_sub[] = { - U_BOOT_CMD_MKENT(report, 2, 1, do_bootstage_report, "", ""), - U_BOOT_CMD_MKENT(stash, 4, 0, do_bootstage_stash, "", ""), - U_BOOT_CMD_MKENT(unstash, 4, 0, do_bootstage_stash, "", ""), -}; +U_BOOT_SUBCMD_START(cmd_bootstage_sub) + U_BOOT_CMD_MKENT(report, 2, 1, do_bootstage_report, "", "") + U_BOOT_CMD_MKENT(stash, 4, 0, do_bootstage_stash, "", "") + U_BOOT_CMD_MKENT(unstash, 4, 0, do_bootstage_stash, "", "") +U_BOOT_SUBCMD_END
/* * Process a bootstage sub-command diff --git a/common/cmd_clk.c b/common/cmd_clk.c index 6d3d46a..c63bae5 100644 --- a/common/cmd_clk.c +++ b/common/cmd_clk.c @@ -19,9 +19,9 @@ static int do_clk_dump(cmd_tbl_t *cmdtp, int flag, int argc, return soc_clk_dump(); }
-static cmd_tbl_t cmd_clk_sub[] = { - U_BOOT_CMD_MKENT(dump, 1, 1, do_clk_dump, "", ""), -}; +U_BOOT_SUBCMD_START(cmd_clk_sub) + U_BOOT_CMD_MKENT(dump, 1, 1, do_clk_dump, "", "") +U_BOOT_SUBCMD_END
static int do_clk(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) diff --git a/common/cmd_demo.c b/common/cmd_demo.c index a3bba7f..a6446dd 100644 --- a/common/cmd_demo.c +++ b/common/cmd_demo.c @@ -58,11 +58,11 @@ int do_demo_list(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return cmd_process_error(cmdtp, ret); }
-static cmd_tbl_t demo_commands[] = { - U_BOOT_CMD_MKENT(list, 0, 1, do_demo_list, "", ""), - U_BOOT_CMD_MKENT(hello, 2, 1, do_demo_hello, "", ""), - U_BOOT_CMD_MKENT(status, 1, 1, do_demo_status, "", ""), -}; +U_BOOT_SUBCMD_START(demo_commands) + U_BOOT_CMD_MKENT(list, 0, 1, do_demo_list, "", "") + U_BOOT_CMD_MKENT(hello, 2, 1, do_demo_hello, "", "") + U_BOOT_CMD_MKENT(status, 1, 1, do_demo_status, "", "") +U_BOOT_SUBCMD_END
static int do_demo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c index ebce7d4..1401835 100644 --- a/common/cmd_i2c.c +++ b/common/cmd_i2c.c @@ -1529,32 +1529,32 @@ static int do_i2c_reset(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv return 0; }
-static cmd_tbl_t cmd_i2c_sub[] = { +U_BOOT_SUBCMD_START(cmd_i2c_sub) #if defined(CONFIG_SYS_I2C) - U_BOOT_CMD_MKENT(bus, 1, 1, do_i2c_show_bus, "", ""), + U_BOOT_CMD_MKENT(bus, 1, 1, do_i2c_show_bus, "", "") #endif - U_BOOT_CMD_MKENT(crc32, 3, 1, do_i2c_crc, "", ""), + U_BOOT_CMD_MKENT(crc32, 3, 1, do_i2c_crc, "", "") #if defined(CONFIG_SYS_I2C) || \ defined(CONFIG_I2C_MULTI_BUS) - U_BOOT_CMD_MKENT(dev, 1, 1, do_i2c_bus_num, "", ""), + U_BOOT_CMD_MKENT(dev, 1, 1, do_i2c_bus_num, "", "") #endif /* CONFIG_I2C_MULTI_BUS */ #if defined(CONFIG_I2C_EDID) - U_BOOT_CMD_MKENT(edid, 1, 1, do_edid, "", ""), + U_BOOT_CMD_MKENT(edid, 1, 1, do_edid, "", "") #endif /* CONFIG_I2C_EDID */ - U_BOOT_CMD_MKENT(loop, 3, 1, do_i2c_loop, "", ""), - U_BOOT_CMD_MKENT(md, 3, 1, do_i2c_md, "", ""), - U_BOOT_CMD_MKENT(mm, 2, 1, do_i2c_mm, "", ""), - U_BOOT_CMD_MKENT(mw, 3, 1, do_i2c_mw, "", ""), - U_BOOT_CMD_MKENT(nm, 2, 1, do_i2c_nm, "", ""), - U_BOOT_CMD_MKENT(probe, 0, 1, do_i2c_probe, "", ""), - U_BOOT_CMD_MKENT(read, 5, 1, do_i2c_read, "", ""), - U_BOOT_CMD_MKENT(write, 5, 0, do_i2c_write, "", ""), - U_BOOT_CMD_MKENT(reset, 0, 1, do_i2c_reset, "", ""), + U_BOOT_CMD_MKENT(loop, 3, 1, do_i2c_loop, "", "") + U_BOOT_CMD_MKENT(md, 3, 1, do_i2c_md, "", "") + U_BOOT_CMD_MKENT(mm, 2, 1, do_i2c_mm, "", "") + U_BOOT_CMD_MKENT(mw, 3, 1, do_i2c_mw, "", "") + U_BOOT_CMD_MKENT(nm, 2, 1, do_i2c_nm, "", "") + U_BOOT_CMD_MKENT(probe, 0, 1, do_i2c_probe, "", "") + U_BOOT_CMD_MKENT(read, 5, 1, do_i2c_read, "", "") + U_BOOT_CMD_MKENT(write, 5, 0, do_i2c_write, "", "") + U_BOOT_CMD_MKENT(reset, 0, 1, do_i2c_reset, "", "") #if defined(CONFIG_CMD_SDRAM) - U_BOOT_CMD_MKENT(sdram, 1, 1, do_sdram, "", ""), + U_BOOT_CMD_MKENT(sdram, 1, 1, do_sdram, "", "") #endif - U_BOOT_CMD_MKENT(speed, 1, 1, do_i2c_bus_speed, "", ""), -}; + U_BOOT_CMD_MKENT(speed, 1, 1, do_i2c_bus_speed, "", "") +U_BOOT_SUBCMD_END
#ifdef CONFIG_NEEDS_MANUAL_RELOC void i2c_reloc(void) { diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c index a09263c..8603e36 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -1080,42 +1080,42 @@ static int do_env_exists(cmd_tbl_t *cmdtp, int flag, int argc, /* * New command line interface: "env" command with subcommands */ -static cmd_tbl_t cmd_env_sub[] = { +U_BOOT_SUBCMD_START(cmd_env_sub) #if defined(CONFIG_CMD_ASKENV) - U_BOOT_CMD_MKENT(ask, CONFIG_SYS_MAXARGS, 1, do_env_ask, "", ""), + U_BOOT_CMD_MKENT(ask, CONFIG_SYS_MAXARGS, 1, do_env_ask, "", "") #endif - U_BOOT_CMD_MKENT(default, 1, 0, do_env_default, "", ""), - U_BOOT_CMD_MKENT(delete, CONFIG_SYS_MAXARGS, 0, do_env_delete, "", ""), + U_BOOT_CMD_MKENT(default, 1, 0, do_env_default, "", "") + U_BOOT_CMD_MKENT(delete, CONFIG_SYS_MAXARGS, 0, do_env_delete, "", "") #if defined(CONFIG_CMD_EDITENV) - U_BOOT_CMD_MKENT(edit, 2, 0, do_env_edit, "", ""), + U_BOOT_CMD_MKENT(edit, 2, 0, do_env_edit, "", "") #endif #if defined(CONFIG_CMD_ENV_CALLBACK) - U_BOOT_CMD_MKENT(callbacks, 1, 0, do_env_callback, "", ""), + U_BOOT_CMD_MKENT(callbacks, 1, 0, do_env_callback, "", "") #endif #if defined(CONFIG_CMD_ENV_FLAGS) - U_BOOT_CMD_MKENT(flags, 1, 0, do_env_flags, "", ""), + U_BOOT_CMD_MKENT(flags, 1, 0, do_env_flags, "", "") #endif #if defined(CONFIG_CMD_EXPORTENV) - U_BOOT_CMD_MKENT(export, 4, 0, do_env_export, "", ""), + U_BOOT_CMD_MKENT(export, 4, 0, do_env_export, "", "") #endif #if defined(CONFIG_CMD_GREPENV) - U_BOOT_CMD_MKENT(grep, CONFIG_SYS_MAXARGS, 1, do_env_grep, "", ""), + U_BOOT_CMD_MKENT(grep, CONFIG_SYS_MAXARGS, 1, do_env_grep, "", "") #endif #if defined(CONFIG_CMD_IMPORTENV) - U_BOOT_CMD_MKENT(import, 5, 0, do_env_import, "", ""), + U_BOOT_CMD_MKENT(import, 5, 0, do_env_import, "", "") #endif - U_BOOT_CMD_MKENT(print, CONFIG_SYS_MAXARGS, 1, do_env_print, "", ""), + U_BOOT_CMD_MKENT(print, CONFIG_SYS_MAXARGS, 1, do_env_print, "", "") #if defined(CONFIG_CMD_RUN) - U_BOOT_CMD_MKENT(run, CONFIG_SYS_MAXARGS, 1, do_run, "", ""), + U_BOOT_CMD_MKENT(run, CONFIG_SYS_MAXARGS, 1, do_run, "", "") #endif #if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_ENV_IS_NOWHERE) - U_BOOT_CMD_MKENT(save, 1, 0, do_env_save, "", ""), + U_BOOT_CMD_MKENT(save, 1, 0, do_env_save, "", "") #endif - U_BOOT_CMD_MKENT(set, CONFIG_SYS_MAXARGS, 0, do_env_set, "", ""), + U_BOOT_CMD_MKENT(set, CONFIG_SYS_MAXARGS, 0, do_env_set, "", "") #if defined(CONFIG_CMD_ENV_EXISTS) - U_BOOT_CMD_MKENT(exists, 2, 0, do_env_exists, "", ""), + U_BOOT_CMD_MKENT(exists, 2, 0, do_env_exists, "", "") #endif -}; +U_BOOT_SUBCMD_END
#if defined(CONFIG_NEEDS_MANUAL_RELOC) void env_reloc(void) diff --git a/common/cmd_onenand.c b/common/cmd_onenand.c index 06cc140..2b17aff 100644 --- a/common/cmd_onenand.c +++ b/common/cmd_onenand.c @@ -546,17 +546,18 @@ static int do_onenand_markbad(cmd_tbl_t * cmdtp, int flag, int argc, char * cons return ret; }
-static cmd_tbl_t cmd_onenand_sub[] = { - U_BOOT_CMD_MKENT(info, 1, 0, do_onenand_info, "", ""), - U_BOOT_CMD_MKENT(bad, 1, 0, do_onenand_bad, "", ""), - U_BOOT_CMD_MKENT(read, 4, 0, do_onenand_read, "", ""), - U_BOOT_CMD_MKENT(write, 4, 0, do_onenand_write, "", ""), - U_BOOT_CMD_MKENT(write.yaffs, 4, 0, do_onenand_write, "", ""), - U_BOOT_CMD_MKENT(erase, 3, 0, do_onenand_erase, "", ""), - U_BOOT_CMD_MKENT(test, 3, 0, do_onenand_test, "", ""), - U_BOOT_CMD_MKENT(dump, 2, 0, do_onenand_dump, "", ""), - U_BOOT_CMD_MKENT(markbad, CONFIG_SYS_MAXARGS, 0, do_onenand_markbad, "", ""), -}; +U_BOOT_SUBCMD_START(cmd_onenand_sub) + U_BOOT_CMD_MKENT(info, 1, 0, do_onenand_info, "", "") + U_BOOT_CMD_MKENT(bad, 1, 0, do_onenand_bad, "", "") + U_BOOT_CMD_MKENT(read, 4, 0, do_onenand_read, "", "") + U_BOOT_CMD_MKENT(write, 4, 0, do_onenand_write, "", "") + U_BOOT_CMD_MKENT(write.yaffs, 4, 0, do_onenand_write, "", "") + U_BOOT_CMD_MKENT(erase, 3, 0, do_onenand_erase, "", "") + U_BOOT_CMD_MKENT(test, 3, 0, do_onenand_test, "", "") + U_BOOT_CMD_MKENT(dump, 2, 0, do_onenand_dump, "", "") + U_BOOT_CMD_MKENT(markbad, CONFIG_SYS_MAXARGS, 0, do_onenand_markbad, + "", "") +U_BOOT_SUBCMD_END
#ifdef CONFIG_NEEDS_MANUAL_RELOC void onenand_reloc(void) { diff --git a/common/cmd_pxe.c b/common/cmd_pxe.c index 3483328..16ffdab 100644 --- a/common/cmd_pxe.c +++ b/common/cmd_pxe.c @@ -1557,10 +1557,10 @@ do_pxe_boot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return 0; }
-static cmd_tbl_t cmd_pxe_sub[] = { - U_BOOT_CMD_MKENT(get, 1, 1, do_pxe_get, "", ""), +U_BOOT_SUBCMD_START(cmd_pxe_sub) + U_BOOT_CMD_MKENT(get, 1, 1, do_pxe_get, "", "") U_BOOT_CMD_MKENT(boot, 2, 1, do_pxe_boot, "", "") -}; +U_BOOT_SUBCMD_END
int do_pxe(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { diff --git a/common/cmd_sandbox.c b/common/cmd_sandbox.c index 00982b1..50470ea 100644 --- a/common/cmd_sandbox.c +++ b/common/cmd_sandbox.c @@ -85,13 +85,13 @@ static int do_sandbox_info(cmd_tbl_t *cmdtp, int flag, int argc, return 0; }
-static cmd_tbl_t cmd_sandbox_sub[] = { - U_BOOT_CMD_MKENT(load, 7, 0, do_sandbox_load, "", ""), - U_BOOT_CMD_MKENT(ls, 3, 0, do_sandbox_ls, "", ""), - U_BOOT_CMD_MKENT(save, 6, 0, do_sandbox_save, "", ""), - U_BOOT_CMD_MKENT(bind, 3, 0, do_sandbox_bind, "", ""), - U_BOOT_CMD_MKENT(info, 3, 0, do_sandbox_info, "", ""), -}; +U_BOOT_SUBCMD_START(cmd_sandbox_sub) + U_BOOT_CMD_MKENT(load, 7, 0, do_sandbox_load, "", "") + U_BOOT_CMD_MKENT(ls, 3, 0, do_sandbox_ls, "", "") + U_BOOT_CMD_MKENT(save, 6, 0, do_sandbox_save, "", "") + U_BOOT_CMD_MKENT(bind, 3, 0, do_sandbox_bind, "", "") + U_BOOT_CMD_MKENT(info, 3, 0, do_sandbox_info, "", "") +U_BOOT_SUBCMD_END
static int do_sandbox(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) diff --git a/common/cmd_sound.c b/common/cmd_sound.c index f5dd8bc..7f02191 100644 --- a/common/cmd_sound.c +++ b/common/cmd_sound.c @@ -47,10 +47,10 @@ static int do_play(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) return 0; }
-static cmd_tbl_t cmd_sound_sub[] = { - U_BOOT_CMD_MKENT(init, 0, 1, do_init, "", ""), - U_BOOT_CMD_MKENT(play, 2, 1, do_play, "", ""), -}; +U_BOOT_SUBCMD_START(cmd_sound_sub) + U_BOOT_CMD_MKENT(init, 0, 1, do_init, "", "") + U_BOOT_CMD_MKENT(play, 2, 1, do_play, "", "") +U_BOOT_SUBCMD_END
/* process sound command */ static int do_sound(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) diff --git a/common/cmd_spl.c b/common/cmd_spl.c index 057764a..59dfb99 100644 --- a/common/cmd_spl.c +++ b/common/cmd_spl.c @@ -94,10 +94,10 @@ static int call_bootm(int argc, char * const argv[], const char *subcommand[]) return 0; }
-static cmd_tbl_t cmd_spl_export_sub[] = { - U_BOOT_CMD_MKENT(fdt, 0, 1, (void *)SPL_EXPORT_FDT, "", ""), - U_BOOT_CMD_MKENT(atags, 0, 1, (void *)SPL_EXPORT_ATAGS, "", ""), -}; +U_BOOT_SUBCMD_START(cmd_spl_export_sub) + U_BOOT_CMD_MKENT(fdt, 0, 1, (void *)SPL_EXPORT_FDT, "", "") + U_BOOT_CMD_MKENT(atags, 0, 1, (void *)SPL_EXPORT_ATAGS, "", "") +U_BOOT_SUBCMD_END
static int spl_export(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { @@ -133,9 +133,9 @@ static int spl_export(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return 0; }
-static cmd_tbl_t cmd_spl_sub[] = { - U_BOOT_CMD_MKENT(export, 0, 1, (void *)SPL_EXPORT, "", ""), -}; +U_BOOT_SUBCMD_START(cmd_spl_sub) + U_BOOT_CMD_MKENT(export, 0, 1, (void *)SPL_EXPORT, "", "") +U_BOOT_SUBCMD_END
static int do_spl(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { diff --git a/common/cmd_tpm.c b/common/cmd_tpm.c index 0294952..35e0be4 100644 --- a/common/cmd_tpm.c +++ b/common/cmd_tpm.c @@ -606,58 +606,58 @@ TPM_COMMAND_NO_ARG(tpm_end_oiap) #define MAKE_TPM_CMD_ENTRY(cmd) \ U_BOOT_CMD_MKENT(cmd, 0, 1, do_tpm_ ## cmd, "", "")
-static cmd_tbl_t tpm_commands[] = { +U_BOOT_SUBCMD_START(tpm_commands) U_BOOT_CMD_MKENT(init, 0, 1, - do_tpm_init, "", ""), + do_tpm_init, "", "") U_BOOT_CMD_MKENT(startup, 0, 1, - do_tpm_startup, "", ""), + do_tpm_startup, "", "") U_BOOT_CMD_MKENT(self_test_full, 0, 1, - do_tpm_self_test_full, "", ""), + do_tpm_self_test_full, "", "") U_BOOT_CMD_MKENT(continue_self_test, 0, 1, - do_tpm_continue_self_test, "", ""), + do_tpm_continue_self_test, "", "") U_BOOT_CMD_MKENT(force_clear, 0, 1, - do_tpm_force_clear, "", ""), + do_tpm_force_clear, "", "") U_BOOT_CMD_MKENT(physical_enable, 0, 1, - do_tpm_physical_enable, "", ""), + do_tpm_physical_enable, "", "") U_BOOT_CMD_MKENT(physical_disable, 0, 1, - do_tpm_physical_disable, "", ""), + do_tpm_physical_disable, "", "") U_BOOT_CMD_MKENT(nv_define_space, 0, 1, - do_tpm_nv_define_space, "", ""), + do_tpm_nv_define_space, "", "") U_BOOT_CMD_MKENT(nv_read_value, 0, 1, - do_tpm_nv_read_value, "", ""), + do_tpm_nv_read_value, "", "") U_BOOT_CMD_MKENT(nv_write_value, 0, 1, - do_tpm_nv_write_value, "", ""), + do_tpm_nv_write_value, "", "") U_BOOT_CMD_MKENT(extend, 0, 1, - do_tpm_extend, "", ""), + do_tpm_extend, "", "") U_BOOT_CMD_MKENT(pcr_read, 0, 1, - do_tpm_pcr_read, "", ""), + do_tpm_pcr_read, "", "") U_BOOT_CMD_MKENT(tsc_physical_presence, 0, 1, - do_tpm_tsc_physical_presence, "", ""), + do_tpm_tsc_physical_presence, "", "") U_BOOT_CMD_MKENT(read_pubek, 0, 1, - do_tpm_read_pubek, "", ""), + do_tpm_read_pubek, "", "") U_BOOT_CMD_MKENT(physical_set_deactivated, 0, 1, - do_tpm_physical_set_deactivated, "", ""), + do_tpm_physical_set_deactivated, "", "") U_BOOT_CMD_MKENT(get_capability, 0, 1, - do_tpm_get_capability, "", ""), + do_tpm_get_capability, "", "") U_BOOT_CMD_MKENT(raw_transfer, 0, 1, - do_tpm_raw_transfer, "", ""), + do_tpm_raw_transfer, "", "") U_BOOT_CMD_MKENT(nv_define, 0, 1, - do_tpm_nv_define, "", ""), + do_tpm_nv_define, "", "") U_BOOT_CMD_MKENT(nv_read, 0, 1, - do_tpm_nv_read, "", ""), + do_tpm_nv_read, "", "") U_BOOT_CMD_MKENT(nv_write, 0, 1, - do_tpm_nv_write, "", ""), + do_tpm_nv_write, "", "") #ifdef CONFIG_TPM_AUTH_SESSIONS U_BOOT_CMD_MKENT(oiap, 0, 1, - do_tpm_oiap, "", ""), + do_tpm_oiap, "", "") U_BOOT_CMD_MKENT(end_oiap, 0, 1, - do_tpm_end_oiap, "", ""), + do_tpm_end_oiap, "", "") U_BOOT_CMD_MKENT(load_key2_oiap, 0, 1, - do_tpm_load_key2_oiap, "", ""), + do_tpm_load_key2_oiap, "", "") U_BOOT_CMD_MKENT(get_pub_key_oiap, 0, 1, - do_tpm_get_pub_key_oiap, "", ""), + do_tpm_get_pub_key_oiap, "", "") #endif /* CONFIG_TPM_AUTH_SESSIONS */ -}; +U_BOOT_SUBCMD_END
static int do_tpm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c index 7371cd4..2ce5866 100644 --- a/drivers/gpio/pca953x.c +++ b/drivers/gpio/pca953x.c @@ -205,15 +205,15 @@ static int pca953x_info(uint8_t chip) } #endif /* CONFIG_CMD_PCA953X_INFO */
-cmd_tbl_t cmd_pca953x[] = { - U_BOOT_CMD_MKENT(device, 3, 0, (void *)PCA953X_CMD_DEVICE, "", ""), - U_BOOT_CMD_MKENT(output, 4, 0, (void *)PCA953X_CMD_OUTPUT, "", ""), - U_BOOT_CMD_MKENT(input, 3, 0, (void *)PCA953X_CMD_INPUT, "", ""), - U_BOOT_CMD_MKENT(invert, 4, 0, (void *)PCA953X_CMD_INVERT, "", ""), +U_BOOT_SUBCMD_START(cmd_pca953x) + U_BOOT_CMD_MKENT(device, 3, 0, (void *)PCA953X_CMD_DEVICE, "", "") + U_BOOT_CMD_MKENT(output, 4, 0, (void *)PCA953X_CMD_OUTPUT, "", "") + U_BOOT_CMD_MKENT(input, 3, 0, (void *)PCA953X_CMD_INPUT, "", "") + U_BOOT_CMD_MKENT(invert, 4, 0, (void *)PCA953X_CMD_INVERT, "", "") #ifdef CONFIG_CMD_PCA953X_INFO - U_BOOT_CMD_MKENT(info, 2, 0, (void *)PCA953X_CMD_INFO, "", ""), + U_BOOT_CMD_MKENT(info, 2, 0, (void *)PCA953X_CMD_INFO, "", "") #endif -}; +U_BOOT_SUBCMD_END
int do_pca953x(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { diff --git a/drivers/gpio/tca642x.c b/drivers/gpio/tca642x.c index 6386835..c750020 100644 --- a/drivers/gpio/tca642x.c +++ b/drivers/gpio/tca642x.c @@ -212,13 +212,13 @@ static int tca642x_info(uchar chip) return 0; }
-cmd_tbl_t cmd_tca642x[] = { - U_BOOT_CMD_MKENT(device, 3, 0, (void *)TCA642X_CMD_DEVICE, "", ""), - U_BOOT_CMD_MKENT(output, 4, 0, (void *)TCA642X_CMD_OUTPUT, "", ""), - U_BOOT_CMD_MKENT(input, 3, 0, (void *)TCA642X_CMD_INPUT, "", ""), - U_BOOT_CMD_MKENT(invert, 4, 0, (void *)TCA642X_CMD_INVERT, "", ""), - U_BOOT_CMD_MKENT(info, 2, 0, (void *)TCA642X_CMD_INFO, "", ""), -}; +U_BOOT_SUBCMD_START(cmd_tca642x) + U_BOOT_CMD_MKENT(device, 3, 0, (void *)TCA642X_CMD_DEVICE, "", "") + U_BOOT_CMD_MKENT(output, 4, 0, (void *)TCA642X_CMD_OUTPUT, "", "") + U_BOOT_CMD_MKENT(input, 3, 0, (void *)TCA642X_CMD_INPUT, "", "") + U_BOOT_CMD_MKENT(invert, 4, 0, (void *)TCA642X_CMD_INVERT, "", "") + U_BOOT_CMD_MKENT(info, 2, 0, (void *)TCA642X_CMD_INFO, "", "") +U_BOOT_SUBCMD_END
int do_tca642x(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { diff --git a/drivers/misc/ds4510.c b/drivers/misc/ds4510.c index aa893c3..e6b16a0 100644 --- a/drivers/misc/ds4510.c +++ b/drivers/misc/ds4510.c @@ -254,24 +254,24 @@ static int ds4510_info(uint8_t chip) } #endif /* CONFIG_CMD_DS4510_INFO */
-cmd_tbl_t cmd_ds4510[] = { - U_BOOT_CMD_MKENT(device, 3, 0, (void *)DS4510_CMD_DEVICE, "", ""), - U_BOOT_CMD_MKENT(nv, 3, 0, (void *)DS4510_CMD_NV, "", ""), - U_BOOT_CMD_MKENT(output, 4, 0, (void *)DS4510_CMD_OUTPUT, "", ""), - U_BOOT_CMD_MKENT(input, 3, 0, (void *)DS4510_CMD_INPUT, "", ""), - U_BOOT_CMD_MKENT(pullup, 4, 0, (void *)DS4510_CMD_PULLUP, "", ""), +U_BOOT_SUBCMD_START(cmd_ds4510) + U_BOOT_CMD_MKENT(device, 3, 0, (void *)DS4510_CMD_DEVICE, "", "") + U_BOOT_CMD_MKENT(nv, 3, 0, (void *)DS4510_CMD_NV, "", "") + U_BOOT_CMD_MKENT(output, 4, 0, (void *)DS4510_CMD_OUTPUT, "", "") + U_BOOT_CMD_MKENT(input, 3, 0, (void *)DS4510_CMD_INPUT, "", "") + U_BOOT_CMD_MKENT(pullup, 4, 0, (void *)DS4510_CMD_PULLUP, "", "") #ifdef CONFIG_CMD_DS4510_INFO - U_BOOT_CMD_MKENT(info, 2, 0, (void *)DS4510_CMD_INFO, "", ""), + U_BOOT_CMD_MKENT(info, 2, 0, (void *)DS4510_CMD_INFO, "", "") #endif #ifdef CONFIG_CMD_DS4510_RST - U_BOOT_CMD_MKENT(rstdelay, 3, 0, (void *)DS4510_CMD_RSTDELAY, "", ""), + U_BOOT_CMD_MKENT(rstdelay, 3, 0, (void *)DS4510_CMD_RSTDELAY, "", "") #endif #ifdef CONFIG_CMD_DS4510_MEM - U_BOOT_CMD_MKENT(eeprom, 6, 0, (void *)DS4510_CMD_EEPROM, "", ""), - U_BOOT_CMD_MKENT(seeprom, 6, 0, (void *)DS4510_CMD_SEEPROM, "", ""), - U_BOOT_CMD_MKENT(sram, 6, 0, (void *)DS4510_CMD_SRAM, "", ""), + U_BOOT_CMD_MKENT(eeprom, 6, 0, (void *)DS4510_CMD_EEPROM, "", "") + U_BOOT_CMD_MKENT(seeprom, 6, 0, (void *)DS4510_CMD_SEEPROM, "", "") + U_BOOT_CMD_MKENT(sram, 6, 0, (void *)DS4510_CMD_SRAM, "", "") #endif -}; +U_BOOT_SUBCMD_END
int do_ds4510(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { diff --git a/include/command.h b/include/command.h index 53ec853..1a3871f 100644 --- a/include/command.h +++ b/include/command.h @@ -170,20 +170,43 @@ int cmd_process(int flag, int argc, char * const argv[], # define _CMD_HELP(x) #endif
-#define U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd, \ - _usage, _help, _comp, _info) \ +/* + * These macros help declare commands. They are set up in such as way that + * it is possible to completely remove all commands when CONFIG_CMDLINE is + * not defined. + * + * Usage is: + * U_BOOT_SUBCMD_START(name) + * U_BOOT_CMD_MKENT(...) (or U_BOOT_CMD_MKENT_COMPLETE) + * U_BOOT_CMD_MKENT(...) + * ... + * U_BOOT_SUBCMD_END + * + * We need to ensure that a command is placed between each entry + */ +#define U_BOOT_SUBCMD_START(name) static cmd_tbl_t name[] = { +#define U_BOOT_SUBCMD_END }; +#define U_BOOT_CMD_MKENT_LINE(_name, _maxargs, _rep, _cmd, _usage, \ + _help, _comp, _info) \ { #_name, _maxargs, (_rep) << CMD_INFO_REPEATABLE_SHIFT | (_info), \ _cmd, _usage, _CMD_HELP(_help) _CMD_COMPLETE(_comp) }
-#define U_BOOT_CMD_MKENT(_name, _maxargs, _rep, _cmd, _usage, _help) \ - U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd, \ - _usage, _help, NULL, 0) +/* Add a comma to separate lines */ +#define U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, \ + _help, _comp, _info) \ + U_BOOT_CMD_MKENT_LINE(_name, _maxargs, _rep, _cmd, _usage, \ + _help, _comp, _info),
+/* Here we want a semicolon after the (single) entry */ #define U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, \ _comp, _info) \ ll_entry_declare(cmd_tbl_t, _name, cmd) = \ - U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd, \ - _usage, _help, _comp, _info); + U_BOOT_CMD_MKENT_LINE(_name, _maxargs, _rep, _cmd, \ + _usage, _help, _comp, _info); + +#define U_BOOT_CMD_MKENT(_name, _maxargs, _rep, _cmd, _usage, _help) \ + U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd, \ + _usage, _help, NULL, 0)
#define U_BOOT_CMD(_name, _maxargs, _rep, _cmd, _usage, _help) \ U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, \ diff --git a/test/dm/cmd_dm.c b/test/dm/cmd_dm.c index a03fe20..8395429 100644 --- a/test/dm/cmd_dm.c +++ b/test/dm/cmd_dm.c @@ -99,11 +99,11 @@ static int do_dm_test(cmd_tbl_t *cmdtp, int flag, int argc, return dm_test_main(); }
-static cmd_tbl_t test_commands[] = { - U_BOOT_CMD_MKENT(tree, 0, 1, do_dm_dump_all, "", ""), - U_BOOT_CMD_MKENT(uclass, 1, 1, do_dm_dump_uclass, "", ""), - U_BOOT_CMD_MKENT(test, 1, 1, do_dm_test, "", ""), -}; +U_BOOT_SUBCMD_START(test_commands) + U_BOOT_CMD_MKENT(tree, 0, 1, do_dm_dump_all, "", "") + U_BOOT_CMD_MKENT(uclass, 1, 1, do_dm_dump_uclass, "", "") + U_BOOT_CMD_MKENT(test, 1, 1, do_dm_test, "", "") +U_BOOT_SUBCMD_END
static int do_dm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) {

A large chunk of the U-Boot code is the command line. For some applications this is not needed, since the boot can be controlled by a board-specific hard-coded boot procedure. This saves a significant amount of space.
This makes U-Boot proper look a little more like SPL in terms of size.
Signed-off-by: Simon Glass sjg@chromium.org ---
README | 8 ++++++++ arch/x86/cpu/u-boot.lds | 4 ++++ common/cmd_cbfs.c | 3 ++- common/cmd_help.c | 4 ++++ common/command.c | 2 ++ common/main.c | 6 ++++++ include/command.h | 30 ++++++++++++++++++++++++++++++ include/config_defaults.h | 2 ++ include/config_fallbacks.h | 7 +++++++ 9 files changed, 65 insertions(+), 1 deletion(-)
diff --git a/README b/README index 216f0c7..28c79fb 100644 --- a/README +++ b/README @@ -1035,6 +1035,14 @@ The following options need to be configured:
XXX - this list needs to get updated!
+- Removal of commands + If no commands are needed to boot, you can undefine + CONFIG_CMDLINE in your board config file to remove them. + In this case, the command line will not be available, and + when U-Boot wants to execute the boot command (on start-up) + it will call board_run_command() instead. This can reduce + image size significantly for very simple boot procedures. + - Regular expression support: CONFIG_REGEX If this variable is defined, U-Boot is linked against diff --git a/arch/x86/cpu/u-boot.lds b/arch/x86/cpu/u-boot.lds index f48bff5..9720286 100644 --- a/arch/x86/cpu/u-boot.lds +++ b/arch/x86/cpu/u-boot.lds @@ -12,6 +12,10 @@ ENTRY(_start)
SECTIONS { +#ifndef CONFIG_CMDLINE + /DISCARD/ : { *(.u_boot_list_2_cmd_*) } +#endif + . = CONFIG_SYS_TEXT_BASE; /* Location of bootcode in flash */ __text_start = .; .text : { *(.text*); } diff --git a/common/cmd_cbfs.c b/common/cmd_cbfs.c index 35d8a7a..5f1add8 100644 --- a/common/cmd_cbfs.c +++ b/common/cmd_cbfs.c @@ -44,7 +44,8 @@ U_BOOT_CMD( " CBFS is in. It defaults to 0xFFFFFFFF\n" );
-int do_cbfs_fsload(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +static int do_cbfs_fsload(cmd_tbl_t *cmdtp, int flag, int argc, + char *const argv[]) { const struct cbfs_cachenode *file; unsigned long offset; diff --git a/common/cmd_help.c b/common/cmd_help.c index 6ff494d..701ae7e 100644 --- a/common/cmd_help.c +++ b/common/cmd_help.c @@ -10,9 +10,13 @@
static int do_help(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { +#ifdef CONFIG_CMDLINE cmd_tbl_t *start = ll_entry_start(cmd_tbl_t, cmd); const int len = ll_entry_count(cmd_tbl_t, cmd); return _do_help(start, len, cmdtp, flag, argc, argv); +#else + return 0; +#endif }
U_BOOT_CMD( diff --git a/common/command.c b/common/command.c index 35c9d71..180ce27 100644 --- a/common/command.c +++ b/common/command.c @@ -87,6 +87,7 @@ int _do_help (cmd_tbl_t *cmd_start, int cmd_items, cmd_tbl_t * cmdtp, int */ cmd_tbl_t *find_cmd_tbl (const char *cmd, cmd_tbl_t *table, int table_len) { +#ifdef CONFIG_CMDLINE cmd_tbl_t *cmdtp; cmd_tbl_t *cmdtp_temp = table; /*Init value */ const char *p; @@ -115,6 +116,7 @@ cmd_tbl_t *find_cmd_tbl (const char *cmd, cmd_tbl_t *table, int table_len) if (n_found == 1) { /* exactly one match */ return cmdtp_temp; } +#endif /* CONFIG_CMDLINE */
return NULL; /* not found or ambiguous command */ } diff --git a/common/main.c b/common/main.c index 8b6f274..cb021d3 100644 --- a/common/main.c +++ b/common/main.c @@ -270,7 +270,9 @@ static int abortboot(int bootdelay) #if defined(CONFIG_BOOTDELAY) && defined(CONFIG_OF_CONTROL) static void secure_boot_cmd(char *cmd) { +#ifdef CONFIG_CMDLINE cmd_tbl_t *cmdtp; +#endif int rc;
if (!cmd) { @@ -282,6 +284,7 @@ static void secure_boot_cmd(char *cmd) disable_ctrlc(1);
/* Find the command directly. */ +#ifdef CONFIG_CMDLINE cmdtp = find_cmd(cmd); if (!cmdtp) { printf("## Error: "%s" not defined\n", cmd); @@ -290,6 +293,9 @@ static void secure_boot_cmd(char *cmd)
/* Run the command, forcing no flags and faking argc and argv. */ rc = (cmdtp->cmd)(cmdtp, 0, 1, &cmd); +#else + rc = board_run_command(cmd); +#endif
/* Shouldn't ever return from boot command. */ printf("## Error: "%s" returned (code %d)\n", cmd, rc); diff --git a/include/command.h b/include/command.h index 1a3871f..9f507d9 100644 --- a/include/command.h +++ b/include/command.h @@ -184,6 +184,7 @@ int cmd_process(int flag, int argc, char * const argv[], * * We need to ensure that a command is placed between each entry */ +#ifdef CONFIG_CMDLINE #define U_BOOT_SUBCMD_START(name) static cmd_tbl_t name[] = { #define U_BOOT_SUBCMD_END }; #define U_BOOT_CMD_MKENT_LINE(_name, _maxargs, _rep, _cmd, _usage, \ @@ -203,6 +204,26 @@ int cmd_process(int flag, int argc, char * const argv[], ll_entry_declare(cmd_tbl_t, _name, cmd) = \ U_BOOT_CMD_MKENT_LINE(_name, _maxargs, _rep, _cmd, \ _usage, _help, _comp, _info); +#else +#define U_BOOT_SUBCMD_START(name) static cmd_tbl_t name[] = {}; +#define U_BOOT_SUBCMD_END + +#define _CMD_REMOVE(_name, _cmd) \ + int __remove_ ## _name(void) \ + { \ + if (0) \ + _cmd(NULL, 0, 0, NULL); \ + return 0; \ + } +#define U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, \ + _help, _comp, _info) \ + _CMD_REMOVE(_name ## _cmd, _cmd) + +#define U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, \ + _comp, _info) \ + _CMD_REMOVE(sub_ ## _name, _cmd) + +#endif /* CONFIG_CMDLINE */
#define U_BOOT_CMD_MKENT(_name, _maxargs, _rep, _cmd, _usage, _help) \ U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd, \ @@ -223,6 +244,15 @@ static inline int cmd_dummy(cmd_tbl_t *cmdtp, int flag, int argc, return 0; }
+/* + * When there is no U-Boot command line, the board must provide a way of + * executing commands. + * + * @cmd: Command string to execute + * @return Result of command, CMD_RET_... + */ +int board_run_command(const char *cmd); + #endif /* __ASSEMBLY__ */
#endif /* __COMMAND_H */ diff --git a/include/config_defaults.h b/include/config_defaults.h index ad08c1d..913acaf 100644 --- a/include/config_defaults.h +++ b/include/config_defaults.h @@ -20,4 +20,6 @@ #define CONFIG_ZLIB 1 #define CONFIG_PARTITIONS 1
+#define CONFIG_CMDLINE + #endif diff --git a/include/config_fallbacks.h b/include/config_fallbacks.h index d8339b2..8b11b54 100644 --- a/include/config_fallbacks.h +++ b/include/config_fallbacks.h @@ -63,4 +63,11 @@ #define CONFIG_SYS_HZ 1000 #endif
+#ifndef CONFIG_CMDLINE +#undef CONFIG_CMDLINE_EDITING +#undef CONFIG_SYS_LONGHELP +#undef CONFIG_CMD_RUN +#undef CONFIG_SYS_HUSH_PARSER +#endif + #endif /* __CONFIG_FALLBACKS_H */

It would be better to split common/main.c into a few chunks: readline, the standard parser and the real main. However such a change is fairly invasive.
For now, use #ifdef to remove the unwanted code.
This helps to reduce the image size by removing unwanted code.
Signed-off-by: Simon Glass sjg@chromium.org ---
common/command.c | 7 +++++++ common/main.c | 26 ++++++++++++++++++++------ 2 files changed, 27 insertions(+), 6 deletions(-)
diff --git a/common/command.c b/common/command.c index 180ce27..dd09d08 100644 --- a/common/command.c +++ b/common/command.c @@ -481,6 +481,7 @@ void fixup_cmdtable(cmd_tbl_t *cmdtp, int size) } #endif
+#ifdef CONFIG_CMDLINE /** * Call a command function. This should be the only route in U-Boot to call * a command, so that we can track whether we are waiting for input or @@ -501,11 +502,14 @@ static int cmd_call(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) debug("Command failed, result=%d", result); return result; } +#endif /* CONFIG_CMDLINE */
enum command_ret_t cmd_process(int flag, int argc, char * const argv[], int *repeatable, ulong *ticks) { enum command_ret_t rc = CMD_RET_SUCCESS; + +#ifdef CONFIG_CMDLINE cmd_tbl_t *cmdtp;
/* Look up command in command table */ @@ -543,6 +547,9 @@ enum command_ret_t cmd_process(int flag, int argc, char * const argv[], } if (rc == CMD_RET_USAGE) rc = cmd_usage(cmdtp); +#else + rc = board_run_command(argv[0]); +#endif return rc; }
diff --git a/common/main.c b/common/main.c index cb021d3..2fdea01 100644 --- a/common/main.c +++ b/common/main.c @@ -45,7 +45,9 @@ void show_boot_progress (int val) __attribute__((weak, alias("__show_boot_progre
char console_buffer[CONFIG_SYS_CBSIZE + 1]; /* console I/O buffer */
+#ifdef CONFIG_CMDLINE static char * delete_char (char *buffer, char *p, int *colp, int *np, int plen); +#endif static const char erase_seq[] = "\b \b"; /* erase sequence */ static const char tab_seq[] = " "; /* used to expand TABs */
@@ -421,7 +423,7 @@ static void process_boot_delay(void)
void main_loop(void) { -#ifndef CONFIG_SYS_HUSH_PARSER +#if defined(CONFIG_CMDLINE) && !defined(CONFIG_SYS_HUSH_PARSER) static char lastcommand[CONFIG_SYS_CBSIZE] = { 0, }; int len; int rc = 1; @@ -464,8 +466,9 @@ void main_loop(void) # ifdef CONFIG_AUTOBOOT_KEYED int prev = disable_ctrlc(1); /* disable Control C checking */ # endif - +#ifdef CONFIG_CMDLINE run_command_list(p, -1, 0); +#endif
# ifdef CONFIG_AUTOBOOT_KEYED disable_ctrlc(prev); /* restore Control C checking */ @@ -483,6 +486,7 @@ void main_loop(void) /* * Main Loop for Monitor Command Processing */ +#ifdef CONFIG_CMDLINE #ifdef CONFIG_SYS_HUSH_PARSER parse_file_outer(); /* This point is never reached */ @@ -528,7 +532,8 @@ void main_loop(void) lastcommand[0] = 0; } } -#endif /*CONFIG_SYS_HUSH_PARSER*/ +#endif /* CONFIG_SYS_HUSH_PARSER */ +#endif /* CONFIG_CMDLINE */ }
#ifdef CONFIG_BOOT_RETRY_TIME @@ -983,6 +988,7 @@ static int cread_line(const char *const prompt, char *buf, unsigned int *len,
/****************************************************************************/
+#ifdef CONFIG_CMDLINE /* * Prompt for input and read a line. * If CONFIG_BOOT_RETRY_TIME is defined and retry_time >= 0, @@ -1211,10 +1217,10 @@ int parse_line (char *line, char *argv[]) debug_parser("parse_line: nargs=%d\n", nargs); return (nargs); } - +#endif /* CONFIG_CMDLINE */ /****************************************************************************/
-#ifndef CONFIG_SYS_HUSH_PARSER +#if !defined(CONFIG_SYS_HUSH_PARSER) && defined(CONFIG_CMDLINE) static void process_macros (const char *input, char *output) { char c, prev; @@ -1433,6 +1439,7 @@ static int builtin_run_command(const char *cmd, int flag) */ int run_command(const char *cmd, int flag) { +#ifdef CONFIG_CMDLINE #ifndef CONFIG_SYS_HUSH_PARSER /* * builtin_run_command can return 0 or 1 for success, so clean up @@ -1446,9 +1453,12 @@ int run_command(const char *cmd, int flag) return parse_string_outer(cmd, FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP); #endif +#else + return board_run_command(cmd); +#endif }
-#ifndef CONFIG_SYS_HUSH_PARSER +#if !defined(CONFIG_SYS_HUSH_PARSER) && defined(CONFIG_CMDLINE) /** * Execute a list of command separated by ; or \n using the built-in parser. * @@ -1493,6 +1503,7 @@ static int builtin_run_command_list(char *cmd, int flag)
int run_command_list(const char *cmd, int len, int flag) { +#ifdef CONFIG_CMDLINE int need_buff = 1; char *buff = (char *)cmd; /* cast away const */ int rcode = 0; @@ -1530,6 +1541,9 @@ int run_command_list(const char *cmd, int len, int flag) #endif
return rcode; +#else + return board_run_command(cmd); +#endif }
/****************************************************************************/

At present when this option is not defined, we do not process the FDT options - for example we do not run the boot command specified by the FDT. Move this code into the common function and make sure it is always called when CONFIG_OF_CONTROL is defined.
Signed-off-by: Simon Glass sjg@chromium.org ---
common/main.c | 69 ++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 45 insertions(+), 24 deletions(-)
diff --git a/common/main.c b/common/main.c index 2fdea01..0a65593 100644 --- a/common/main.c +++ b/common/main.c @@ -269,7 +269,7 @@ static int abortboot(int bootdelay) * printing the error message to console. */
-#if defined(CONFIG_BOOTDELAY) && defined(CONFIG_OF_CONTROL) +#if defined(CONFIG_OF_CONTROL) static void secure_boot_cmd(char *cmd) { #ifdef CONFIG_CMDLINE @@ -309,29 +309,54 @@ err: */ hang(); } +#endif /* CONFIG_OF_CONTROL */
-static void process_fdt_options(const void *blob) +/** + * Process options contained in the device tree + * + * This handles various features provided by the device tree, which can + * affect environment variables or operation on start-up. + * + * @param blob Device tree to process + * @param cmdp Returns the boot command obtained from the FDT + */ +static void process_fdt_options(const void *blob, char **cmdp) { +#ifdef CONFIG_OF_CONTROL ulong addr; + char *s = *cmdp, *env; + + /* Allow the fdt to override the boot command */ + env = fdtdec_get_config_string(blob, "bootcmd"); + if (env) + s = env;
/* Add an env variable to point to a kernel payload, if available */ - addr = fdtdec_get_config_int(gd->fdt_blob, "kernel-offset", 0); + addr = fdtdec_get_config_int(blob, "kernel-offset", 0); if (addr) setenv_addr("kernaddr", (void *)(CONFIG_SYS_TEXT_BASE + addr));
/* Add an env variable to point to a root disk, if available */ - addr = fdtdec_get_config_int(gd->fdt_blob, "rootdisk-offset", 0); + addr = fdtdec_get_config_int(blob, "rootdisk-offset", 0); if (addr) setenv_addr("rootaddr", (void *)(CONFIG_SYS_TEXT_BASE + addr)); -} + + /* + * If the bootsecure option was chosen, use secure_boot_cmd(). + * Always use 'env' in this case, since bootsecure requres that the + * bootcmd was specified in the FDT too. + */ + if (fdtdec_get_config_int(blob, "bootsecure", 0)) { + secure_boot_cmd(s); + panic("Secure boot command returned"); + } + *cmdp = s; #endif /* CONFIG_OF_CONTROL */ +}
#ifdef CONFIG_BOOTDELAY static void process_boot_delay(void) { -#ifdef CONFIG_OF_CONTROL - char *env; -#endif char *s; int bootdelay; #ifdef CONFIG_BOOTCOUNT_LIMIT @@ -379,23 +404,8 @@ static void process_boot_delay(void) else #endif /* CONFIG_BOOTCOUNT_LIMIT */ s = getenv ("bootcmd"); -#ifdef CONFIG_OF_CONTROL - /* Allow the fdt to override the boot command */ - env = fdtdec_get_config_string(gd->fdt_blob, "bootcmd"); - if (env) - s = env;
- process_fdt_options(gd->fdt_blob); - - /* - * If the bootsecure option was chosen, use secure_boot_cmd(). - * Always use 'env' in this case, since bootsecure requres that the - * bootcmd was specified in the FDT too. - */ - if (fdtdec_get_config_int(gd->fdt_blob, "bootsecure", 0)) - secure_boot_cmd(env); - -#endif /* CONFIG_OF_CONTROL */ + process_fdt_options(gd->fdt_blob, &s);
debug ("### main_loop: bootcmd="%s"\n", s ? s : "<UNDEFINED>");
@@ -482,6 +492,17 @@ void main_loop(void)
#ifdef CONFIG_BOOTDELAY process_boot_delay(); +#else + char *s = NULL; + + process_fdt_options(gd->fdt_blob, &s); + if (s) { +# ifdef CONFIG_CMDLINE + run_command_list(s, -1, 0); +# else + board_run_command(s); +# endif + } #endif /* * Main Loop for Monitor Command Processing

Add a simple board_run_command() function for sandbox. It does nothing except print the command that would be executed. This can be extended to perform actual tasks.
Signed-off-by: Simon Glass sjg@chromium.org ---
board/sandbox/sandbox/sandbox.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/board/sandbox/sandbox/sandbox.c b/board/sandbox/sandbox/sandbox.c index e4d4e02..71ccab3 100644 --- a/board/sandbox/sandbox/sandbox.c +++ b/board/sandbox/sandbox/sandbox.c @@ -78,6 +78,16 @@ int board_late_init(void) panic("Cannot init cros-ec device"); return -1; } + + return 0; +} +#endif + +#ifndef CONFIG_CMDLINE +int board_run_command(const char *cmd) +{ + printf("Run command: %s\n", cmd); + return 0; } #endif

On Mon, Mar 24, 2014 at 09:51:05AM -0600, Simon Glass wrote:
A large chunk of U-Boot's executable size is the code to process and execute commands. This is reasonable, since commands and scripts are an important part of U-Boot's feature set and provide much of its flexibility.
However, for some applications only a very limited set of commands is required. Where image size is important, it is desirable to be able to easily remove unwanted code.
This series introduces a new board_run_command() function which can be used to run a small subset of commands as required by the board (typically load and bootm), thus allowing the rest of the commands to be automatically and reliably dropped from the image using toolchain dead code elimination.
This is an interesting concept certainly. Can you also provide a non-trivial example here?

Hi Tom,
On 31 March 2014 12:30, Tom Rini trini@ti.com wrote:
On Mon, Mar 24, 2014 at 09:51:05AM -0600, Simon Glass wrote:
A large chunk of U-Boot's executable size is the code to process and execute commands. This is reasonable, since commands and scripts are an important part of U-Boot's feature set and provide much of its flexibility.
However, for some applications only a very limited set of commands is required. Where image size is important, it is desirable to be able to easily remove unwanted code.
This series introduces a new board_run_command() function which can be used to run a small subset of commands as required by the board (typically load and bootm), thus allowing the rest of the commands to be automatically and reliably dropped from the image using toolchain dead code elimination.
This is an interesting concept certainly. Can you also provide a non-trivial example here?
I have a very non-trivial example which is a lot of code, and calls things like the SPI layer and do_bootm(). That might be more than you want.
Would it help if I wrote a simple FDT-based boot to a kernel in a function?
Regards, Simon

On Mon, Mar 31, 2014 at 12:38:20PM -0600, Simon Glass wrote:
Hi Tom,
On 31 March 2014 12:30, Tom Rini trini@ti.com wrote:
On Mon, Mar 24, 2014 at 09:51:05AM -0600, Simon Glass wrote:
A large chunk of U-Boot's executable size is the code to process and execute commands. This is reasonable, since commands and scripts are an important part of U-Boot's feature set and provide much of its flexibility.
However, for some applications only a very limited set of commands is required. Where image size is important, it is desirable to be able to easily remove unwanted code.
This series introduces a new board_run_command() function which can be used to run a small subset of commands as required by the board (typically load and bootm), thus allowing the rest of the commands to be automatically and reliably dropped from the image using toolchain dead code elimination.
This is an interesting concept certainly. Can you also provide a non-trivial example here?
I have a very non-trivial example which is a lot of code, and calls things like the SPI layer and do_bootm(). That might be more than you want.
Would it help if I wrote a simple FDT-based boot to a kernel in a function?
How about both?

Hi Tom,
On 31 March 2014 12:59, Tom Rini trini@ti.com wrote:
On Mon, Mar 31, 2014 at 12:38:20PM -0600, Simon Glass wrote:
Hi Tom,
On 31 March 2014 12:30, Tom Rini trini@ti.com wrote:
On Mon, Mar 24, 2014 at 09:51:05AM -0600, Simon Glass wrote:
A large chunk of U-Boot's executable size is the code to process and execute commands. This is reasonable, since commands and scripts are an important part of U-Boot's feature set and provide much of its flexibility.
However, for some applications only a very limited set of commands is required. Where image size is important, it is desirable to be able
to
easily remove unwanted code.
This series introduces a new board_run_command() function which can be used to run a small subset of commands as required by the board (typically load and bootm), thus allowing the rest of the commands to be automatically and reliably dropped from the image using
toolchain
dead code elimination.
This is an interesting concept certainly. Can you also provide a non-trivial example here?
I have a very non-trivial example which is a lot of code, and calls
things
like the SPI layer and do_bootm(). That might be more than you want.
Would it help if I wrote a simple FDT-based boot to a kernel in a
function?
How about both?
For the first case, here is a commit that adds a function
https://chromium.googlesource.com/chromiumos/third_party/u-boot/+/b9e8864294...
For example, this code set up and boots a kernel:
https://chromium.googlesource.com/chromiumos/third_party/u-boot/+/b9e8864294...
and this code deals with checking for a second-stage read-write U-Boot to run:
https://chromium.googlesource.com/chromiumos/third_party/u-boot/+/b9e8864294...
Does that help?
For the second case, I can write something.
Regards, Simon
participants (2)
-
Simon Glass
-
Tom Rini