diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/Kconfig.boot | 17 | ||||
-rw-r--r-- | common/bootm.c | 38 |
2 files changed, 52 insertions, 3 deletions
diff --git a/common/Kconfig.boot b/common/Kconfig.boot index 3f6d9c1a25..58e98548de 100644 --- a/common/Kconfig.boot +++ b/common/Kconfig.boot @@ -865,6 +865,23 @@ config BOOTARGS CONFIG_BOOTARGS goes into the environment value "bootargs". Note that this value will also override the "chosen" node in FDT blob. +config BOOTARGS_SUBST + bool "Support substituting strings in boot arguments" + help + This allows substituting string values in the boot arguments. These + are applied after the commandline has been built. + + One use for this is to insert the root-disk UUID into the command + line where bootargs contains "root=${uuid}" + + setenv bootargs "console= root=${uuid}" + # Set the 'uuid' environment variable + part uuid mmc 2:2 uuid + + # Command-line substitution will put the real uuid into the + # kernel command line + bootm + config USE_BOOTCOMMAND bool "Enable a default value for bootcmd" help diff --git a/common/bootm.c b/common/bootm.c index 020449db3f..8298693900 100644 --- a/common/bootm.c +++ b/common/bootm.c @@ -7,6 +7,7 @@ #ifndef USE_HOSTCC #include <common.h> #include <bootstage.h> +#include <cli.h> #include <cpu_func.h> #include <env.h> #include <errno.h> @@ -542,6 +543,33 @@ static int fixup_silent_linux(char *buf, int maxlen) return 0; } +/** + * process_subst() - Handle substitution of ${...} fields in the environment + * + * Handle variable substitution in the provided buffer + * + * @buf: Buffer containing the string to process + * @maxlen: Maximum length of buffer + * @return 0 if OK, -ENOSPC if @maxlen is too small + */ +static int process_subst(char *buf, int maxlen) +{ + char *cmdline; + int size; + int ret; + + /* Move to end of buffer */ + size = strlen(buf) + 1; + cmdline = buf + maxlen - size; + if (buf + size > cmdline) + return -ENOSPC; + memmove(cmdline, buf, size); + + ret = cli_simple_process_macros(cmdline, buf, cmdline - buf); + + return ret; +} + int bootm_process_cmdline(char *buf, int maxlen, int flags) { int ret; @@ -554,6 +582,11 @@ int bootm_process_cmdline(char *buf, int maxlen, int flags) if (ret) return log_msg_ret("silent", ret); } + if (IS_ENABLED(CONFIG_BOOTARGS_SUBST) && (flags & BOOTM_CL_SUBST)) { + ret = process_subst(buf, maxlen); + if (ret) + return log_msg_ret("silent", ret); + } return 0; } @@ -569,7 +602,7 @@ int bootm_process_cmdline_env(int flags) /* First check if any action is needed */ do_silent = IS_ENABLED(CONFIG_SILENT_CONSOLE) && !IS_ENABLED(CONFIG_SILENT_U_BOOT_ONLY) && (flags & BOOTM_CL_SILENT); - if (!do_silent) + if (!do_silent && !IS_ENABLED(CONFIG_BOOTARGS_SUBST)) return 0; env = env_get("bootargs"); @@ -702,8 +735,7 @@ int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int argc, if (!ret && (states & BOOTM_STATE_OS_BD_T)) ret = boot_fn(BOOTM_STATE_OS_BD_T, argc, argv, images); if (!ret && (states & BOOTM_STATE_OS_PREP)) { - ret = bootm_process_cmdline_env(images->os.os == IH_OS_LINUX ? - BOOTM_CL_SILENT : 0); + ret = bootm_process_cmdline_env(images->os.os == IH_OS_LINUX); if (ret) { printf("Cmdline setup failed (err=%d)\n", ret); ret = CMD_RET_FAILURE; |