Merge patch series "test: env: Add test for environment storage in SPI NOR"
This patch series from Marek Vasut <marek.vasut+renesas@mailbox.org> adds support for having a platform be able to convert from a non-redundant envrionment to a redundant one at run-time. Link: https://lore.kernel.org/r/20251223143130.16266-1-marek.vasut+renesas@mailbox.org
This commit is contained in:
@@ -89,6 +89,7 @@ static enum env_location env_locations[] = {
|
||||
ENVL_NOWHERE,
|
||||
ENVL_EXT4,
|
||||
ENVL_FAT,
|
||||
ENVL_SPI_FLASH,
|
||||
};
|
||||
|
||||
enum env_location env_get_location(enum env_operation op, int prio)
|
||||
|
||||
@@ -2,10 +2,13 @@ CONFIG_TEXT_BASE=0
|
||||
CONFIG_SYS_MALLOC_LEN=0x6000000
|
||||
CONFIG_NR_DRAM_BANKS=1
|
||||
CONFIG_ENV_SIZE=0x2000
|
||||
CONFIG_ENV_OFFSET=0x0
|
||||
CONFIG_ENV_SECT_SIZE=0x1000
|
||||
CONFIG_DEFAULT_DEVICE_TREE="sandbox64"
|
||||
CONFIG_DM_RESET=y
|
||||
CONFIG_SYS_LOAD_ADDR=0x0
|
||||
CONFIG_PRE_CON_BUF_ADDR=0x100000
|
||||
CONFIG_ENV_OFFSET_REDUND=0x10000
|
||||
CONFIG_PCI=y
|
||||
CONFIG_SANDBOX64=y
|
||||
CONFIG_DEBUG_UART=y
|
||||
@@ -105,6 +108,10 @@ CONFIG_OF_LIVE=y
|
||||
CONFIG_ENV_IS_NOWHERE=y
|
||||
CONFIG_ENV_IS_IN_FAT=y
|
||||
CONFIG_ENV_IS_IN_EXT4=y
|
||||
CONFIG_ENV_IS_IN_SPI_FLASH=y
|
||||
CONFIG_ENV_SECT_SIZE_AUTO=y
|
||||
CONFIG_ENV_REDUNDANT=y
|
||||
CONFIG_ENV_REDUNDANT_UPGRADE=y
|
||||
CONFIG_ENV_EXT4_INTERFACE="host"
|
||||
CONFIG_ENV_EXT4_DEVICE_AND_PART="0:0"
|
||||
CONFIG_ENV_IMPORT_FDT=y
|
||||
|
||||
@@ -2,9 +2,12 @@ CONFIG_TEXT_BASE=0
|
||||
CONFIG_SYS_MALLOC_LEN=0x6000000
|
||||
CONFIG_NR_DRAM_BANKS=1
|
||||
CONFIG_ENV_SIZE=0x2000
|
||||
CONFIG_ENV_OFFSET=0x0
|
||||
CONFIG_ENV_SECT_SIZE=0x1000
|
||||
CONFIG_DM_RESET=y
|
||||
CONFIG_SYS_LOAD_ADDR=0x0
|
||||
CONFIG_PRE_CON_BUF_ADDR=0xf0000
|
||||
CONFIG_ENV_OFFSET_REDUND=0x10000
|
||||
CONFIG_PCI=y
|
||||
CONFIG_DEBUG_UART=y
|
||||
CONFIG_SYS_MEMTEST_START=0x00100000
|
||||
@@ -152,6 +155,10 @@ CONFIG_OF_LIVE=y
|
||||
CONFIG_ENV_IS_NOWHERE=y
|
||||
CONFIG_ENV_IS_IN_FAT=y
|
||||
CONFIG_ENV_IS_IN_EXT4=y
|
||||
CONFIG_ENV_IS_IN_SPI_FLASH=y
|
||||
CONFIG_ENV_SECT_SIZE_AUTO=y
|
||||
CONFIG_ENV_REDUNDANT=y
|
||||
CONFIG_ENV_REDUNDANT_UPGRADE=y
|
||||
CONFIG_ENV_EXT4_INTERFACE="host"
|
||||
CONFIG_ENV_EXT4_DEVICE_AND_PART="0:0"
|
||||
CONFIG_ENV_IMPORT_FDT=y
|
||||
|
||||
11
env/Kconfig
vendored
11
env/Kconfig
vendored
@@ -489,6 +489,17 @@ config ENV_REDUNDANT
|
||||
which is used by env import/export commands which are independent of
|
||||
storing variables to redundant location on a non volatile device.
|
||||
|
||||
config ENV_REDUNDANT_UPGRADE
|
||||
bool "Enable single-copy to redundant environment upgrade support"
|
||||
depends on ENV_REDUNDANT
|
||||
help
|
||||
Normally, redundant environment is expected to always operate on
|
||||
two copies of the environment. However, hardware that may have
|
||||
originally shipped with single-copy environment can be upgraded
|
||||
to redundant environment without loss of existing environment
|
||||
content by correctly configuring the location of the redundant
|
||||
environment copy and by enabling this option.
|
||||
|
||||
config ENV_FAT_INTERFACE
|
||||
string "Name of the block device for the environment"
|
||||
depends on ENV_IS_IN_FAT
|
||||
|
||||
31
env/common.c
vendored
31
env/common.c
vendored
@@ -473,14 +473,24 @@ int env_import(const char *buf, int check, int flags)
|
||||
#ifdef CONFIG_ENV_REDUNDANT
|
||||
static unsigned char env_flags;
|
||||
|
||||
#define ENV_SINGLE_HEADER_SIZE (sizeof(uint32_t))
|
||||
#define ENV_SINGLE_SIZE (CONFIG_ENV_SIZE - ENV_SINGLE_HEADER_SIZE)
|
||||
|
||||
typedef struct {
|
||||
uint32_t crc; /* CRC32 over data bytes */
|
||||
unsigned char data[ENV_SINGLE_SIZE]; /* Environment data */
|
||||
} env_single_t;
|
||||
|
||||
int env_check_redund(const char *buf1, int buf1_read_fail,
|
||||
const char *buf2, int buf2_read_fail)
|
||||
{
|
||||
int crc1_ok = 0, crc2_ok = 0;
|
||||
int crc1_ok = 0, crc2_ok = 0, i;
|
||||
env_t *tmp_env1, *tmp_env2;
|
||||
env_single_t *tmp_envs;
|
||||
|
||||
tmp_env1 = (env_t *)buf1;
|
||||
tmp_env2 = (env_t *)buf2;
|
||||
tmp_envs = (env_single_t *)buf1;
|
||||
|
||||
if (buf1_read_fail && buf2_read_fail) {
|
||||
puts("*** Error - No Valid Environment Area found\n");
|
||||
@@ -498,6 +508,25 @@ int env_check_redund(const char *buf1, int buf1_read_fail,
|
||||
tmp_env2->crc;
|
||||
|
||||
if (!crc1_ok && !crc2_ok) {
|
||||
/*
|
||||
* Upgrade single-copy environment to redundant environment.
|
||||
* In case CRC checks on both environment copies fail, try
|
||||
* one more CRC check on the primary environment copy and
|
||||
* treat it as single-copy environment. If that check does
|
||||
* pass, rewrite the single-copy environment into redundant
|
||||
* environment format and indicate the environment is valid.
|
||||
* The follow up calls will import the environment as if it
|
||||
* was a redundant environment. Follow up 'env save' will
|
||||
* then store two environment copies.
|
||||
*/
|
||||
if (CONFIG_IS_ENABLED(ENV_REDUNDANT_UPGRADE) && !buf1_read_fail &&
|
||||
crc32(0, tmp_envs->data, ENV_SINGLE_SIZE) == tmp_envs->crc) {
|
||||
for (i = ENV_SIZE - 1; i >= 0; i--)
|
||||
tmp_env1->data[i] = tmp_envs->data[i];
|
||||
tmp_env1->flags = 0;
|
||||
gd->env_valid = ENV_VALID;
|
||||
return 0;
|
||||
}
|
||||
gd->env_valid = ENV_INVALID;
|
||||
return -ENOMSG; /* needed for env_load() */
|
||||
} else if (crc1_ok && !crc2_ok) {
|
||||
|
||||
@@ -457,6 +457,42 @@ def mk_env_ext4(state_test_env):
|
||||
utils.run_and_log(c, ['cp', '-f', persistent, fs_img])
|
||||
return fs_img
|
||||
|
||||
def mk_env_spi_flash(state_test_env):
|
||||
|
||||
"""Create an empty SPI NOR image."""
|
||||
c = state_test_env.ubman
|
||||
filename = 'spi.bin'
|
||||
persistent = c.config.persistent_data_dir + '/' + filename
|
||||
spi_flash_img = c.config.source_dir + '/' + filename
|
||||
|
||||
if os.path.exists(persistent):
|
||||
c.log.action('SPI NOR image file ' + persistent + ' already exists')
|
||||
else:
|
||||
try:
|
||||
utils.run_and_log(c, 'dd if=/dev/zero of=%s bs=1M count=2' % persistent)
|
||||
except CalledProcessError:
|
||||
call('rm -f %s' % persistent, shell=True)
|
||||
raise
|
||||
|
||||
utils.run_and_log(c, ['cp', '-f', persistent, spi_flash_img])
|
||||
return spi_flash_img
|
||||
|
||||
def mk_env_spi_flash_single(state_test_env):
|
||||
|
||||
"""Create an single-copy SPI NOR image with foo=bar entry."""
|
||||
c = state_test_env.ubman
|
||||
filename = 'spi.bin'
|
||||
spi_flash_img = c.config.source_dir + '/' + filename
|
||||
|
||||
try:
|
||||
mkenvimage = os.path.join(c.config.build_dir, 'tools/mkenvimage')
|
||||
call('( echo foo=bar | %s -s 8192 -p 0x00 - ; dd if=/dev/zero bs=2088960 count=1 2>/dev/null ) > %s' % ( mkenvimage , spi_flash_img ), shell=True)
|
||||
except CalledProcessError:
|
||||
call('rm -f %s' % spi_flash_img, shell=True)
|
||||
raise
|
||||
|
||||
return spi_flash_img
|
||||
|
||||
@pytest.mark.boardspec('sandbox')
|
||||
@pytest.mark.buildconfigspec('cmd_echo')
|
||||
@pytest.mark.buildconfigspec('cmd_nvedit_info')
|
||||
@@ -544,6 +580,143 @@ def test_env_ext4(state_test_env):
|
||||
if fs_img:
|
||||
call('rm -f %s' % fs_img, shell=True)
|
||||
|
||||
@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_spi_flash')
|
||||
def test_env_spi_flash(state_test_env):
|
||||
|
||||
"""Test ENV in SPI NOR on sandbox."""
|
||||
c = state_test_env.ubman
|
||||
spi_flash_img = ''
|
||||
try:
|
||||
spi_flash_img = mk_env_spi_flash_single(state_test_env)
|
||||
|
||||
response = c.run_command('sf probe')
|
||||
assert 'SF: Detected m25p16 with page size 256 Bytes, erase size 64 KiB, total 2 MiB' in response
|
||||
|
||||
# force env location: SF
|
||||
response = c.run_command('env select SPIFlash')
|
||||
assert 'Select Environment on SPIFlash: OK' in response
|
||||
|
||||
response = c.run_command('env load')
|
||||
assert 'Loading Environment from SPIFlash... OK' in response
|
||||
|
||||
response = c.run_command('env print foo')
|
||||
assert 'foo=bar' in response
|
||||
|
||||
response = c.run_command('env save')
|
||||
assert 'Saving Environment to SPIFlash' in response
|
||||
|
||||
response = c.run_command('env load')
|
||||
assert 'Loading Environment from SPIFlash... OK' in response
|
||||
|
||||
response = c.run_command('env print foo')
|
||||
assert 'foo=bar' in response
|
||||
|
||||
response = c.run_command('env save')
|
||||
assert 'Saving Environment to SPIFlash' in response
|
||||
|
||||
response = c.run_command('env save')
|
||||
assert 'Saving Environment to SPIFlash' in response
|
||||
|
||||
response = c.run_command('env load')
|
||||
assert 'Loading Environment from SPIFlash... OK' in response
|
||||
|
||||
response = c.run_command('env print foo')
|
||||
assert 'foo=bar' 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 spi_flash_img:
|
||||
call('rm -f %s' % spi_flash_img, shell=True)
|
||||
|
||||
spi_flash_img = ''
|
||||
try:
|
||||
spi_flash_img = mk_env_spi_flash(state_test_env)
|
||||
|
||||
# force env location: SF
|
||||
response = c.run_command('env select SPIFlash')
|
||||
assert 'Select Environment on SPIFlash: OK' in response
|
||||
|
||||
response = c.run_command('env save')
|
||||
assert 'Saving Environment to SPIFlash' in response
|
||||
|
||||
response = c.run_command('env load')
|
||||
assert 'Loading Environment from SPIFlash... OK' 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 SPIFlash... ' 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 spi_flash_img:
|
||||
call('rm -f %s' % spi_flash_img, shell=True)
|
||||
|
||||
def test_env_text(ubman):
|
||||
"""Test the script that converts the environment to a text file"""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user