It can be useful to use the same U-Boot binary for multiple purposes, say the normal one, one for developers that allow breaking into the U-Boot shell, and one for use during bootstrapping which runs a special-purpose bootcmd. To that end, allow the control dtb to contain a /config/default-enviroment property, whose value will be used to amend the default environment baked into the U-Boot binary itself.
Signed-off-by: Rasmus Villemoes <rasmus.villem...@prevas.dk> --- cmd/nvedit.c | 37 +++++++++++++++++++++++++++++++++++++ env/Kconfig | 21 +++++++++++++++++++++ env/common.c | 19 +++++++++++++++++++ 3 files changed, 77 insertions(+) diff --git a/cmd/nvedit.c b/cmd/nvedit.c index 7fce723800..eda8b3b9d2 100644 --- a/cmd/nvedit.c +++ b/cmd/nvedit.c @@ -703,6 +703,39 @@ char *from_env(const char *envvar) return ret; } +static int env_get_f_fdt(const char *name, char *buf, unsigned len) +{ + const char *env; + int plen, nlen, n; + + if (!IS_ENABLED(CONFIG_ENV_AMEND_DEFAULT_FROM_FDT)) + return 0; + + env = fdtdec_get_config_property(gd->fdt_blob, "default-environment", + &plen); + if (!env) + return 0; + + nlen = strlen(name); + while (plen > nlen) { + if (memcmp(name, env, nlen) == 0 && env[nlen] == '=') { + /* Found. Copy value. */ + n = strlcpy(buf, &env[nlen + 1], len); + if (n < len) + return n; + + printf("env_buf [%u bytes] too small for value of \"%s\"\n", + len, name); + return len; + } + /* Skip this key=val pair. */ + n = strlen(env) + 1; + plen -= n; + env += n; + } + return 0; +} + /* * Look up variable from environment for restricted C runtime env. */ @@ -710,6 +743,10 @@ int env_get_f(const char *name, char *buf, unsigned len) { int i, nxt, c; + i = env_get_f_fdt(name, buf, len); + if (i) + return i; + for (i = 0; env_get_char(i) != '\0'; i = nxt + 1) { int val, n; diff --git a/env/Kconfig b/env/Kconfig index 67ce93061b..66bbac42c7 100644 --- a/env/Kconfig +++ b/env/Kconfig @@ -646,6 +646,27 @@ config DELAY_ENVIRONMENT later by U-Boot code. With CONFIG_OF_CONTROL this is instead controlled by the value of /config/load-environment. +config ENV_AMEND_DEFAULT_FROM_FDT + bool "Amend default environment by /config/default-environment property" + depends on OF_CONTROL + help + The default environment built into the U-Boot binary is a + static array defined from various CONFIG_ options, or via + CONFIG_DEFAULT_ENV_FILE. Selecting this option means that + whenever that default environment is used (either for + populating the initial environment, or for resetting + specific variables to their default value), the device tree + property /config/default-environment is also consulted, and + values found there have precedence over those in the static + array. That property should be a series of "key=value" + pairs, e.g. + + /config { + default-environment = "ipaddr=1.2.3.4", + "bootcmd=tftp $loadaddr foo.itb; bootm $loadaddr", + "bootdelay=5"; + } + config ENV_APPEND bool "Always append the environment with new data" default n diff --git a/env/common.c b/env/common.c index 7363da849b..8d0e45fde6 100644 --- a/env/common.c +++ b/env/common.c @@ -63,6 +63,22 @@ char *env_get_default(const char *name) return ret_val; } +static void env_amend_default_from_fdt(int flags, int nvars, char *const vars[]) +{ + const void *val; + int len; + + if (!IS_ENABLED(CONFIG_ENV_AMEND_DEFAULT_FROM_FDT)) + return; + + val = fdtdec_get_config_property(gd->fdt_blob, "default-environment", + &len); + if (!val) + return; + + himport_r(&env_htab, val, len, '\0', flags, 0, nvars, vars); +} + void env_set_default(const char *s, int flags) { if (sizeof(default_environment) > ENV_SIZE) { @@ -88,6 +104,8 @@ void env_set_default(const char *s, int flags) pr_err("## Error: Environment import failed: errno = %d\n", errno); + env_amend_default_from_fdt(flags | H_NOCLEAR, 0, NULL); + gd->flags |= GD_FLG_ENV_READY; gd->flags |= GD_FLG_ENV_DEFAULT; } @@ -104,6 +122,7 @@ void env_set_default_vars(int nvars, char * const vars[], int flags) himport_r(&env_htab, (const char *)default_environment, sizeof(default_environment), '\0', flags, 0, nvars, vars); + env_amend_default_from_fdt(flags, nvars, vars); } /* -- 2.23.0