1
0
Fork 0

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>
utp
Joe Hershberger 2013-04-08 10:32:52 +00:00 committed by Tom Rini
parent 2b74433f36
commit 785881f775
4 changed files with 129 additions and 0 deletions

6
README
View File

@ -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

View File

@ -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 */

View File

@ -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
View File

@ -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;