📄 fw_env.c
字号:
{ int fd, fdr, rc, otherdev, len, resid; erase_info_t erase; char *data; if ((fd = open (DEVNAME (curdev), mode)) < 0) { fprintf (stderr, "Can't open %s: %s\n", DEVNAME (curdev), strerror (errno)); return (-1); } len = sizeof (environment.crc); if (HaveRedundEnv) { len += sizeof (environment.flags); } if (mode == O_RDWR) { if (HaveRedundEnv) { /* switch to next partition for writing */ otherdev = !curdev; if ((fdr = open (DEVNAME (otherdev), mode)) < 0) { fprintf (stderr, "Can't open %s: %s\n", DEVNAME (otherdev), strerror (errno)); return (-1); } } else { otherdev = curdev; fdr = fd; } printf ("Unlocking flash...\n"); erase.length = DEVESIZE (otherdev); erase.start = DEVOFFSET (otherdev); ioctl (fdr, MEMUNLOCK, &erase); if (HaveRedundEnv) { erase.length = DEVESIZE (curdev); erase.start = DEVOFFSET (curdev); ioctl (fd, MEMUNLOCK, &erase); environment.flags = active_flag; } printf ("Done\n"); resid = DEVESIZE (otherdev) - CFG_ENV_SIZE; if (resid) { if ((data = malloc (resid)) == NULL) { fprintf (stderr, "Cannot malloc %d bytes: %s\n", resid, strerror (errno)); return (-1); } if (lseek (fdr, DEVOFFSET (otherdev) + CFG_ENV_SIZE, SEEK_SET) == -1) { fprintf (stderr, "seek error on %s: %s\n", DEVNAME (otherdev), strerror (errno)); return (-1); } if ((rc = read (fdr, data, resid)) != resid) { fprintf (stderr, "read error on %s: %s\n", DEVNAME (otherdev), strerror (errno)); return (-1); } } printf ("Erasing old environment...\n"); erase.length = DEVESIZE (otherdev); erase.start = DEVOFFSET (otherdev); if (ioctl (fdr, MEMERASE, &erase) != 0) { fprintf (stderr, "MTD erase error on %s: %s\n", DEVNAME (otherdev), strerror (errno)); return (-1); } printf ("Done\n"); printf ("Writing environment to %s...\n", DEVNAME (otherdev)); if (lseek (fdr, DEVOFFSET (otherdev), SEEK_SET) == -1) { fprintf (stderr, "seek error on %s: %s\n", DEVNAME (otherdev), strerror (errno)); return (-1); } if (write (fdr, &environment, len) != len) { fprintf (stderr, "CRC write error on %s: %s\n", DEVNAME (otherdev), strerror (errno)); return (-1); } if (write (fdr, environment.data, ENV_SIZE) != ENV_SIZE) { fprintf (stderr, "Write error on %s: %s\n", DEVNAME (otherdev), strerror (errno)); return (-1); } if (resid) { if (write (fdr, data, resid) != resid) { fprintf (stderr, "write error on %s: %s\n", DEVNAME (curdev), strerror (errno)); return (-1); } free (data); } if (HaveRedundEnv) { /* change flag on current active env partition */ if (lseek (fd, DEVOFFSET (curdev) + sizeof (ulong), SEEK_SET) == -1) { fprintf (stderr, "seek error on %s: %s\n", DEVNAME (curdev), strerror (errno)); return (-1); } if (write (fd, &obsolete_flag, sizeof (obsolete_flag)) != sizeof (obsolete_flag)) { fprintf (stderr, "Write error on %s: %s\n", DEVNAME (curdev), strerror (errno)); return (-1); } } printf ("Done\n"); printf ("Locking ...\n"); erase.length = DEVESIZE (otherdev); erase.start = DEVOFFSET (otherdev); ioctl (fdr, MEMLOCK, &erase); if (HaveRedundEnv) { erase.length = DEVESIZE (curdev); erase.start = DEVOFFSET (curdev); ioctl (fd, MEMLOCK, &erase); if (close (fdr)) { fprintf (stderr, "I/O error on %s: %s\n", DEVNAME (otherdev), strerror (errno)); return (-1); } } printf ("Done\n"); } else { if (lseek (fd, DEVOFFSET (curdev), SEEK_SET) == -1) { fprintf (stderr, "seek error on %s: %s\n", DEVNAME (curdev), strerror (errno)); return (-1); } if (read (fd, &environment, len) != len) { fprintf (stderr, "CRC read error on %s: %s\n", DEVNAME (curdev), strerror (errno)); return (-1); } if ((rc = read (fd, environment.data, ENV_SIZE)) != ENV_SIZE) { fprintf (stderr, "Read error on %s: %s\n", DEVNAME (curdev), strerror (errno)); return (-1); } } if (close (fd)) { fprintf (stderr, "I/O error on %s: %s\n", DEVNAME (curdev), strerror (errno)); return (-1); } /* everything ok */ return (0);}/* * 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 uchar *envmatch (uchar * s1, uchar * s2){ while (*s1 == *s2++) if (*s1++ == '=') return (s2); if (*s1 == '\0' && *(s2 - 1) == '=') return (s2); return (NULL);}/* * Prevent confusion if running from erased flash memory */static int env_init (void){ int crc1, crc1_ok; uchar *addr1; int crc2, crc2_ok; uchar flag1, flag2, *addr2; if (parse_config ()) /* should fill envdevices */ return 1; if ((addr1 = calloc (1, ENV_SIZE)) == NULL) { fprintf (stderr, "Not enough memory for environment (%ld bytes)\n", ENV_SIZE); return (errno); } /* read environment from FLASH to local buffer */ environment.data = addr1; curdev = 0; if (flash_io (O_RDONLY)) { return (errno); } crc1_ok = ((crc1 = crc32 (0, environment.data, ENV_SIZE)) == environment.crc); if (!HaveRedundEnv) { if (!crc1_ok) { fprintf (stderr, "Warning: Bad CRC, using default environment\n"); environment.data = default_environment; free (addr1); } } else { flag1 = environment.flags; curdev = 1; if ((addr2 = calloc (1, ENV_SIZE)) == NULL) { fprintf (stderr, "Not enough memory for environment (%ld bytes)\n", ENV_SIZE); return (errno); } environment.data = addr2; if (flash_io (O_RDONLY)) { return (errno); } crc2_ok = ((crc2 = crc32 (0, environment.data, ENV_SIZE)) == environment.crc); flag2 = environment.flags; if (crc1_ok && !crc2_ok) { environment.data = addr1; environment.flags = flag1; environment.crc = crc1; curdev = 0; free (addr2); } else if (!crc1_ok && crc2_ok) { environment.data = addr2; environment.flags = flag2; environment.crc = crc2; curdev = 1; free (addr1); } else if (!crc1_ok && !crc2_ok) { fprintf (stderr, "Warning: Bad CRC, using default environment\n"); environment.data = default_environment; curdev = 0; free (addr2); free (addr1); } else if (flag1 == active_flag && flag2 == obsolete_flag) { environment.data = addr1; environment.flags = flag1; environment.crc = crc1; curdev = 0; free (addr2); } else if (flag1 == obsolete_flag && flag2 == active_flag) { environment.data = addr2; environment.flags = flag2; environment.crc = crc2; curdev = 1; free (addr1); } else if (flag1 == flag2) { environment.data = addr1; environment.flags = flag1; environment.crc = crc1; curdev = 0; free (addr2); } else if (flag1 == 0xFF) { environment.data = addr1; environment.flags = flag1; environment.crc = crc1; curdev = 0; free (addr2); } else if (flag2 == 0xFF) { environment.data = addr2; environment.flags = flag2; environment.crc = crc2; curdev = 1; free (addr1); } } return (0);}static int parse_config (){ struct stat st;#if defined(CONFIG_FILE) /* Fills in DEVNAME(), ENVSIZE(), DEVESIZE(). Or don't. */ if (get_config (CONFIG_FILE)) { fprintf (stderr, "Cannot parse config file: %s\n", strerror (errno)); return 1; }#else strcpy (DEVNAME (0), DEVICE1_NAME); DEVOFFSET (0) = DEVICE1_OFFSET; ENVSIZE (0) = ENV1_SIZE; DEVESIZE (0) = DEVICE1_ESIZE;#ifdef HAVE_REDUND strcpy (DEVNAME (1), DEVICE2_NAME); DEVOFFSET (1) = DEVICE2_OFFSET; ENVSIZE (1) = ENV2_SIZE; DEVESIZE (1) = DEVICE2_ESIZE; HaveRedundEnv = 1;#endif#endif if (stat (DEVNAME (0), &st)) { fprintf (stderr, "Cannot access MTD device %s: %s\n", DEVNAME (0), strerror (errno)); return 1; } if (HaveRedundEnv && stat (DEVNAME (1), &st)) { fprintf (stderr, "Cannot access MTD device %s: %s\n", DEVNAME (2), strerror (errno)); return 1; } return 0;}#if defined(CONFIG_FILE)static int get_config (char *fname){ FILE *fp; int i = 0; int rc; char dump[128]; if ((fp = fopen (fname, "r")) == NULL) { return 1; } while ((i < 2) && ((rc = fscanf (fp, "%s %lx %lx %lx", DEVNAME (i), &DEVOFFSET (i), &ENVSIZE (i), &DEVESIZE (i) )) != EOF)) { /* Skip incomplete conversions and comment strings */ if ((rc < 3) || (*DEVNAME (i) == '#')) { fgets (dump, sizeof (dump), fp); /* Consume till end */ continue; } i++; } fclose (fp); HaveRedundEnv = i - 1; if (!i) { /* No valid entries found */ errno = EINVAL; return 1; } else return 0;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -