env: allow environment to be amended from control dtb

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. Or one can have several board variants that
can share almost all boot logic, but just needs a few tweaks in the
variables used by the boot script.

To that end, allow the control dtb to contain a /config/enviroment
node (or whatever one puts in fdt_env_path variable), whose
property/value pairs are used to update the run-time environment after
it has been loaded from its persistent location.

The indirection via fdt_env_path is for maximum flexibility - for
example, should the user wish (or board logic dictate) that the values
in the DTB should no longer be applied, one simply needs to delete the
fdt_env_path variable; that can even be done automatically by
including a

  fdt_env_path = "";

property in the DTB node.

Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
Acked-by: Joe Hershberger <joe.hershberger@ni.com>
This commit is contained in:
Rasmus Villemoes 2021-04-21 11:06:54 +02:00 committed by Tom Rini
parent 1cbfed8d3e
commit 95fd977201
5 changed files with 68 additions and 0 deletions

View File

@ -459,6 +459,8 @@ static int initr_env(void)
else
env_set_default(NULL, 0);
env_import_fdt();
if (IS_ENABLED(CONFIG_OF_CONTROL))
env_set_hex("fdtcontroladdr",
(unsigned long)map_to_sysmem(gd->fdt_blob));

18
env/Kconfig vendored
View File

@ -670,6 +670,24 @@ 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_IMPORT_FDT
bool "Amend environment by FDT properties"
depends on OF_CONTROL
help
If selected, after the environment has been loaded from its
persistent location, the "env_fdt_path" variable is looked
up and used as a path to a node in the control DTB. The
property/value pairs in that node is then used to update the
run-time environment. This can be useful to use the same
U-Boot binary with different board variants.
config ENV_FDT_PATH
string "Default value for env_fdt_path variable"
depends on ENV_IMPORT_FDT
default "/config/environment"
help
The initial value of the env_fdt_path variable.
config ENV_APPEND
bool "Always append the environment with new data"
default n

30
env/common.c vendored
View File

@ -20,6 +20,7 @@
#include <errno.h>
#include <malloc.h>
#include <u-boot/crc.h>
#include <dm/ofnode.h>
DECLARE_GLOBAL_DATA_PTR;
@ -334,3 +335,32 @@ int env_complete(char *var, int maxv, char *cmdv[], int bufsz, char *buf,
return found;
}
#endif
#ifdef CONFIG_ENV_IMPORT_FDT
void env_import_fdt(void)
{
const char *path;
struct ofprop prop;
ofnode node;
int res;
path = env_get("env_fdt_path");
if (!path || !path[0])
return;
node = ofnode_path(path);
if (!ofnode_valid(node)) {
printf("Warning: device tree node '%s' not found\n", path);
return;
}
for (res = ofnode_get_first_property(node, &prop);
!res;
res = ofnode_get_next_property(&prop)) {
const char *name, *val;
val = ofnode_get_property_by_prop(&prop, &name, NULL);
env_set(name, val);
}
}
#endif

View File

@ -375,4 +375,19 @@ int env_get_char(int index);
* This is used for those unfortunate archs with crappy toolchains
*/
void env_reloc(void);
/**
* env_import_fdt() - Import environment values from device tree blob
*
* This uses the value of the environment variable "env_fdt_path" as a
* path to an fdt node, whose property/value pairs are added to the
* environment.
*/
#ifdef CONFIG_ENV_IMPORT_FDT
void env_import_fdt(void);
#else
static inline void env_import_fdt(void) {}
#endif
#endif

View File

@ -103,6 +103,9 @@ const uchar default_environment[] = {
#ifdef CONFIG_SYS_SOC
"soc=" CONFIG_SYS_SOC "\0"
#endif
#ifdef CONFIG_ENV_IMPORT_FDT
"env_fdt_path=" CONFIG_ENV_FDT_PATH "\0"
#endif
#endif
#if defined(CONFIG_BOOTCOUNT_BOOTLIMIT) && (CONFIG_BOOTCOUNT_BOOTLIMIT > 0)
"bootlimit=" __stringify(CONFIG_BOOTCOUNT_BOOTLIMIT)"\0"