mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-18 13:11:31 +00:00
Merge branch '2020-07-31-more-env-updates'
- Fix EFI selftest to not force setting serial# environment (and also get the U-Boot prompt dynamically). - Support for append only environment and other related features. - Improved ext4 environment support - Fix the case of fw_setenv being used on flash devices that were not already locked.
This commit is contained in:
commit
a2d051e7b6
33 changed files with 507 additions and 65 deletions
|
@ -7,6 +7,7 @@
|
|||
#include <cpu_func.h>
|
||||
#include <cros_ec.h>
|
||||
#include <dm.h>
|
||||
#include <env_internal.h>
|
||||
#include <init.h>
|
||||
#include <led.h>
|
||||
#include <os.h>
|
||||
|
@ -44,6 +45,20 @@ unsigned long timer_read_counter(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* specific order for sandbox: nowhere is the first value, used by default */
|
||||
static enum env_location env_locations[] = {
|
||||
ENVL_NOWHERE,
|
||||
ENVL_EXT4,
|
||||
};
|
||||
|
||||
enum env_location env_get_location(enum env_operation op, int prio)
|
||||
{
|
||||
if (prio >= ARRAY_SIZE(env_locations))
|
||||
return ENVL_UNKNOWN;
|
||||
|
||||
return env_locations[prio];
|
||||
}
|
||||
|
||||
int dram_init(void)
|
||||
{
|
||||
gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
|
||||
|
|
11
cmd/Kconfig
11
cmd/Kconfig
|
@ -604,6 +604,17 @@ config CMD_NVEDIT_INFO
|
|||
[-q] : quiet output
|
||||
The result of multiple evaluations will be combined with AND.
|
||||
|
||||
config CMD_NVEDIT_LOAD
|
||||
bool "env load"
|
||||
help
|
||||
Load all environment variables from the compiled-in persistent
|
||||
storage.
|
||||
|
||||
config CMD_NVEDIT_SELECT
|
||||
bool "env select"
|
||||
help
|
||||
Select the compiled-in persistent storage of environment variables.
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Memory commands"
|
||||
|
|
29
cmd/nvedit.c
29
cmd/nvedit.c
|
@ -794,6 +794,23 @@ U_BOOT_CMD(
|
|||
);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_CMD_NVEDIT_LOAD)
|
||||
static int do_env_load(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
char *const argv[])
|
||||
{
|
||||
return env_reload() ? 1 : 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_CMD_NVEDIT_SELECT)
|
||||
static int do_env_select(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
char *const argv[])
|
||||
{
|
||||
return env_select(argv[1]) ? 1 : 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_SPL_BUILD */
|
||||
|
||||
int env_match(uchar *s1, int i2)
|
||||
|
@ -1346,6 +1363,9 @@ static struct cmd_tbl cmd_env_sub[] = {
|
|||
#endif
|
||||
#if defined(CONFIG_CMD_NVEDIT_INFO)
|
||||
U_BOOT_CMD_MKENT(info, 3, 0, do_env_info, "", ""),
|
||||
#endif
|
||||
#if defined(CONFIG_CMD_NVEDIT_LOAD)
|
||||
U_BOOT_CMD_MKENT(load, 1, 0, do_env_load, "", ""),
|
||||
#endif
|
||||
U_BOOT_CMD_MKENT(print, CONFIG_SYS_MAXARGS, 1, do_env_print, "", ""),
|
||||
#if defined(CONFIG_CMD_RUN)
|
||||
|
@ -1356,6 +1376,9 @@ static struct cmd_tbl cmd_env_sub[] = {
|
|||
#if defined(CONFIG_CMD_ERASEENV)
|
||||
U_BOOT_CMD_MKENT(erase, 1, 0, do_env_erase, "", ""),
|
||||
#endif
|
||||
#endif
|
||||
#if defined(CONFIG_CMD_NVEDIT_SELECT)
|
||||
U_BOOT_CMD_MKENT(select, 2, 0, do_env_select, "", ""),
|
||||
#endif
|
||||
U_BOOT_CMD_MKENT(set, CONFIG_SYS_MAXARGS, 0, do_env_set, "", ""),
|
||||
#if defined(CONFIG_CMD_ENV_EXISTS)
|
||||
|
@ -1442,6 +1465,12 @@ static char env_help_text[] =
|
|||
"env erase - erase environment\n"
|
||||
#endif
|
||||
#endif
|
||||
#if defined(CONFIG_CMD_NVEDIT_LOAD)
|
||||
"env load - load environment\n"
|
||||
#endif
|
||||
#if defined(CONFIG_CMD_NVEDIT_SELECT)
|
||||
"env select [target] - select environment target\n"
|
||||
#endif
|
||||
#if defined(CONFIG_CMD_NVEDIT_EFI)
|
||||
"env set -e [-nv][-bs][-rt][-at][-a][-i addr,size][-v] name [arg ...]\n"
|
||||
" - set UEFI variable; unset if '-i' or 'arg' not specified\n"
|
||||
|
|
|
@ -27,10 +27,13 @@ CONFIG_CMD_BOOTEFI_HELLO=y
|
|||
# CONFIG_CMD_ELF is not set
|
||||
CONFIG_CMD_ASKENV=y
|
||||
CONFIG_CMD_GREPENV=y
|
||||
CONFIG_CMD_ERASEENV=y
|
||||
CONFIG_CMD_ENV_CALLBACK=y
|
||||
CONFIG_CMD_ENV_FLAGS=y
|
||||
CONFIG_CMD_NVEDIT_EFI=y
|
||||
CONFIG_CMD_NVEDIT_INFO=y
|
||||
CONFIG_CMD_NVEDIT_LOAD=y
|
||||
CONFIG_CMD_NVEDIT_SELECT=y
|
||||
CONFIG_LOOPW=y
|
||||
CONFIG_CMD_MD5SUM=y
|
||||
CONFIG_CMD_MEMINFO=y
|
||||
|
@ -83,6 +86,10 @@ CONFIG_OF_CONTROL=y
|
|||
CONFIG_OF_LIVE=y
|
||||
CONFIG_OF_HOSTFILE=y
|
||||
CONFIG_BOOTP_SEND_HOSTNAME=y
|
||||
CONFIG_ENV_IS_NOWHERE=y
|
||||
CONFIG_ENV_IS_IN_EXT4=y
|
||||
CONFIG_ENV_EXT4_INTERFACE="host"
|
||||
CONFIG_ENV_EXT4_DEVICE_AND_PART="0:0"
|
||||
CONFIG_NETCONSOLE=y
|
||||
CONFIG_IP_DEFRAG=y
|
||||
CONFIG_REGMAP=y
|
||||
|
|
|
@ -32,10 +32,13 @@ CONFIG_CMD_ABOOTIMG=y
|
|||
# CONFIG_CMD_ELF is not set
|
||||
CONFIG_CMD_ASKENV=y
|
||||
CONFIG_CMD_GREPENV=y
|
||||
CONFIG_CMD_ERASEENV=y
|
||||
CONFIG_CMD_ENV_CALLBACK=y
|
||||
CONFIG_CMD_ENV_FLAGS=y
|
||||
CONFIG_CMD_NVEDIT_EFI=y
|
||||
CONFIG_CMD_NVEDIT_INFO=y
|
||||
CONFIG_CMD_NVEDIT_LOAD=y
|
||||
CONFIG_CMD_NVEDIT_SELECT=y
|
||||
CONFIG_LOOPW=y
|
||||
CONFIG_CMD_MD5SUM=y
|
||||
CONFIG_CMD_MEMINFO=y
|
||||
|
@ -94,6 +97,10 @@ CONFIG_OF_CONTROL=y
|
|||
CONFIG_OF_LIVE=y
|
||||
CONFIG_OF_HOSTFILE=y
|
||||
CONFIG_BOOTP_SEND_HOSTNAME=y
|
||||
CONFIG_ENV_IS_NOWHERE=y
|
||||
CONFIG_ENV_IS_IN_EXT4=y
|
||||
CONFIG_ENV_EXT4_INTERFACE="host"
|
||||
CONFIG_ENV_EXT4_DEVICE_AND_PART="0:0"
|
||||
CONFIG_NETCONSOLE=y
|
||||
CONFIG_IP_DEFRAG=y
|
||||
CONFIG_REGMAP=y
|
||||
|
|
|
@ -24,7 +24,10 @@ CONFIG_CMD_BOOTEFI_HELLO=y
|
|||
# CONFIG_CMD_ELF is not set
|
||||
CONFIG_CMD_ASKENV=y
|
||||
CONFIG_CMD_GREPENV=y
|
||||
CONFIG_CMD_ERASEENV=y
|
||||
CONFIG_CMD_NVEDIT_INFO=y
|
||||
CONFIG_CMD_NVEDIT_LOAD=y
|
||||
CONFIG_CMD_NVEDIT_SELECT=y
|
||||
CONFIG_LOOPW=y
|
||||
CONFIG_CMD_MD5SUM=y
|
||||
CONFIG_CMD_MEMINFO=y
|
||||
|
@ -66,6 +69,10 @@ CONFIG_AMIGA_PARTITION=y
|
|||
CONFIG_OF_CONTROL=y
|
||||
CONFIG_OF_HOSTFILE=y
|
||||
CONFIG_BOOTP_SEND_HOSTNAME=y
|
||||
CONFIG_ENV_IS_NOWHERE=y
|
||||
CONFIG_ENV_IS_IN_EXT4=y
|
||||
CONFIG_ENV_EXT4_INTERFACE="host"
|
||||
CONFIG_ENV_EXT4_DEVICE_AND_PART="0:0"
|
||||
CONFIG_NETCONSOLE=y
|
||||
CONFIG_IP_DEFRAG=y
|
||||
CONFIG_REGMAP=y
|
||||
|
|
|
@ -34,9 +34,12 @@ CONFIG_CMD_BOOTEFI_HELLO=y
|
|||
# CONFIG_CMD_ELF is not set
|
||||
CONFIG_CMD_ASKENV=y
|
||||
CONFIG_CMD_GREPENV=y
|
||||
CONFIG_CMD_ERASEENV=y
|
||||
CONFIG_CMD_ENV_CALLBACK=y
|
||||
CONFIG_CMD_ENV_FLAGS=y
|
||||
CONFIG_CMD_NVEDIT_INFO=y
|
||||
CONFIG_CMD_NVEDIT_LOAD=y
|
||||
CONFIG_CMD_NVEDIT_SELECT=y
|
||||
CONFIG_LOOPW=y
|
||||
CONFIG_CMD_MD5SUM=y
|
||||
CONFIG_CMD_MEMINFO=y
|
||||
|
@ -83,6 +86,10 @@ CONFIG_SPL_OF_CONTROL=y
|
|||
CONFIG_OF_HOSTFILE=y
|
||||
CONFIG_SPL_OF_PLATDATA=y
|
||||
CONFIG_BOOTP_SEND_HOSTNAME=y
|
||||
CONFIG_ENV_IS_NOWHERE=y
|
||||
CONFIG_ENV_IS_IN_EXT4=y
|
||||
CONFIG_ENV_EXT4_INTERFACE="host"
|
||||
CONFIG_ENV_EXT4_DEVICE_AND_PART="0:0"
|
||||
CONFIG_NETCONSOLE=y
|
||||
CONFIG_IP_DEFRAG=y
|
||||
CONFIG_SPL_DM=y
|
||||
|
|
19
env/Kconfig
vendored
19
env/Kconfig
vendored
|
@ -479,7 +479,7 @@ config ENV_EXT4_DEVICE_AND_PART
|
|||
config ENV_EXT4_FILE
|
||||
string "Name of the EXT4 file to use for the environment"
|
||||
depends on ENV_IS_IN_EXT4
|
||||
default "uboot.env"
|
||||
default "/uboot.env"
|
||||
help
|
||||
It's a string of the EXT4 file name. This file use to store the
|
||||
environment (explicit path to the file)
|
||||
|
@ -614,6 +614,23 @@ 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_APPEND
|
||||
bool "Always append the environment with new data"
|
||||
default n
|
||||
help
|
||||
If defined, the environment hash table is only ever appended with new
|
||||
data, but the existing hash table can never be dropped and reloaded
|
||||
with newly imported data. This may be used in combination with static
|
||||
flags to e.g. to protect variables which must not be modified.
|
||||
|
||||
config ENV_WRITEABLE_LIST
|
||||
bool "Permit write access only to listed variables"
|
||||
default n
|
||||
help
|
||||
If defined, only environment variables which explicitly set the 'w'
|
||||
writeable flag can be written and modified at runtime. No variables
|
||||
can be otherwise created, written or imported into the environment.
|
||||
|
||||
config ENV_ACCESS_IGNORE_FORCE
|
||||
bool "Block forced environment operations"
|
||||
default n
|
||||
|
|
16
env/common.c
vendored
16
env/common.c
vendored
|
@ -81,6 +81,7 @@ void env_set_default(const char *s, int flags)
|
|||
debug("Using default environment\n");
|
||||
}
|
||||
|
||||
flags |= H_DEFAULT;
|
||||
if (himport_r(&env_htab, (char *)default_environment,
|
||||
sizeof(default_environment), '\0', flags, 0,
|
||||
0, NULL) == 0)
|
||||
|
@ -99,7 +100,7 @@ int env_set_default_vars(int nvars, char * const vars[], int flags)
|
|||
* Special use-case: import from default environment
|
||||
* (and use \0 as a separator)
|
||||
*/
|
||||
flags |= H_NOCLEAR;
|
||||
flags |= H_NOCLEAR | H_DEFAULT;
|
||||
return himport_r(&env_htab, (const char *)default_environment,
|
||||
sizeof(default_environment), '\0',
|
||||
flags, 0, nvars, vars);
|
||||
|
@ -109,7 +110,7 @@ int env_set_default_vars(int nvars, char * const vars[], int flags)
|
|||
* Check if CRC is valid and (if yes) import the environment.
|
||||
* Note that "buf" may or may not be aligned.
|
||||
*/
|
||||
int env_import(const char *buf, int check)
|
||||
int env_import(const char *buf, int check, int flags)
|
||||
{
|
||||
env_t *ep = (env_t *)buf;
|
||||
|
||||
|
@ -124,7 +125,7 @@ int env_import(const char *buf, int check)
|
|||
}
|
||||
}
|
||||
|
||||
if (himport_r(&env_htab, (char *)ep->data, ENV_SIZE, '\0', 0, 0,
|
||||
if (himport_r(&env_htab, (char *)ep->data, ENV_SIZE, '\0', flags, 0,
|
||||
0, NULL)) {
|
||||
gd->flags |= GD_FLG_ENV_READY;
|
||||
return 0;
|
||||
|
@ -141,7 +142,8 @@ int env_import(const char *buf, int check)
|
|||
static unsigned char env_flags;
|
||||
|
||||
int env_import_redund(const char *buf1, int buf1_read_fail,
|
||||
const char *buf2, int buf2_read_fail)
|
||||
const char *buf2, int buf2_read_fail,
|
||||
int flags)
|
||||
{
|
||||
int crc1_ok, crc2_ok;
|
||||
env_t *ep, *tmp_env1, *tmp_env2;
|
||||
|
@ -161,10 +163,10 @@ int env_import_redund(const char *buf1, int buf1_read_fail,
|
|||
return -EIO;
|
||||
} else if (!buf1_read_fail && buf2_read_fail) {
|
||||
gd->env_valid = ENV_VALID;
|
||||
return env_import((char *)tmp_env1, 1);
|
||||
return env_import((char *)tmp_env1, 1, flags);
|
||||
} else if (buf1_read_fail && !buf2_read_fail) {
|
||||
gd->env_valid = ENV_REDUND;
|
||||
return env_import((char *)tmp_env2, 1);
|
||||
return env_import((char *)tmp_env2, 1, flags);
|
||||
}
|
||||
|
||||
crc1_ok = crc32(0, tmp_env1->data, ENV_SIZE) ==
|
||||
|
@ -199,7 +201,7 @@ int env_import_redund(const char *buf1, int buf1_read_fail,
|
|||
ep = tmp_env2;
|
||||
|
||||
env_flags = ep->flags;
|
||||
return env_import((char *)ep, 0);
|
||||
return env_import((char *)ep, 0, flags);
|
||||
}
|
||||
#endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */
|
||||
|
||||
|
|
2
env/eeprom.c
vendored
2
env/eeprom.c
vendored
|
@ -188,7 +188,7 @@ static int env_eeprom_load(void)
|
|||
eeprom_bus_read(CONFIG_SYS_DEF_EEPROM_ADDR,
|
||||
off, (uchar *)buf_env, CONFIG_ENV_SIZE);
|
||||
|
||||
return env_import(buf_env, 1);
|
||||
return env_import(buf_env, 1, H_EXTERNAL);
|
||||
}
|
||||
|
||||
static int env_eeprom_save(void)
|
||||
|
|
82
env/env.c
vendored
82
env/env.c
vendored
|
@ -131,8 +131,6 @@ __weak enum env_location env_get_location(enum env_operation op, int prio)
|
|||
if (prio >= ARRAY_SIZE(env_locations))
|
||||
return ENVL_UNKNOWN;
|
||||
|
||||
gd->env_load_prio = prio;
|
||||
|
||||
return env_locations[prio];
|
||||
}
|
||||
|
||||
|
@ -189,9 +187,6 @@ int env_load(void)
|
|||
for (prio = 0; (drv = env_driver_lookup(ENVOP_LOAD, prio)); prio++) {
|
||||
int ret;
|
||||
|
||||
if (!drv->load)
|
||||
continue;
|
||||
|
||||
if (!env_has_inited(drv->location))
|
||||
continue;
|
||||
|
||||
|
@ -204,7 +199,11 @@ int env_load(void)
|
|||
ret = drv->load();
|
||||
if (!ret) {
|
||||
printf("OK\n");
|
||||
gd->env_load_prio = prio;
|
||||
|
||||
#if !CONFIG_IS_ENABLED(ENV_APPEND)
|
||||
return 0;
|
||||
#endif
|
||||
} else if (ret == -ENOMSG) {
|
||||
/* Handle "bad CRC" case */
|
||||
if (best_prio == -1)
|
||||
|
@ -227,7 +226,36 @@ int env_load(void)
|
|||
debug("Selecting environment with bad CRC\n");
|
||||
else
|
||||
best_prio = 0;
|
||||
env_get_location(ENVOP_LOAD, best_prio);
|
||||
|
||||
gd->env_load_prio = best_prio;
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
int env_reload(void)
|
||||
{
|
||||
struct env_driver *drv;
|
||||
|
||||
drv = env_driver_lookup(ENVOP_LOAD, gd->env_load_prio);
|
||||
if (drv) {
|
||||
int ret;
|
||||
|
||||
printf("Loading Environment from %s... ", drv->name);
|
||||
|
||||
if (!env_has_inited(drv->location)) {
|
||||
printf("not initialized\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = drv->load();
|
||||
if (ret)
|
||||
printf("Failed (%d)\n", ret);
|
||||
else
|
||||
printf("OK\n");
|
||||
|
||||
if (!ret)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
@ -318,3 +346,45 @@ int env_init(void)
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int env_select(const char *name)
|
||||
{
|
||||
struct env_driver *drv;
|
||||
const int n_ents = ll_entry_count(struct env_driver, env_driver);
|
||||
struct env_driver *entry;
|
||||
int prio;
|
||||
bool found = false;
|
||||
|
||||
printf("Select Environment on %s: ", name);
|
||||
|
||||
/* search ENV driver by name */
|
||||
drv = ll_entry_start(struct env_driver, env_driver);
|
||||
for (entry = drv; entry != drv + n_ents; entry++) {
|
||||
if (!strcmp(entry->name, name)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
printf("driver not found\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* search priority by driver */
|
||||
for (prio = 0; (drv = env_driver_lookup(ENVOP_INIT, prio)); prio++) {
|
||||
if (entry->location == env_get_location(ENVOP_LOAD, prio)) {
|
||||
/* when priority change, reset the ENV flags */
|
||||
if (gd->env_load_prio != prio) {
|
||||
gd->env_load_prio = prio;
|
||||
gd->env_valid = ENV_INVALID;
|
||||
gd->flags &= ~GD_FLG_ENV_DEFAULT;
|
||||
}
|
||||
printf("OK\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
printf("priority not found\n");
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
|
54
env/ext4.c
vendored
54
env/ext4.c
vendored
|
@ -32,6 +32,8 @@
|
|||
#include <ext4fs.h>
|
||||
#include <mmc.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
__weak const char *env_ext4_get_intf(void)
|
||||
{
|
||||
return (const char *)CONFIG_ENV_EXT4_INTERFACE;
|
||||
|
@ -42,9 +44,8 @@ __weak const char *env_ext4_get_dev_part(void)
|
|||
return (const char *)CONFIG_ENV_EXT4_DEVICE_AND_PART;
|
||||
}
|
||||
|
||||
static int env_ext4_save(void)
|
||||
static int env_ext4_save_buffer(env_t *env_new)
|
||||
{
|
||||
env_t env_new;
|
||||
struct blk_desc *dev_desc = NULL;
|
||||
struct disk_partition info;
|
||||
int dev, part;
|
||||
|
@ -52,10 +53,6 @@ static int env_ext4_save(void)
|
|||
const char *ifname = env_ext4_get_intf();
|
||||
const char *dev_and_part = env_ext4_get_dev_part();
|
||||
|
||||
err = env_export(&env_new);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
part = blk_get_device_part_str(ifname, dev_and_part,
|
||||
&dev_desc, &info, 1);
|
||||
if (part < 0)
|
||||
|
@ -70,7 +67,7 @@ static int env_ext4_save(void)
|
|||
return 1;
|
||||
}
|
||||
|
||||
err = ext4fs_write(CONFIG_ENV_EXT4_FILE, (void *)&env_new,
|
||||
err = ext4fs_write(CONFIG_ENV_EXT4_FILE, (void *)env_new,
|
||||
sizeof(env_t), FILETYPE_REG);
|
||||
ext4fs_close();
|
||||
|
||||
|
@ -80,7 +77,42 @@ static int env_ext4_save(void)
|
|||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int env_ext4_save(void)
|
||||
{
|
||||
env_t env_new;
|
||||
int err;
|
||||
|
||||
err = env_export(&env_new);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = env_ext4_save_buffer(&env_new);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
gd->env_valid = ENV_VALID;
|
||||
puts("done\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int env_ext4_erase(void)
|
||||
{
|
||||
env_t env_new;
|
||||
int err;
|
||||
|
||||
memset(&env_new, 0, sizeof(env_t));
|
||||
|
||||
err = env_ext4_save_buffer(&env_new);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
gd->env_valid = ENV_INVALID;
|
||||
puts("done\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -124,7 +156,11 @@ static int env_ext4_load(void)
|
|||
goto err_env_relocate;
|
||||
}
|
||||
|
||||
return env_import(buf, 1);
|
||||
err = env_import(buf, 1, H_EXTERNAL);
|
||||
if (!err)
|
||||
gd->env_valid = ENV_VALID;
|
||||
|
||||
return err;
|
||||
|
||||
err_env_relocate:
|
||||
env_set_default(NULL, 0);
|
||||
|
@ -137,4 +173,6 @@ U_BOOT_ENV_LOCATION(ext4) = {
|
|||
ENV_NAME("EXT4")
|
||||
.load = env_ext4_load,
|
||||
.save = ENV_SAVE_PTR(env_ext4_save),
|
||||
.erase = CONFIG_IS_ENABLED(CMD_ERASEENV) ? env_ext4_erase :
|
||||
NULL,
|
||||
};
|
||||
|
|
2
env/fat.c
vendored
2
env/fat.c
vendored
|
@ -144,7 +144,7 @@ static int env_fat_load(void)
|
|||
goto err_env_relocate;
|
||||
}
|
||||
|
||||
return env_import(buf, 1);
|
||||
return env_import(buf, 1, H_EXTERNAL);
|
||||
|
||||
err_env_relocate:
|
||||
env_set_default(NULL, 0);
|
||||
|
|
66
env/flags.c
vendored
66
env/flags.c
vendored
|
@ -28,8 +28,15 @@
|
|||
#define ENV_FLAGS_NET_VARTYPE_REPS ""
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ENV_WRITEABLE_LIST
|
||||
#define ENV_FLAGS_WRITEABLE_VARACCESS_REPS "w"
|
||||
#else
|
||||
#define ENV_FLAGS_WRITEABLE_VARACCESS_REPS ""
|
||||
#endif
|
||||
|
||||
static const char env_flags_vartype_rep[] = "sdxb" ENV_FLAGS_NET_VARTYPE_REPS;
|
||||
static const char env_flags_varaccess_rep[] = "aroc";
|
||||
static const char env_flags_varaccess_rep[] =
|
||||
"aroc" ENV_FLAGS_WRITEABLE_VARACCESS_REPS;
|
||||
static const int env_flags_varaccess_mask[] = {
|
||||
0,
|
||||
ENV_FLAGS_VARACCESS_PREVENT_DELETE |
|
||||
|
@ -38,7 +45,11 @@ static const int env_flags_varaccess_mask[] = {
|
|||
ENV_FLAGS_VARACCESS_PREVENT_DELETE |
|
||||
ENV_FLAGS_VARACCESS_PREVENT_OVERWR,
|
||||
ENV_FLAGS_VARACCESS_PREVENT_DELETE |
|
||||
ENV_FLAGS_VARACCESS_PREVENT_NONDEF_OVERWR};
|
||||
ENV_FLAGS_VARACCESS_PREVENT_NONDEF_OVERWR,
|
||||
#ifdef CONFIG_ENV_WRITEABLE_LIST
|
||||
ENV_FLAGS_VARACCESS_WRITEABLE,
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef CONFIG_CMD_ENV_FLAGS
|
||||
static const char * const env_flags_vartype_names[] = {
|
||||
|
@ -56,6 +67,9 @@ static const char * const env_flags_varaccess_names[] = {
|
|||
"read-only",
|
||||
"write-once",
|
||||
"change-default",
|
||||
#ifdef CONFIG_ENV_WRITEABLE_LIST
|
||||
"writeable",
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -130,21 +144,25 @@ enum env_flags_vartype env_flags_parse_vartype(const char *flags)
|
|||
*/
|
||||
enum env_flags_varaccess env_flags_parse_varaccess(const char *flags)
|
||||
{
|
||||
enum env_flags_varaccess va_default = env_flags_varaccess_any;
|
||||
enum env_flags_varaccess va;
|
||||
char *access;
|
||||
|
||||
if (strlen(flags) <= ENV_FLAGS_VARACCESS_LOC)
|
||||
return env_flags_varaccess_any;
|
||||
return va_default;
|
||||
|
||||
access = strchr(env_flags_varaccess_rep,
|
||||
flags[ENV_FLAGS_VARACCESS_LOC]);
|
||||
|
||||
if (access != NULL)
|
||||
return (enum env_flags_varaccess)
|
||||
if (access != NULL) {
|
||||
va = (enum env_flags_varaccess)
|
||||
(access - &env_flags_varaccess_rep[0]);
|
||||
return va;
|
||||
}
|
||||
|
||||
printf("## Warning: Unknown environment variable access method '%c'\n",
|
||||
flags[ENV_FLAGS_VARACCESS_LOC]);
|
||||
return env_flags_varaccess_any;
|
||||
return va_default;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -152,17 +170,21 @@ enum env_flags_varaccess env_flags_parse_varaccess(const char *flags)
|
|||
*/
|
||||
enum env_flags_varaccess env_flags_parse_varaccess_from_binflags(int binflags)
|
||||
{
|
||||
enum env_flags_varaccess va_default = env_flags_varaccess_any;
|
||||
enum env_flags_varaccess va;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(env_flags_varaccess_mask); i++)
|
||||
if (env_flags_varaccess_mask[i] ==
|
||||
(binflags & ENV_FLAGS_VARACCESS_BIN_MASK))
|
||||
return (enum env_flags_varaccess)i;
|
||||
(binflags & ENV_FLAGS_VARACCESS_BIN_MASK)) {
|
||||
va = (enum env_flags_varaccess)i;
|
||||
return va;
|
||||
}
|
||||
|
||||
printf("Warning: Non-standard access flags. (0x%x)\n",
|
||||
binflags & ENV_FLAGS_VARACCESS_BIN_MASK);
|
||||
|
||||
return env_flags_varaccess_any;
|
||||
return va_default;
|
||||
}
|
||||
|
||||
static inline int is_hex_prefix(const char *value)
|
||||
|
@ -326,13 +348,14 @@ enum env_flags_vartype env_flags_get_type(const char *name)
|
|||
enum env_flags_varaccess env_flags_get_varaccess(const char *name)
|
||||
{
|
||||
const char *flags_list = env_get(ENV_FLAGS_VAR);
|
||||
enum env_flags_varaccess va_default = env_flags_varaccess_any;
|
||||
char flags[ENV_FLAGS_ATTR_MAX_LEN + 1];
|
||||
|
||||
if (env_flags_lookup(flags_list, name, flags))
|
||||
return env_flags_varaccess_any;
|
||||
return va_default;
|
||||
|
||||
if (strlen(flags) <= ENV_FLAGS_VARACCESS_LOC)
|
||||
return env_flags_varaccess_any;
|
||||
return va_default;
|
||||
|
||||
return env_flags_parse_varaccess(flags);
|
||||
}
|
||||
|
@ -426,7 +449,11 @@ void env_flags_init(struct env_entry *var_entry)
|
|||
int ret = 1;
|
||||
|
||||
if (first_call) {
|
||||
#ifdef CONFIG_ENV_WRITEABLE_LIST
|
||||
flags_list = ENV_FLAGS_LIST_STATIC;
|
||||
#else
|
||||
flags_list = env_get(ENV_FLAGS_VAR);
|
||||
#endif
|
||||
first_call = 0;
|
||||
}
|
||||
/* look in the ".flags" and static for a reference to this variable */
|
||||
|
@ -523,9 +550,24 @@ int env_flags_validate(const struct env_entry *item, const char *newval,
|
|||
}
|
||||
|
||||
/* check for access permission */
|
||||
#ifdef CONFIG_ENV_WRITEABLE_LIST
|
||||
if (flag & H_DEFAULT)
|
||||
return 0; /* Default env is always OK */
|
||||
|
||||
/*
|
||||
* External writeable variables can be overwritten by external env,
|
||||
* anything else can not be overwritten by external env.
|
||||
*/
|
||||
if ((flag & H_EXTERNAL) &&
|
||||
!(item->flags & ENV_FLAGS_VARACCESS_WRITEABLE))
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_ENV_ACCESS_IGNORE_FORCE
|
||||
if (flag & H_FORCE)
|
||||
if (flag & H_FORCE) {
|
||||
printf("## Error: Can't force access to \"%s\"\n", name);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
switch (op) {
|
||||
case env_op_delete:
|
||||
|
|
2
env/flash.c
vendored
2
env/flash.c
vendored
|
@ -351,7 +351,7 @@ static int env_flash_load(void)
|
|||
"reading environment; recovered successfully\n\n");
|
||||
#endif /* CONFIG_ENV_ADDR_REDUND */
|
||||
|
||||
return env_import((char *)flash_addr, 1);
|
||||
return env_import((char *)flash_addr, 1, H_EXTERNAL);
|
||||
}
|
||||
#endif /* LOADENV */
|
||||
|
||||
|
|
4
env/mmc.c
vendored
4
env/mmc.c
vendored
|
@ -338,7 +338,7 @@ static int env_mmc_load(void)
|
|||
read2_fail = read_env(mmc, CONFIG_ENV_SIZE, offset2, tmp_env2);
|
||||
|
||||
ret = env_import_redund((char *)tmp_env1, read1_fail, (char *)tmp_env2,
|
||||
read2_fail);
|
||||
read2_fail, H_EXTERNAL);
|
||||
|
||||
fini:
|
||||
fini_mmc_for_env(mmc);
|
||||
|
@ -380,7 +380,7 @@ static int env_mmc_load(void)
|
|||
goto fini;
|
||||
}
|
||||
|
||||
ret = env_import(buf, 1);
|
||||
ret = env_import(buf, 1, H_EXTERNAL);
|
||||
if (!ret) {
|
||||
ep = (env_t *)buf;
|
||||
gd->env_addr = (ulong)&ep->data;
|
||||
|
|
4
env/nand.c
vendored
4
env/nand.c
vendored
|
@ -331,7 +331,7 @@ static int env_nand_load(void)
|
|||
read2_fail = readenv(CONFIG_ENV_OFFSET_REDUND, (u_char *) tmp_env2);
|
||||
|
||||
ret = env_import_redund((char *)tmp_env1, read1_fail, (char *)tmp_env2,
|
||||
read2_fail);
|
||||
read2_fail, H_EXTERNAL);
|
||||
|
||||
done:
|
||||
free(tmp_env1);
|
||||
|
@ -372,7 +372,7 @@ static int env_nand_load(void)
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
return env_import(buf, 1);
|
||||
return env_import(buf, 1, H_EXTERNAL);
|
||||
#endif /* ! ENV_IS_EMBEDDED */
|
||||
|
||||
return 0;
|
||||
|
|
17
env/nowhere.c
vendored
17
env/nowhere.c
vendored
|
@ -27,8 +27,25 @@ static int env_nowhere_init(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int env_nowhere_load(void)
|
||||
{
|
||||
/*
|
||||
* for SPL, set env_valid = ENV_INVALID is enougth as env_get_char()
|
||||
* return the default env if env_get is used
|
||||
* and SPL don't used env_import to reduce its size
|
||||
* For U-Boot proper, import the default environment to allow reload.
|
||||
*/
|
||||
if (!IS_ENABLED(CONFIG_SPL_BUILD))
|
||||
env_set_default(NULL, 0);
|
||||
|
||||
gd->env_valid = ENV_INVALID;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_BOOT_ENV_LOCATION(nowhere) = {
|
||||
.location = ENVL_NOWHERE,
|
||||
.init = env_nowhere_init,
|
||||
.load = env_nowhere_load,
|
||||
ENV_NAME("nowhere")
|
||||
};
|
||||
|
|
2
env/nvram.c
vendored
2
env/nvram.c
vendored
|
@ -64,7 +64,7 @@ static int env_nvram_load(void)
|
|||
#else
|
||||
memcpy(buf, (void *)CONFIG_ENV_ADDR, CONFIG_ENV_SIZE);
|
||||
#endif
|
||||
return env_import(buf, 1);
|
||||
return env_import(buf, 1, H_EXTERNAL);
|
||||
}
|
||||
|
||||
static int env_nvram_save(void)
|
||||
|
|
2
env/onenand.c
vendored
2
env/onenand.c
vendored
|
@ -55,7 +55,7 @@ static int env_onenand_load(void)
|
|||
mtd->writesize = MAX_ONENAND_PAGESIZE;
|
||||
#endif /* !ENV_IS_EMBEDDED */
|
||||
|
||||
rc = env_import(buf, 1);
|
||||
rc = env_import(buf, 1, H_EXTERNAL);
|
||||
if (!rc)
|
||||
gd->env_valid = ENV_VALID;
|
||||
|
||||
|
|
2
env/remote.c
vendored
2
env/remote.c
vendored
|
@ -45,7 +45,7 @@ static int env_remote_save(void)
|
|||
static int env_remote_load(void)
|
||||
{
|
||||
#ifndef ENV_IS_EMBEDDED
|
||||
return env_import((char *)env_ptr, 1);
|
||||
return env_import((char *)env_ptr, 1, H_EXTERNAL);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
|
2
env/sata.c
vendored
2
env/sata.c
vendored
|
@ -111,7 +111,7 @@ static void env_sata_load(void)
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
return env_import(buf, 1);
|
||||
return env_import(buf, 1, H_EXTERNAL);
|
||||
}
|
||||
|
||||
U_BOOT_ENV_LOCATION(sata) = {
|
||||
|
|
6
env/sf.c
vendored
6
env/sf.c
vendored
|
@ -172,7 +172,7 @@ static int env_sf_load(void)
|
|||
CONFIG_ENV_SIZE, tmp_env2);
|
||||
|
||||
ret = env_import_redund((char *)tmp_env1, read1_fail, (char *)tmp_env2,
|
||||
read2_fail);
|
||||
read2_fail, H_EXTERNAL);
|
||||
|
||||
spi_flash_free(env_flash);
|
||||
env_flash = NULL;
|
||||
|
@ -265,7 +265,7 @@ static int env_sf_load(void)
|
|||
goto err_read;
|
||||
}
|
||||
|
||||
ret = env_import(buf, 1);
|
||||
ret = env_import(buf, 1, H_EXTERNAL);
|
||||
if (!ret)
|
||||
gd->env_valid = ENV_VALID;
|
||||
|
||||
|
@ -305,7 +305,7 @@ static int env_sf_init(void)
|
|||
|
||||
U_BOOT_ENV_LOCATION(sf) = {
|
||||
.location = ENVL_SPI_FLASH,
|
||||
ENV_NAME("SPI Flash")
|
||||
ENV_NAME("SPIFlash")
|
||||
.load = env_sf_load,
|
||||
.save = CONFIG_IS_ENABLED(SAVEENV) ? ENV_SAVE_PTR(env_sf_save) : NULL,
|
||||
#if defined(INITENV) && (CONFIG_ENV_ADDR != 0x0)
|
||||
|
|
4
env/ubi.c
vendored
4
env/ubi.c
vendored
|
@ -141,7 +141,7 @@ static int env_ubi_load(void)
|
|||
CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME_REDUND);
|
||||
|
||||
return env_import_redund((char *)tmp_env1, read1_fail, (char *)tmp_env2,
|
||||
read2_fail);
|
||||
read2_fail, H_EXTERNAL);
|
||||
}
|
||||
#else /* ! CONFIG_SYS_REDUNDAND_ENVIRONMENT */
|
||||
static int env_ubi_load(void)
|
||||
|
@ -172,7 +172,7 @@ static int env_ubi_load(void)
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
return env_import(buf, 1);
|
||||
return env_import(buf, 1, H_EXTERNAL);
|
||||
}
|
||||
#endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */
|
||||
|
||||
|
|
|
@ -265,6 +265,13 @@ int env_set_default_vars(int nvars, char *const vars[], int flags);
|
|||
*/
|
||||
int env_load(void);
|
||||
|
||||
/**
|
||||
* env_reload() - Re-Load the environment from current storage
|
||||
*
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int env_reload(void);
|
||||
|
||||
/**
|
||||
* env_save() - Save the environment to storage
|
||||
*
|
||||
|
@ -279,6 +286,13 @@ int env_save(void);
|
|||
*/
|
||||
int env_erase(void);
|
||||
|
||||
/**
|
||||
* env_select() - Select the environment storage
|
||||
*
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int env_select(const char *name);
|
||||
|
||||
/**
|
||||
* env_import() - Import from a binary representation into hash table
|
||||
*
|
||||
|
@ -288,10 +302,11 @@ int env_erase(void);
|
|||
* @buf: Buffer containing the environment (struct environemnt_s *)
|
||||
* @check: non-zero to check the CRC at the start of the environment, 0 to
|
||||
* ignore it
|
||||
* @flags: Flags controlling matching (H_... - see search.h)
|
||||
* @return 0 if imported successfully, -ENOMSG if the CRC was bad, -EIO if
|
||||
* something else went wrong
|
||||
*/
|
||||
int env_import(const char *buf, int check);
|
||||
int env_import(const char *buf, int check, int flags);
|
||||
|
||||
/**
|
||||
* env_export() - Export the environment to a buffer
|
||||
|
@ -310,10 +325,12 @@ int env_export(struct environment_s *env_out);
|
|||
* @buf1_read_fail: 0 if buf1 is valid, non-zero if invalid
|
||||
* @buf2: Second environment (struct environemnt_s *)
|
||||
* @buf2_read_fail: 0 if buf2 is valid, non-zero if invalid
|
||||
* @flags: Flags controlling matching (H_... - see search.h)
|
||||
* @return 0 if OK, -EIO if no environment is valid, -ENOMSG if the CRC was bad
|
||||
*/
|
||||
int env_import_redund(const char *buf1, int buf1_read_fail,
|
||||
const char *buf2, int buf2_read_fail);
|
||||
const char *buf2, int buf2_read_fail,
|
||||
int flags);
|
||||
|
||||
/**
|
||||
* env_get_default() - Look up a variable from the default environment
|
||||
|
@ -342,5 +359,4 @@ int env_get_char(int index);
|
|||
* This is used for those unfortunate archs with crappy toolchains
|
||||
*/
|
||||
void env_reloc(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -24,6 +24,9 @@ enum env_flags_varaccess {
|
|||
env_flags_varaccess_readonly,
|
||||
env_flags_varaccess_writeonce,
|
||||
env_flags_varaccess_changedefault,
|
||||
#ifdef CONFIG_ENV_WRITEABLE_LIST
|
||||
env_flags_varaccess_writeable,
|
||||
#endif
|
||||
env_flags_varaccess_end
|
||||
};
|
||||
|
||||
|
@ -173,6 +176,7 @@ int env_flags_validate(const struct env_entry *item, const char *newval,
|
|||
#define ENV_FLAGS_VARACCESS_PREVENT_CREATE 0x00000010
|
||||
#define ENV_FLAGS_VARACCESS_PREVENT_OVERWR 0x00000020
|
||||
#define ENV_FLAGS_VARACCESS_PREVENT_NONDEF_OVERWR 0x00000040
|
||||
#define ENV_FLAGS_VARACCESS_BIN_MASK 0x00000078
|
||||
#define ENV_FLAGS_VARACCESS_WRITEABLE 0x00000080
|
||||
#define ENV_FLAGS_VARACCESS_BIN_MASK 0x000000f8
|
||||
|
||||
#endif /* __ENV_FLAGS_H__ */
|
||||
|
|
|
@ -154,8 +154,7 @@ struct env_driver {
|
|||
/**
|
||||
* load() - Load the environment from storage
|
||||
*
|
||||
* This method is optional. If not provided, no environment will be
|
||||
* loaded.
|
||||
* This method is required for loading environment
|
||||
*
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
|
@ -211,6 +210,26 @@ struct env_driver {
|
|||
|
||||
extern struct hsearch_data env_htab;
|
||||
|
||||
/**
|
||||
* env_ext4_get_intf() - Provide the interface for env in EXT4
|
||||
*
|
||||
* It is a weak function allowing board to overidde the default interface for
|
||||
* U-Boot env in EXT4: CONFIG_ENV_EXT4_INTERFACE
|
||||
*
|
||||
* @return string of interface, empty if not supported
|
||||
*/
|
||||
const char *env_ext4_get_intf(void);
|
||||
|
||||
/**
|
||||
* env_ext4_get_dev_part() - Provide the device and partition for env in EXT4
|
||||
*
|
||||
* It is a weak function allowing board to overidde the default device and
|
||||
* partition used for U-Boot env in EXT4: CONFIG_ENV_EXT4_DEVICE_AND_PART
|
||||
*
|
||||
* @return string of device and partition
|
||||
*/
|
||||
const char *env_ext4_get_dev_part(void);
|
||||
|
||||
/**
|
||||
* env_get_location()- Provide the best location for the U-Boot environment
|
||||
*
|
||||
|
|
|
@ -112,5 +112,7 @@ int hwalk_r(struct hsearch_data *htab,
|
|||
#define H_MATCH_METHOD (H_MATCH_IDENT | H_MATCH_SUBSTR | H_MATCH_REGEX)
|
||||
#define H_PROGRAMMATIC (1 << 9) /* indicate that an import is from env_set() */
|
||||
#define H_ORIGIN_FLAGS (H_INTERACTIVE | H_PROGRAMMATIC)
|
||||
#define H_DEFAULT (1 << 10) /* indicate that an import is default env */
|
||||
#define H_EXTERNAL (1 << 11) /* indicate that an import is external env */
|
||||
|
||||
#endif /* _SEARCH_H_ */
|
||||
|
|
|
@ -826,6 +826,10 @@ int himport_r(struct hsearch_data *htab,
|
|||
if (nvars)
|
||||
memcpy(localvars, vars, sizeof(vars[0]) * nvars);
|
||||
|
||||
#if CONFIG_IS_ENABLED(ENV_APPEND)
|
||||
flag |= H_NOCLEAR;
|
||||
#endif
|
||||
|
||||
if ((flag & H_NOCLEAR) == 0 && !nvars) {
|
||||
/* Destroy old hash table if one exists */
|
||||
debug("Destroy Hash Table: %p table = %p\n", htab,
|
||||
|
@ -946,9 +950,12 @@ int himport_r(struct hsearch_data *htab,
|
|||
e.data = value;
|
||||
|
||||
hsearch_r(e, ENV_ENTER, &rv, htab, flag);
|
||||
if (rv == NULL)
|
||||
#if !CONFIG_IS_ENABLED(ENV_WRITEABLE_LIST)
|
||||
if (rv == NULL) {
|
||||
printf("himport_r: can't insert \"%s=%s\" into hash table\n",
|
||||
name, value);
|
||||
}
|
||||
#endif
|
||||
|
||||
debug("INSERT: table %p, filled %d/%d rv %p ==> name=\"%s\" value=\"%s\"\n",
|
||||
htab, htab->filled, htab->size,
|
||||
|
|
|
@ -199,6 +199,6 @@ def test_efi_grub_net(u_boot_console):
|
|||
# Then exit cleanly
|
||||
u_boot_console.wait_for('grub>')
|
||||
u_boot_console.run_command('exit', wait_for_prompt=False, wait_for_echo=False)
|
||||
u_boot_console.wait_for('=>')
|
||||
u_boot_console.wait_for(u_boot_console.prompt)
|
||||
# And give us our U-Boot prompt back
|
||||
u_boot_console.run_command('')
|
||||
|
|
|
@ -36,7 +36,7 @@ def test_efi_selftest_device_tree(u_boot_console):
|
|||
output = u_boot_console.run_command('bootefi selftest')
|
||||
assert '\'device tree\'' in output
|
||||
u_boot_console.run_command(cmd='setenv efi_selftest device tree')
|
||||
u_boot_console.run_command(cmd='setenv -f serial# Testing DT')
|
||||
u_boot_console.run_command(cmd='setenv serial# Testing DT')
|
||||
u_boot_console.run_command(cmd='bootefi selftest ${fdtcontroladdr}', wait_for_prompt=False)
|
||||
m = u_boot_console.p.expect(['serial-number: Testing DT', 'U-Boot'])
|
||||
if m != 0:
|
||||
|
|
|
@ -4,6 +4,10 @@
|
|||
|
||||
# Test operation of shell commands relating to environment variables.
|
||||
|
||||
import os
|
||||
import os.path
|
||||
from subprocess import call, check_call, CalledProcessError
|
||||
|
||||
import pytest
|
||||
import u_boot_utils
|
||||
|
||||
|
@ -374,7 +378,6 @@ def test_env_info(state_test_env):
|
|||
@pytest.mark.buildconfigspec('cmd_nvedit_info')
|
||||
@pytest.mark.buildconfigspec('cmd_echo')
|
||||
def test_env_info_sandbox(state_test_env):
|
||||
|
||||
"""Test 'env info' command result with several options on sandbox
|
||||
with a known ENV configuration: ready & default & persistent
|
||||
"""
|
||||
|
@ -399,3 +402,111 @@ def test_env_info_sandbox(state_test_env):
|
|||
response = c.run_command('env info -d -p -q')
|
||||
response = c.run_command('echo $?')
|
||||
assert response == "1"
|
||||
|
||||
def mk_env_ext4(state_test_env):
|
||||
|
||||
"""Create a empty ext4 file system volume."""
|
||||
c = state_test_env.u_boot_console
|
||||
filename = 'env.ext4.img'
|
||||
persistent = c.config.persistent_data_dir + '/' + filename
|
||||
fs_img = c.config.result_dir + '/' + filename
|
||||
|
||||
if os.path.exists(persistent):
|
||||
c.log.action('Disk image file ' + persistent + ' already exists')
|
||||
else:
|
||||
try:
|
||||
u_boot_utils.run_and_log(c, 'dd if=/dev/zero of=%s bs=1M count=16' % persistent)
|
||||
u_boot_utils.run_and_log(c, 'mkfs.ext4 -O ^metadata_csum %s' % persistent)
|
||||
except CalledProcessError:
|
||||
call('rm -f %s' % persistent, shell=True)
|
||||
raise
|
||||
|
||||
u_boot_utils.run_and_log(c, ['cp', '-f', persistent, fs_img])
|
||||
return fs_img
|
||||
|
||||
@pytest.mark.boardspec('sandbox')
|
||||
@pytest.mark.buildconfigspec('cmd_echo')
|
||||
@pytest.mark.buildconfigspec('cmd_nvedit_info')
|
||||
@pytest.mark.buildconfigspec('cmd_nvedit_load')
|
||||
@pytest.mark.buildconfigspec('cmd_nvedit_select')
|
||||
@pytest.mark.buildconfigspec('env_is_in_ext4')
|
||||
def test_env_ext4(state_test_env):
|
||||
|
||||
"""Test ENV in EXT4 on sandbox."""
|
||||
c = state_test_env.u_boot_console
|
||||
fs_img = ''
|
||||
try:
|
||||
fs_img = mk_env_ext4(state_test_env)
|
||||
|
||||
c.run_command('host bind 0 %s' % fs_img)
|
||||
|
||||
response = c.run_command('ext4ls host 0:0')
|
||||
assert 'uboot.env' not in response
|
||||
|
||||
# force env location: EXT4 (prio 1 in sandbox)
|
||||
response = c.run_command('env select EXT4')
|
||||
assert 'Select Environment on EXT4: OK' in response
|
||||
|
||||
response = c.run_command('env save')
|
||||
assert 'Saving Environment to EXT4' in response
|
||||
|
||||
response = c.run_command('env load')
|
||||
assert 'Loading Environment from EXT4... OK' in response
|
||||
|
||||
response = c.run_command('ext4ls host 0:0')
|
||||
assert '8192 uboot.env' in response
|
||||
|
||||
response = c.run_command('env info')
|
||||
assert 'env_valid = valid' in response
|
||||
assert 'env_ready = true' in response
|
||||
assert 'env_use_default = false' in response
|
||||
|
||||
response = c.run_command('env info -p -d')
|
||||
assert 'Environment was loaded from persistent storage' in response
|
||||
assert 'Environment can be persisted' in response
|
||||
|
||||
response = c.run_command('env info -d -q')
|
||||
assert response == ""
|
||||
response = c.run_command('echo $?')
|
||||
assert response == "1"
|
||||
|
||||
response = c.run_command('env info -p -q')
|
||||
assert response == ""
|
||||
response = c.run_command('echo $?')
|
||||
assert response == "0"
|
||||
|
||||
response = c.run_command('env erase')
|
||||
assert 'OK' in response
|
||||
|
||||
response = c.run_command('env load')
|
||||
assert 'Loading Environment from EXT4... ' in response
|
||||
assert 'bad CRC, using default environment' in response
|
||||
|
||||
response = c.run_command('env info')
|
||||
assert 'env_valid = invalid' in response
|
||||
assert 'env_ready = true' in response
|
||||
assert 'env_use_default = true' in response
|
||||
|
||||
response = c.run_command('env info -p -d')
|
||||
assert 'Default environment is used' in response
|
||||
assert 'Environment can be persisted' in response
|
||||
|
||||
# restore env location: NOWHERE (prio 0 in sandbox)
|
||||
response = c.run_command('env select nowhere')
|
||||
assert 'Select Environment on nowhere: OK' in response
|
||||
|
||||
response = c.run_command('env load')
|
||||
assert 'Loading Environment from nowhere... OK' in response
|
||||
|
||||
response = c.run_command('env info')
|
||||
assert 'env_valid = invalid' in response
|
||||
assert 'env_ready = true' in response
|
||||
assert 'env_use_default = true' in response
|
||||
|
||||
response = c.run_command('env info -p -d')
|
||||
assert 'Default environment is used' in response
|
||||
assert 'Environment cannot be persisted' in response
|
||||
|
||||
finally:
|
||||
if fs_img:
|
||||
call('rm -f %s' % fs_img, shell=True)
|
||||
|
|
24
tools/env/fw_env.c
vendored
24
tools/env/fw_env.c
vendored
|
@ -995,6 +995,7 @@ static int flash_write_buf(int dev, int fd, void *buf, size_t count)
|
|||
of the data */
|
||||
loff_t blockstart; /* running start of the current block -
|
||||
MEMGETBADBLOCK needs 64 bits */
|
||||
int was_locked; /* flash lock flag */
|
||||
int rc;
|
||||
|
||||
/*
|
||||
|
@ -1080,6 +1081,12 @@ static int flash_write_buf(int dev, int fd, void *buf, size_t count)
|
|||
}
|
||||
|
||||
erase.length = erasesize;
|
||||
if (DEVTYPE(dev) != MTD_ABSENT) {
|
||||
was_locked = ioctl(fd, MEMISLOCKED, &erase);
|
||||
/* treat any errors as unlocked flash */
|
||||
if (was_locked < 0)
|
||||
was_locked = 0;
|
||||
}
|
||||
|
||||
/* This only runs once on NOR flash and SPI-dataflash */
|
||||
while (processed < write_total) {
|
||||
|
@ -1099,7 +1106,8 @@ static int flash_write_buf(int dev, int fd, void *buf, size_t count)
|
|||
|
||||
if (DEVTYPE(dev) != MTD_ABSENT) {
|
||||
erase.start = blockstart;
|
||||
ioctl(fd, MEMUNLOCK, &erase);
|
||||
if (was_locked)
|
||||
ioctl(fd, MEMUNLOCK, &erase);
|
||||
/* These do not need an explicit erase cycle */
|
||||
if (DEVTYPE(dev) != MTD_DATAFLASH)
|
||||
if (ioctl(fd, MEMERASE, &erase) != 0) {
|
||||
|
@ -1127,8 +1135,10 @@ static int flash_write_buf(int dev, int fd, void *buf, size_t count)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (DEVTYPE(dev) != MTD_ABSENT)
|
||||
ioctl(fd, MEMLOCK, &erase);
|
||||
if (DEVTYPE(dev) != MTD_ABSENT) {
|
||||
if (was_locked)
|
||||
ioctl(fd, MEMLOCK, &erase);
|
||||
}
|
||||
|
||||
processed += erasesize;
|
||||
block_seek = 0;
|
||||
|
@ -1149,7 +1159,9 @@ static int flash_flag_obsolete(int dev, int fd, off_t offset)
|
|||
int rc;
|
||||
struct erase_info_user erase;
|
||||
char tmp = ENV_REDUND_OBSOLETE;
|
||||
int was_locked; /* flash lock flag */
|
||||
|
||||
was_locked = ioctl(fd, MEMISLOCKED, &erase);
|
||||
erase.start = DEVOFFSET(dev);
|
||||
erase.length = DEVESIZE(dev);
|
||||
/* This relies on the fact, that ENV_REDUND_OBSOLETE == 0 */
|
||||
|
@ -1159,9 +1171,11 @@ static int flash_flag_obsolete(int dev, int fd, off_t offset)
|
|||
DEVNAME(dev));
|
||||
return rc;
|
||||
}
|
||||
ioctl(fd, MEMUNLOCK, &erase);
|
||||
if (was_locked)
|
||||
ioctl(fd, MEMUNLOCK, &erase);
|
||||
rc = write(fd, &tmp, sizeof(tmp));
|
||||
ioctl(fd, MEMLOCK, &erase);
|
||||
if (was_locked)
|
||||
ioctl(fd, MEMLOCK, &erase);
|
||||
if (rc < 0)
|
||||
perror("Could not set obsolete flag");
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue