mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2025-09-19 21:01:51 +02:00
Merge branch '2022-04-08-env-updates'
- Assorted env tooling updates - Bug fix around multiple possible env locations and ENV_IS_NOWHERE - Add 'indirect' sub-command to env - Allow for FAT env to have the location overridden by the board code.
This commit is contained in:
commit
03a8a797e5
3
Makefile
3
Makefile
@ -2459,7 +2459,8 @@ endif
|
|||||||
|
|
||||||
quiet_cmd_genenv = GENENV $@
|
quiet_cmd_genenv = GENENV $@
|
||||||
cmd_genenv = $(OBJCOPY) --dump-section .rodata.default_environment=$@ env/common.o; \
|
cmd_genenv = $(OBJCOPY) --dump-section .rodata.default_environment=$@ env/common.o; \
|
||||||
sed --in-place -e 's/\x00/\x0A/g' $@
|
sed --in-place -e 's/\x00/\x0A/g' $@; sed --in-place -e '/^\s*$$/d' $@; \
|
||||||
|
sort --field-separator== -k1,1 --stable $@ -o $@
|
||||||
|
|
||||||
u-boot-initial-env: u-boot.bin
|
u-boot-initial-env: u-boot.bin
|
||||||
$(call if_changed,genenv)
|
$(call if_changed,genenv)
|
||||||
|
@ -518,6 +518,9 @@ config CMD_NVEDIT_EFI
|
|||||||
If enabled, we are allowed to set/print UEFI variables using
|
If enabled, we are allowed to set/print UEFI variables using
|
||||||
"env" command with "-e" option without knowing details.
|
"env" command with "-e" option without knowing details.
|
||||||
|
|
||||||
|
config CMD_NVEDIT_INDIRECT
|
||||||
|
bool "env indirect - Sets environment value from another"
|
||||||
|
|
||||||
config CMD_NVEDIT_INFO
|
config CMD_NVEDIT_INFO
|
||||||
bool "env info - print or evaluate environment information"
|
bool "env info - print or evaluate environment information"
|
||||||
help
|
help
|
||||||
|
45
cmd/nvedit.c
45
cmd/nvedit.c
@ -1018,6 +1018,45 @@ sep_err:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_CMD_NVEDIT_INDIRECT)
|
||||||
|
static int do_env_indirect(struct cmd_tbl *cmdtp, int flag,
|
||||||
|
int argc, char *const argv[])
|
||||||
|
{
|
||||||
|
char *to = argv[1];
|
||||||
|
char *from = argv[2];
|
||||||
|
char *default_value = NULL;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (argc < 3 || argc > 4) {
|
||||||
|
return CMD_RET_USAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc == 4) {
|
||||||
|
default_value = argv[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (env_get(from) == NULL && default_value == NULL) {
|
||||||
|
printf("## env indirect: Environment variable for <from> (%s) does not exist.\n", from);
|
||||||
|
|
||||||
|
return CMD_RET_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (env_get(from) == NULL) {
|
||||||
|
ret = env_set(to, default_value);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret = env_set(to, env_get(from));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == 0) {
|
||||||
|
return CMD_RET_SUCCESS;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return CMD_RET_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_CMD_NVEDIT_INFO)
|
#if defined(CONFIG_CMD_NVEDIT_INFO)
|
||||||
/*
|
/*
|
||||||
* print_env_info - print environment information
|
* print_env_info - print environment information
|
||||||
@ -1181,6 +1220,9 @@ static struct cmd_tbl cmd_env_sub[] = {
|
|||||||
#if defined(CONFIG_CMD_IMPORTENV)
|
#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
|
#endif
|
||||||
|
#if defined(CONFIG_CMD_NVEDIT_INDIRECT)
|
||||||
|
U_BOOT_CMD_MKENT(indirect, 3, 0, do_env_indirect, "", ""),
|
||||||
|
#endif
|
||||||
#if defined(CONFIG_CMD_NVEDIT_INFO)
|
#if defined(CONFIG_CMD_NVEDIT_INFO)
|
||||||
U_BOOT_CMD_MKENT(info, 3, 0, do_env_info, "", ""),
|
U_BOOT_CMD_MKENT(info, 3, 0, do_env_info, "", ""),
|
||||||
#endif
|
#endif
|
||||||
@ -1265,6 +1307,9 @@ static char env_help_text[] =
|
|||||||
#if defined(CONFIG_CMD_IMPORTENV)
|
#if defined(CONFIG_CMD_IMPORTENV)
|
||||||
"env import [-d] [-t [-r] | -b | -c] addr [size] [var ...] - import environment\n"
|
"env import [-d] [-t [-r] | -b | -c] addr [size] [var ...] - import environment\n"
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(CONFIG_CMD_NVEDIT_INDIRECT)
|
||||||
|
"env indirect <to> <from> [default] - sets <to> to the value of <from>, using [default] when unset\n"
|
||||||
|
#endif
|
||||||
#if defined(CONFIG_CMD_NVEDIT_INFO)
|
#if defined(CONFIG_CMD_NVEDIT_INFO)
|
||||||
"env info - display environment information\n"
|
"env info - display environment information\n"
|
||||||
"env info [-d] [-p] [-q] - evaluate environment information\n"
|
"env info [-d] [-p] [-q] - evaluate environment information\n"
|
||||||
|
@ -446,6 +446,11 @@ const char *bootdelay_process(void)
|
|||||||
s = env_get("bootdelay");
|
s = env_get("bootdelay");
|
||||||
bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;
|
bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Does it really make sense that the devicetree overrides the user
|
||||||
|
* setting? It is possibly helpful for security since the device tree
|
||||||
|
* may be signed whereas the environment is often loaded from storage.
|
||||||
|
*/
|
||||||
if (IS_ENABLED(CONFIG_OF_CONTROL))
|
if (IS_ENABLED(CONFIG_OF_CONTROL))
|
||||||
bootdelay = ofnode_conf_read_int("bootdelay", bootdelay);
|
bootdelay = ofnode_conf_read_int("bootdelay", bootdelay);
|
||||||
|
|
||||||
|
@ -120,7 +120,6 @@ bootdelay
|
|||||||
The default value is defined by CONFIG_BOOTDELAY.
|
The default value is defined by CONFIG_BOOTDELAY.
|
||||||
The value of 'bootdelay' is overridden by the /config/bootdelay value in
|
The value of 'bootdelay' is overridden by the /config/bootdelay value in
|
||||||
the device-tree if CONFIG_OF_CONTROL=y.
|
the device-tree if CONFIG_OF_CONTROL=y.
|
||||||
Does it really make sense that the devicetree overrides the user setting?
|
|
||||||
|
|
||||||
bootcmd
|
bootcmd
|
||||||
The command that is run if the user does not enter the shell during the
|
The command that is run if the user does not enter the shell during the
|
||||||
@ -171,7 +170,7 @@ autoload
|
|||||||
if set to "no" (any string beginning with 'n'),
|
if set to "no" (any string beginning with 'n'),
|
||||||
"bootp" and "dhcp" will just load perform a lookup of the
|
"bootp" and "dhcp" will just load perform a lookup of the
|
||||||
configuration from the BOOTP server, but not try to
|
configuration from the BOOTP server, but not try to
|
||||||
load any image using TFTP or DHCP.
|
load any image.
|
||||||
|
|
||||||
autostart
|
autostart
|
||||||
if set to "yes", an image loaded using the "bootp", "dhcp",
|
if set to "yes", an image loaded using the "bootp", "dhcp",
|
||||||
|
13
env/env.c
vendored
13
env/env.c
vendored
@ -322,17 +322,18 @@ int env_init(void)
|
|||||||
|
|
||||||
debug("%s: Environment %s init done (ret=%d)\n", __func__,
|
debug("%s: Environment %s init done (ret=%d)\n", __func__,
|
||||||
drv->name, ret);
|
drv->name, ret);
|
||||||
|
|
||||||
if (gd->env_valid == ENV_INVALID)
|
|
||||||
ret = -ENOENT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!prio)
|
if (!prio) {
|
||||||
return -ENODEV;
|
gd->env_addr = (ulong)&default_environment[0];
|
||||||
|
gd->env_valid = ENV_INVALID;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (ret == -ENOENT) {
|
if (ret == -ENOENT) {
|
||||||
gd->env_addr = (ulong)&default_environment[0];
|
gd->env_addr = (ulong)&default_environment[0];
|
||||||
gd->env_valid = ENV_VALID;
|
gd->env_valid = ENV_INVALID;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
30
env/fat.c
vendored
30
env/fat.c
vendored
@ -32,7 +32,12 @@
|
|||||||
|
|
||||||
DECLARE_GLOBAL_DATA_PTR;
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
static char *env_fat_device_and_part(void)
|
__weak const char *env_fat_get_intf(void)
|
||||||
|
{
|
||||||
|
return (const char *)CONFIG_ENV_FAT_INTERFACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
__weak char *env_fat_get_dev_part(void)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_MMC
|
#ifdef CONFIG_MMC
|
||||||
static char *part_str;
|
static char *part_str;
|
||||||
@ -60,13 +65,14 @@ static int env_fat_save(void)
|
|||||||
int dev, part;
|
int dev, part;
|
||||||
int err;
|
int err;
|
||||||
loff_t size;
|
loff_t size;
|
||||||
|
const char *ifname = env_fat_get_intf();
|
||||||
|
const char *dev_and_part = env_fat_get_dev_part();
|
||||||
|
|
||||||
err = env_export(&env_new);
|
err = env_export(&env_new);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
part = blk_get_device_part_str(CONFIG_ENV_FAT_INTERFACE,
|
part = blk_get_device_part_str(ifname, dev_and_part,
|
||||||
env_fat_device_and_part(),
|
|
||||||
&dev_desc, &info, 1);
|
&dev_desc, &info, 1);
|
||||||
if (part < 0)
|
if (part < 0)
|
||||||
return 1;
|
return 1;
|
||||||
@ -77,8 +83,7 @@ static int env_fat_save(void)
|
|||||||
* This printf is embedded in the messages from env_save that
|
* This printf is embedded in the messages from env_save that
|
||||||
* will calling it. The missing \n is intentional.
|
* will calling it. The missing \n is intentional.
|
||||||
*/
|
*/
|
||||||
printf("Unable to use %s %d:%d... \n",
|
printf("Unable to use %s %d:%d...\n", ifname, dev, part);
|
||||||
CONFIG_ENV_FAT_INTERFACE, dev, part);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,8 +98,7 @@ static int env_fat_save(void)
|
|||||||
* This printf is embedded in the messages from env_save that
|
* This printf is embedded in the messages from env_save that
|
||||||
* will calling it. The missing \n is intentional.
|
* will calling it. The missing \n is intentional.
|
||||||
*/
|
*/
|
||||||
printf("Unable to write \"%s\" from %s%d:%d... \n",
|
printf("Unable to write \"%s\" from %s%d:%d...\n", file, ifname, dev, part);
|
||||||
file, CONFIG_ENV_FAT_INTERFACE, dev, part);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,14 +121,15 @@ static int env_fat_load(void)
|
|||||||
struct disk_partition info;
|
struct disk_partition info;
|
||||||
int dev, part;
|
int dev, part;
|
||||||
int err1;
|
int err1;
|
||||||
|
const char *ifname = env_fat_get_intf();
|
||||||
|
const char *dev_and_part = env_fat_get_dev_part();
|
||||||
|
|
||||||
#ifdef CONFIG_MMC
|
#ifdef CONFIG_MMC
|
||||||
if (!strcmp(CONFIG_ENV_FAT_INTERFACE, "mmc"))
|
if (!strcmp(ifname, "mmc"))
|
||||||
mmc_initialize(NULL);
|
mmc_initialize(NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
part = blk_get_device_part_str(CONFIG_ENV_FAT_INTERFACE,
|
part = blk_get_device_part_str(ifname, dev_and_part,
|
||||||
env_fat_device_and_part(),
|
|
||||||
&dev_desc, &info, 1);
|
&dev_desc, &info, 1);
|
||||||
if (part < 0)
|
if (part < 0)
|
||||||
goto err_env_relocate;
|
goto err_env_relocate;
|
||||||
@ -135,8 +140,7 @@ static int env_fat_load(void)
|
|||||||
* This printf is embedded in the messages from env_save that
|
* This printf is embedded in the messages from env_save that
|
||||||
* will calling it. The missing \n is intentional.
|
* will calling it. The missing \n is intentional.
|
||||||
*/
|
*/
|
||||||
printf("Unable to use %s %d:%d... \n",
|
printf("Unable to use %s %d:%d...\n", ifname, dev, part);
|
||||||
CONFIG_ENV_FAT_INTERFACE, dev, part);
|
|
||||||
goto err_env_relocate;
|
goto err_env_relocate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,7 +158,7 @@ static int env_fat_load(void)
|
|||||||
* will calling it. The missing \n is intentional.
|
* will calling it. The missing \n is intentional.
|
||||||
*/
|
*/
|
||||||
printf("Unable to read \"%s\" from %s%d:%d... \n",
|
printf("Unable to read \"%s\" from %s%d:%d... \n",
|
||||||
CONFIG_ENV_FAT_FILE, CONFIG_ENV_FAT_INTERFACE, dev, part);
|
CONFIG_ENV_FAT_FILE, ifname, dev, part);
|
||||||
goto err_env_relocate;
|
goto err_env_relocate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,6 +245,26 @@ const char *env_ext4_get_dev_part(void);
|
|||||||
* Return: an enum env_location value on success, or -ve error code.
|
* Return: an enum env_location value on success, or -ve error code.
|
||||||
*/
|
*/
|
||||||
enum env_location env_get_location(enum env_operation op, int prio);
|
enum env_location env_get_location(enum env_operation op, int prio);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* env_fat_get_intf() - Provide the interface for env in FAT
|
||||||
|
*
|
||||||
|
* It is a weak function allowing board to overidde the default interface for
|
||||||
|
* U-Boot env in FAT: CONFIG_ENV_FAT_INTERFACE
|
||||||
|
*
|
||||||
|
* Return: string of interface, empty if not supported
|
||||||
|
*/
|
||||||
|
const char *env_fat_get_intf(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* env_fat_get_dev_part() - Provide the device and partition for env in FAT
|
||||||
|
*
|
||||||
|
* It is a weak function allowing board to overidde the default device and
|
||||||
|
* partition used for U-Boot env in FAT: CONFIG_ENV_FAT_DEVICE_AND_PART
|
||||||
|
*
|
||||||
|
* Return: string of device and partition
|
||||||
|
*/
|
||||||
|
char *env_fat_get_dev_part(void);
|
||||||
#endif /* DO_DEPS_ONLY */
|
#endif /* DO_DEPS_ONLY */
|
||||||
|
|
||||||
#endif /* _ENV_INTERNAL_H_ */
|
#endif /* _ENV_INTERNAL_H_ */
|
||||||
|
@ -81,7 +81,10 @@ END {
|
|||||||
if (do_output) {
|
if (do_output) {
|
||||||
printf("%s", "#define CONFIG_EXTRA_ENV_TEXT \"")
|
printf("%s", "#define CONFIG_EXTRA_ENV_TEXT \"")
|
||||||
|
|
||||||
# Print out all the variables
|
# Print out all the variables by alphabetic order, if using
|
||||||
|
# gawk. This allows test_env_test.py to work on both awk (where
|
||||||
|
# this next line does nothing)
|
||||||
|
PROCINFO["sorted_in"] = "@ind_str_asc"
|
||||||
for (var in vars) {
|
for (var in vars) {
|
||||||
env = vars[var]
|
env = vars[var]
|
||||||
print var "=" vars[var] "\\0"
|
print var "=" vars[var] "\\0"
|
||||||
|
@ -35,8 +35,8 @@ cp ${env_obj_file_path} ${ENV_OBJ_FILE_COPY}
|
|||||||
${OBJCOPY} --dump-section .rodata.default_environment=${ENV_OBJ_FILE_COPY} \
|
${OBJCOPY} --dump-section .rodata.default_environment=${ENV_OBJ_FILE_COPY} \
|
||||||
${env_obj_file_path}
|
${env_obj_file_path}
|
||||||
|
|
||||||
# Replace default '\0' with '\n' and sort entries
|
# Replace default '\0' with '\n' , remove blank lines and sort entries
|
||||||
tr '\0' '\n' < ${ENV_OBJ_FILE_COPY} | sort --field-separator== -k1,1 --stable
|
tr '\0' '\n' < ${ENV_OBJ_FILE_COPY} | sed -e '/^\s*$/d' | sort --field-separator== -k1,1 --stable
|
||||||
|
|
||||||
rm ${ENV_OBJ_FILE_COPY}
|
rm ${ENV_OBJ_FILE_COPY}
|
||||||
|
|
||||||
|
@ -554,42 +554,42 @@ def test_env_text(u_boot_console):
|
|||||||
|
|
||||||
# two vars
|
# two vars
|
||||||
check_script('''fred=123
|
check_script('''fred=123
|
||||||
ernie=456''', 'fred=123\\0ernie=456\\0')
|
mary=456''', 'fred=123\\0mary=456\\0')
|
||||||
|
|
||||||
# blank lines
|
# blank lines
|
||||||
check_script('''fred=123
|
check_script('''fred=123
|
||||||
|
|
||||||
|
|
||||||
ernie=456
|
mary=456
|
||||||
|
|
||||||
''', 'fred=123\\0ernie=456\\0')
|
''', 'fred=123\\0mary=456\\0')
|
||||||
|
|
||||||
# append
|
# append
|
||||||
check_script('''fred=123
|
check_script('''fred=123
|
||||||
ernie=456
|
mary=456
|
||||||
fred+= 456''', 'fred=123 456\\0ernie=456\\0')
|
fred+= 456''', 'fred=123 456\\0mary=456\\0')
|
||||||
|
|
||||||
# append from empty
|
# append from empty
|
||||||
check_script('''fred=
|
check_script('''fred=
|
||||||
ernie=456
|
mary=456
|
||||||
fred+= 456''', 'fred= 456\\0ernie=456\\0')
|
fred+= 456''', 'fred= 456\\0mary=456\\0')
|
||||||
|
|
||||||
# variable with + in it
|
# variable with + in it
|
||||||
check_script('fred+ernie=123', 'fred+ernie=123\\0')
|
check_script('fred+mary=123', 'fred+mary=123\\0')
|
||||||
|
|
||||||
# ignores variables that are empty
|
# ignores variables that are empty
|
||||||
check_script('''fred=
|
check_script('''fred=
|
||||||
fred+=
|
fred+=
|
||||||
ernie=456''', 'ernie=456\\0')
|
mary=456''', 'mary=456\\0')
|
||||||
|
|
||||||
# single-character env name
|
# single-character env name
|
||||||
check_script('''f=123
|
check_script('''m=123
|
||||||
e=456
|
e=456
|
||||||
f+= 456''', 'e=456\\0f=123 456\\0')
|
m+= 456''', 'e=456\\0m=123 456\\0')
|
||||||
|
|
||||||
# contains quotes
|
# contains quotes
|
||||||
check_script('''fred="my var"
|
check_script('''fred="my var"
|
||||||
ernie=another"''', 'fred=\\"my var\\"\\0ernie=another\\"\\0')
|
mary=another"''', 'fred=\\"my var\\"\\0mary=another\\"\\0')
|
||||||
|
|
||||||
# variable name ending in +
|
# variable name ending in +
|
||||||
check_script('''fred\\+=my var
|
check_script('''fred\\+=my var
|
||||||
@ -598,7 +598,7 @@ fred++= again''', 'fred+=my var again\\0')
|
|||||||
# variable name containing +
|
# variable name containing +
|
||||||
check_script('''fred+jane=both
|
check_script('''fred+jane=both
|
||||||
fred+jane+=again
|
fred+jane+=again
|
||||||
ernie=456''', 'fred+jane=bothagain\\0ernie=456\\0')
|
mary=456''', 'fred+jane=bothagain\\0mary=456\\0')
|
||||||
|
|
||||||
# multi-line vars - new vars always start at column 1
|
# multi-line vars - new vars always start at column 1
|
||||||
check_script('''fred=first
|
check_script('''fred=first
|
||||||
@ -607,7 +607,7 @@ ernie=456''', 'fred+jane=bothagain\\0ernie=456\\0')
|
|||||||
|
|
||||||
after blank
|
after blank
|
||||||
confusing=oops
|
confusing=oops
|
||||||
ernie=another"''', 'fred=first second third with tab after blank confusing=oops\\0ernie=another\\"\\0')
|
mary=another"''', 'fred=first second third with tab after blank confusing=oops\\0mary=another\\"\\0')
|
||||||
|
|
||||||
# real-world example
|
# real-world example
|
||||||
check_script('''ubifs_boot=
|
check_script('''ubifs_boot=
|
||||||
|
Loading…
x
Reference in New Issue
Block a user