Newer
Older
if (HaveRedundEnv) {
/* switch to next partition for writing */
dev_target = !dev_current;
/* dev_target: fd_target, erase_target */
fd_target = open (DEVNAME (dev_target), mode);
if (fd_target < 0) {
fprintf (stderr,
"Can't open %s: %s\n",
DEVNAME (dev_target),
strerror (errno));
rc = -1;
goto exit;
} else {
dev_target = dev_current;
fd_target = fd_current;
rc = flash_write (fd_current, fd_target, dev_target);
if (HaveRedundEnv) {
fprintf (stderr,
}
} else {
fprintf (stderr,
"I/O error on %s: %s\n",
DEVNAME (dev_current), strerror (errno));
return -1;
}
/*
* s1 is either a simple 'name', or a 'name=value' pair.
* s2 is a 'name=value' pair.
* If the names match, return the value of s2, else NULL.
*/
static char *envmatch (char * s1, char * s2)
if (s1 == NULL || s2 == NULL)
return NULL;
while (*s1 == *s2++)
if (*s1++ == '=')
if (*s1 == '\0' && *(s2 - 1) == '=')
}
/*
* Prevent confusion if running from erased flash memory
*/
int fw_env_open(void)
int crc1, crc1_ok;
struct env_image_single *single;
struct env_image_redundant *redundant;
if (parse_config ()) /* should fill envdevices */
addr0 = calloc(1, CUR_ENVSIZE);
"Not enough memory for environment (%ld bytes)\n",
/* read environment from FLASH to local buffer */
environment.image = addr0;
if (HaveRedundEnv) {
redundant = addr0;
environment.crc = &redundant->crc;
environment.flags = &redundant->flags;
environment.data = redundant->data;
} else {
single = addr0;
environment.crc = &single->crc;
environment.flags = NULL;
environment.data = single->data;
dev_current = 0;
if (flash_io (O_RDONLY))
return -1;
crc0 = crc32 (0, (uint8_t *) environment.data, ENV_SIZE);
crc0_ok = (crc0 == *environment.crc);
if (!HaveRedundEnv) {
fprintf (stderr,
"Warning: Bad CRC, using default environment\n");
memcpy(environment.data, default_environment, sizeof default_environment);
addr1 = calloc(1, CUR_ENVSIZE);
"Not enough memory for environment (%ld bytes)\n",
/*
* have to set environment.image for flash_read(), careful -
* other pointers in environment still point inside addr0
*/
environment.image = addr1;
if (flash_io (O_RDONLY))
return -1;
/* Check flag scheme compatibility */
if (DEVTYPE(dev_current) == MTD_NORFLASH &&
DEVTYPE(!dev_current) == MTD_NORFLASH) {
environment.flag_scheme = FLAG_BOOLEAN;
} else if (DEVTYPE(dev_current) == MTD_NANDFLASH &&
DEVTYPE(!dev_current) == MTD_NANDFLASH) {
environment.flag_scheme = FLAG_INCREMENTAL;
} else if (DEVTYPE(dev_current) == MTD_DATAFLASH &&
DEVTYPE(!dev_current) == MTD_DATAFLASH) {
environment.flag_scheme = FLAG_BOOLEAN;
} else if (DEVTYPE(dev_current) == MTD_UBIVOLUME &&
DEVTYPE(!dev_current) == MTD_UBIVOLUME) {
environment.flag_scheme = FLAG_INCREMENTAL;
} else if (DEVTYPE(dev_current) == MTD_ABSENT &&
DEVTYPE(!dev_current) == MTD_ABSENT) {
environment.flag_scheme = FLAG_INCREMENTAL;
} else {
fprintf (stderr, "Incompatible flash types!\n");
return -1;
crc1 = crc32 (0, (uint8_t *) redundant->data, ENV_SIZE);
crc1_ok = (crc1 == redundant->crc);
flag1 = redundant->flags;
if (crc0_ok && !crc1_ok) {
dev_current = 0;
} else if (!crc0_ok && crc1_ok) {
dev_current = 1;
} else if (!crc0_ok && !crc1_ok) {
fprintf (stderr,
"Warning: Bad CRC, using default environment\n");
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
memcpy (environment.data, default_environment,
sizeof default_environment);
dev_current = 0;
} else {
switch (environment.flag_scheme) {
case FLAG_BOOLEAN:
if (flag0 == active_flag &&
flag1 == obsolete_flag) {
dev_current = 0;
} else if (flag0 == obsolete_flag &&
flag1 == active_flag) {
dev_current = 1;
} else if (flag0 == flag1) {
dev_current = 0;
} else if (flag0 == 0xFF) {
dev_current = 0;
} else if (flag1 == 0xFF) {
dev_current = 1;
} else {
dev_current = 0;
}
break;
case FLAG_INCREMENTAL:
if (flag0 == 255 && flag1 == 0)
dev_current = 1;
else if ((flag1 == 255 && flag0 == 0) ||
else /* flag1 > flag0 */
dev_current = 1;
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
break;
default:
fprintf (stderr, "Unknown flag scheme %u \n",
environment.flag_scheme);
return -1;
}
}
/*
* If we are reading, we don't need the flag and the CRC any
* more, if we are writing, we will re-calculate CRC and update
* flags before writing out
*/
if (dev_current) {
environment.image = addr1;
environment.crc = &redundant->crc;
environment.flags = &redundant->flags;
environment.data = redundant->data;
free (addr0);
} else {
environment.image = addr0;
/* Other pointers are already set */
#ifdef DEBUG
fprintf(stderr, "Selected env in %s\n", DEVNAME(dev_current));
#endif
{
struct stat st;
#if defined(CONFIG_FILE)
/* Fills in DEVNAME(), ENVSIZE(), DEVESIZE(). Or don't. */
fprintf (stderr,
"Cannot parse config file: %s\n", strerror (errno));
strcpy (DEVNAME (0), DEVICE1_NAME);
DEVOFFSET (0) = DEVICE1_OFFSET;
ENVSIZE (0) = ENV1_SIZE;
/* Default values are: erase-size=env-size, #sectors=1 */
DEVESIZE (0) = ENVSIZE (0);
ENVSECTORS (0) = 1;
#ifdef DEVICE1_ESIZE
#endif
#ifdef DEVICE1_ENVSECTORS
#endif
#ifdef HAVE_REDUND
strcpy (DEVNAME (1), DEVICE2_NAME);
DEVOFFSET (1) = DEVICE2_OFFSET;
ENVSIZE (1) = ENV2_SIZE;
/* Default values are: erase-size=env-size, #sectors=1 */
DEVESIZE (1) = ENVSIZE (1);
ENVSECTORS (1) = 1;
#ifdef DEVICE2_ESIZE
#endif
#ifdef DEVICE2_ENVSECTORS
HaveRedundEnv = 1;
if (stat (DEVNAME (0), &st)) {
fprintf (stderr,
"Cannot access MTD device %s: %s\n",
DEVNAME (0), strerror (errno));
if (HaveRedundEnv && stat (DEVNAME (1), &st)) {
fprintf (stderr,
"Cannot access MTD device %s: %s\n",
DEVNAME (1), strerror (errno));
return 0;
}
#if defined(CONFIG_FILE)
static int get_config (char *fname)
{
FILE *fp;
int i = 0;
int rc;
char dump[128];
fp = fopen (fname, "r");
if (fp == NULL)
return -1;
while (i < 2 && fgets (dump, sizeof (dump), fp)) {
/* Skip incomplete conversions and comment strings */
rc = sscanf (dump, "%s %lx %lx %lx %lx",
DEVNAME (i),
&DEVOFFSET (i),
&ENVSIZE (i),
&DEVESIZE (i),
&ENVSECTORS (i));
if (rc < 3)
if (rc < 4)
/* Assume the erase size is the same as the env-size */
DEVESIZE(i) = ENVSIZE(i);
if (rc < 5)
/* Default - 1 sector */
ENVSECTORS (i) = 1;
i++;
}
HaveRedundEnv = i - 1;
if (!i) { /* No valid entries found */
} else
return 0;
}
#endif