mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-18 21:21:37 +00:00
env: Add redundant env support to UBI env
Allow the user to specify two UBI volumes to use for the environment Signed-off-by: Joe Hershberger <joe.hershberger@ni.com>
This commit is contained in:
parent
2b74433f36
commit
785881f775
4 changed files with 129 additions and 0 deletions
6
README
6
README
|
@ -3563,6 +3563,12 @@ but it can not erase, write this NOR flash by SRIO or PCIE interface.
|
||||||
Define this to the name of the volume that you want to store the
|
Define this to the name of the volume that you want to store the
|
||||||
environment in.
|
environment in.
|
||||||
|
|
||||||
|
- CONFIG_ENV_UBI_VOLUME_REDUND:
|
||||||
|
|
||||||
|
Define this to the name of another volume to store a second copy of
|
||||||
|
the environment in. This will enable redundant environments in UBI.
|
||||||
|
It is assumed that both volumes are in the same MTD partition.
|
||||||
|
|
||||||
- CONFIG_UBI_SILENCE_MSG
|
- CONFIG_UBI_SILENCE_MSG
|
||||||
- CONFIG_UBIFS_SILENCE_MSG
|
- CONFIG_UBIFS_SILENCE_MSG
|
||||||
|
|
||||||
|
|
117
common/env_ubi.c
117
common/env_ubi.c
|
@ -47,6 +47,58 @@ int env_init(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_CMD_SAVEENV
|
#ifdef CONFIG_CMD_SAVEENV
|
||||||
|
#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
|
||||||
|
static unsigned char env_flags;
|
||||||
|
|
||||||
|
int saveenv(void)
|
||||||
|
{
|
||||||
|
ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
|
||||||
|
ssize_t len;
|
||||||
|
char *res;
|
||||||
|
|
||||||
|
res = (char *)&env_new->data;
|
||||||
|
len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
|
||||||
|
if (len < 0) {
|
||||||
|
error("Cannot export environment: errno = %d\n", errno);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) {
|
||||||
|
printf("\n** Cannot find mtd partition \"%s\"\n",
|
||||||
|
CONFIG_ENV_UBI_PART);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
env_new->crc = crc32(0, env_new->data, ENV_SIZE);
|
||||||
|
env_new->flags = ++env_flags; /* increase the serial */
|
||||||
|
|
||||||
|
if (gd->env_valid == 1) {
|
||||||
|
puts("Writing to redundant UBI... ");
|
||||||
|
if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME_REDUND,
|
||||||
|
(void *)env_new, CONFIG_ENV_SIZE)) {
|
||||||
|
printf("\n** Unable to write env to %s:%s **\n",
|
||||||
|
CONFIG_ENV_UBI_PART,
|
||||||
|
CONFIG_ENV_UBI_VOLUME_REDUND);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
puts("Writing to UBI... ");
|
||||||
|
if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME,
|
||||||
|
(void *)env_new, CONFIG_ENV_SIZE)) {
|
||||||
|
printf("\n** Unable to write env to %s:%s **\n",
|
||||||
|
CONFIG_ENV_UBI_PART,
|
||||||
|
CONFIG_ENV_UBI_VOLUME);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
puts("done\n");
|
||||||
|
|
||||||
|
gd->env_valid = gd->env_valid == 2 ? 1 : 2;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#else /* ! CONFIG_SYS_REDUNDAND_ENVIRONMENT */
|
||||||
int saveenv(void)
|
int saveenv(void)
|
||||||
{
|
{
|
||||||
ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
|
ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
|
||||||
|
@ -78,8 +130,72 @@ int saveenv(void)
|
||||||
puts("done\n");
|
puts("done\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */
|
||||||
#endif /* CONFIG_CMD_SAVEENV */
|
#endif /* CONFIG_CMD_SAVEENV */
|
||||||
|
|
||||||
|
#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
|
||||||
|
void env_relocate_spec(void)
|
||||||
|
{
|
||||||
|
ALLOC_CACHE_ALIGN_BUFFER(char, env1_buf, CONFIG_ENV_SIZE);
|
||||||
|
ALLOC_CACHE_ALIGN_BUFFER(char, env2_buf, CONFIG_ENV_SIZE);
|
||||||
|
int crc1_ok = 0, crc2_ok = 0;
|
||||||
|
env_t *ep, *tmp_env1, *tmp_env2;
|
||||||
|
|
||||||
|
tmp_env1 = (env_t *)env1_buf;
|
||||||
|
tmp_env2 = (env_t *)env2_buf;
|
||||||
|
|
||||||
|
if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) {
|
||||||
|
printf("\n** Cannot find mtd partition \"%s\"\n",
|
||||||
|
CONFIG_ENV_UBI_PART);
|
||||||
|
set_default_env(NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME, (void *)tmp_env1,
|
||||||
|
CONFIG_ENV_SIZE)) {
|
||||||
|
printf("\n** Unable to read env from %s:%s **\n",
|
||||||
|
CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME_REDUND, (void *)tmp_env2,
|
||||||
|
CONFIG_ENV_SIZE)) {
|
||||||
|
printf("\n** Unable to read redundant env from %s:%s **\n",
|
||||||
|
CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME_REDUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
crc1_ok = crc32(0, tmp_env1->data, ENV_SIZE) == tmp_env1->crc;
|
||||||
|
crc2_ok = crc32(0, tmp_env2->data, ENV_SIZE) == tmp_env2->crc;
|
||||||
|
|
||||||
|
if (!crc1_ok && !crc2_ok) {
|
||||||
|
set_default_env("!bad CRC");
|
||||||
|
return;
|
||||||
|
} else if (crc1_ok && !crc2_ok) {
|
||||||
|
gd->env_valid = 1;
|
||||||
|
} else if (!crc1_ok && crc2_ok) {
|
||||||
|
gd->env_valid = 2;
|
||||||
|
} else {
|
||||||
|
/* both ok - check serial */
|
||||||
|
if (tmp_env1->flags == 255 && tmp_env2->flags == 0)
|
||||||
|
gd->env_valid = 2;
|
||||||
|
else if (tmp_env2->flags == 255 && tmp_env1->flags == 0)
|
||||||
|
gd->env_valid = 1;
|
||||||
|
else if (tmp_env1->flags > tmp_env2->flags)
|
||||||
|
gd->env_valid = 1;
|
||||||
|
else if (tmp_env2->flags > tmp_env1->flags)
|
||||||
|
gd->env_valid = 2;
|
||||||
|
else /* flags are equal - almost impossible */
|
||||||
|
gd->env_valid = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gd->env_valid == 1)
|
||||||
|
ep = tmp_env1;
|
||||||
|
else
|
||||||
|
ep = tmp_env2;
|
||||||
|
|
||||||
|
env_flags = ep->flags;
|
||||||
|
env_import((char *)ep, 0);
|
||||||
|
}
|
||||||
|
#else /* ! CONFIG_SYS_REDUNDAND_ENVIRONMENT */
|
||||||
void env_relocate_spec(void)
|
void env_relocate_spec(void)
|
||||||
{
|
{
|
||||||
ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE);
|
ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE);
|
||||||
|
@ -101,3 +217,4 @@ void env_relocate_spec(void)
|
||||||
|
|
||||||
env_import(buf, 1);
|
env_import(buf, 1);
|
||||||
}
|
}
|
||||||
|
#endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */
|
||||||
|
|
|
@ -103,6 +103,9 @@ extern unsigned long nand_env_oob_offset;
|
||||||
# ifndef CONFIG_ENV_UBI_VOLUME
|
# ifndef CONFIG_ENV_UBI_VOLUME
|
||||||
# error "Need to define CONFIG_ENV_UBI_VOLUME when using CONFIG_ENV_IS_IN_UBI"
|
# error "Need to define CONFIG_ENV_UBI_VOLUME when using CONFIG_ENV_IS_IN_UBI"
|
||||||
# endif
|
# endif
|
||||||
|
# if defined(CONFIG_ENV_UBI_VOLUME_REDUND)
|
||||||
|
# define CONFIG_SYS_REDUNDAND_ENVIRONMENT
|
||||||
|
# endif
|
||||||
# ifndef CONFIG_ENV_SIZE
|
# ifndef CONFIG_ENV_SIZE
|
||||||
# error "Need to define CONFIG_ENV_SIZE when using CONFIG_ENV_IS_IN_UBI"
|
# error "Need to define CONFIG_ENV_SIZE when using CONFIG_ENV_IS_IN_UBI"
|
||||||
# endif
|
# endif
|
||||||
|
|
3
tools/env/fw_env.c
vendored
3
tools/env/fw_env.c
vendored
|
@ -1149,6 +1149,9 @@ int fw_env_open(void)
|
||||||
} else if (DEVTYPE(dev_current) == MTD_DATAFLASH &&
|
} else if (DEVTYPE(dev_current) == MTD_DATAFLASH &&
|
||||||
DEVTYPE(!dev_current) == MTD_DATAFLASH) {
|
DEVTYPE(!dev_current) == MTD_DATAFLASH) {
|
||||||
environment.flag_scheme = FLAG_BOOLEAN;
|
environment.flag_scheme = FLAG_BOOLEAN;
|
||||||
|
} else if (DEVTYPE(dev_current) == MTD_UBIVOLUME &&
|
||||||
|
DEVTYPE(!dev_current) == MTD_UBIVOLUME) {
|
||||||
|
environment.flag_scheme = FLAG_INCREMENTAL;
|
||||||
} else {
|
} else {
|
||||||
fprintf (stderr, "Incompatible flash types!\n");
|
fprintf (stderr, "Incompatible flash types!\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
|
Loading…
Add table
Reference in a new issue