X-Git-Url: http://git.openwrt.org/?p=openwrt%2Fsvn-archive%2Farchive.git;a=blobdiff_plain;f=package%2Fmtd%2Fsrc%2Fmtd.c;h=92873ca19b775eb84bb714d1cfc0e643b7ef78a4;hp=bd966ab7dca699a16aadcfdc61ab0fb88fdd427d;hb=9e72ea694e8cd195711d10d28af760100fa0b8e6;hpb=42949cc5ada341f43eae441f7d036adfa9455b5f diff --git a/package/mtd/src/mtd.c b/package/mtd/src/mtd.c index bd966ab7dc..92873ca19b 100644 --- a/package/mtd/src/mtd.c +++ b/package/mtd/src/mtd.c @@ -41,26 +41,23 @@ #include #include #include -#include "mtd-api.h" +#include #include "fis.h" #include "mtd.h" +#ifndef MTDREFRESH +#define MTDREFRESH _IO('M', 50) +#endif + #define MAX_ARGS 8 #define JFFS2_DEFAULT_DIR "" /* directory name without /, empty means root dir */ -struct trx_header { - uint32_t magic; /* "HDR0" */ - uint32_t len; /* Length of file including header */ - uint32_t crc32; /* 32-bit CRC from flag_version to end of file */ - uint32_t flag_version; /* 0:15 flags, 16:31 version */ - uint32_t offsets[3]; /* Offsets of partitions from start of header */ -}; - static char *buf = NULL; static char *imagefile = NULL; static char *jffs2file = NULL, *jffs2dir = JFFS2_DEFAULT_DIR; static int buflen = 0; int quiet; +int no_erase; int mtdsize = 0; int erasesize = 0; @@ -98,13 +95,13 @@ int mtd_check_open(const char *mtd) fd = mtd_open(mtd, false); if(fd < 0) { fprintf(stderr, "Could not open mtd device: %s\n", mtd); - return 0; + return -1; } if(ioctl(fd, MEMGETINFO, &mtdInfo)) { fprintf(stderr, "Could not get MTD device info from %s\n", mtd); close(fd); - return 0; + return -1; } mtdsize = mtdInfo.size; erasesize = mtdInfo.erasesize; @@ -137,9 +134,9 @@ static int image_check(int imagefd, const char *mtd) { int ret = 1; -#ifdef target_brcm - ret = trx_check(imagefd, mtd, buf, &buflen); -#endif + if (trx_check) { + ret = trx_check(imagefd, mtd, buf, &buflen); + } return ret; } @@ -162,7 +159,7 @@ static int mtd_check(const char *mtd) } fd = mtd_check_open(mtd); - if (!fd) + if (fd < 0) return 0; if (!buf) @@ -199,7 +196,7 @@ mtd_unlock(const char *mtd) } fd = mtd_check_open(mtd); - if(fd <= 0) { + if(fd < 0) { fprintf(stderr, "Could not open mtd device: %s\n", mtd); exit(1); } @@ -230,7 +227,7 @@ mtd_erase(const char *mtd) fprintf(stderr, "Erasing %s ...\n", mtd); fd = mtd_check_open(mtd); - if(fd <= 0) { + if(fd < 0) { fprintf(stderr, "Could not open mtd device: %s\n", mtd); exit(1); } @@ -260,7 +257,7 @@ mtd_refresh(const char *mtd) fprintf(stderr, "Refreshing mtd partition %s ... ", mtd); fd = mtd_check_open(mtd); - if(fd <= 0) { + if(fd < 0) { fprintf(stderr, "Could not open mtd device: %s\n", mtd); exit(1); } @@ -278,13 +275,24 @@ mtd_refresh(const char *mtd) return 0; } +static void +indicate_writing(const char *mtd) +{ + if (quiet < 2) + fprintf(stderr, "\nWriting from %s to %s ... ", imagefile, mtd); + + if (!quiet) + fprintf(stderr, " [ ]"); +} + static int -mtd_write(int imagefd, const char *mtd, char *fis_layout) +mtd_write(int imagefd, const char *mtd, char *fis_layout, size_t part_offset) { char *next = NULL; char *str = NULL; int fd, result; ssize_t r, w, e; + ssize_t skip = 0; uint32_t offset = 0; #ifdef FIS_SUPPORT @@ -362,13 +370,14 @@ resume: exit(1); } - if (quiet < 2) - fprintf(stderr, "Writing from %s to %s ... ", imagefile, mtd); + if (part_offset > 0) { + fprintf(stderr, "Seeking on mtd device '%s' to: %u\n", mtd, part_offset); + lseek(fd, part_offset, SEEK_SET); + } - w = e = 0; - if (!quiet) - fprintf(stderr, " [ ]"); + indicate_writing(mtd); + w = e = 0; for (;;) { /* buffer may contain data already (from trx check or last mtd partition write attempt) */ while (buflen < erasesize) { @@ -391,15 +400,33 @@ resume: if (buflen == 0) break; + if (skip > 0) { + skip -= buflen; + buflen = 0; + if (skip <= 0) + indicate_writing(mtd); + + continue; + } + if (jffs2file) { if (memcmp(buf, JFFS2_EOF, sizeof(JFFS2_EOF) - 1) == 0) { if (!quiet) fprintf(stderr, "\b\b\b "); if (quiet < 2) - fprintf(stderr, "\nAppending jffs2 data to from %s to %s...", jffs2file, mtd); + fprintf(stderr, "\nAppending jffs2 data from %s to %s...", jffs2file, mtd); /* got an EOF marker - this is the place to add some jffs2 data */ - mtd_replace_jffs2(mtd, fd, e, jffs2file); - goto done; + skip = mtd_replace_jffs2(mtd, fd, e, jffs2file); + + /* don't add it again */ + jffs2file = NULL; + + w += skip; + e += skip; + skip -= buflen; + buflen = 0; + offset = 0; + continue; } /* no EOF marker, make sure we figure out the last inode number * before appending some data */ @@ -407,31 +434,34 @@ resume: } /* need to erase the next block before writing data to it */ - while (w + buflen > e) { - if (!quiet) - fprintf(stderr, "\b\b\b[e]"); - - - if (mtd_erase_block(fd, e) < 0) { - if (next) { - if (w < e) { - write(fd, buf + offset, e - w); - offset = e - w; + if(!no_erase) + { + while (w + buflen > e) { + if (!quiet) + fprintf(stderr, "\b\b\b[e]"); + + + if (mtd_erase_block(fd, e) < 0) { + if (next) { + if (w < e) { + write(fd, buf + offset, e - w); + offset = e - w; + } + w = 0; + e = 0; + close(fd); + mtd = next; + fprintf(stderr, "\b\b\b \n"); + goto resume; + } else { + fprintf(stderr, "Failed to erase block\n"); + exit(1); } - w = 0; - e = 0; - close(fd); - mtd = next; - fprintf(stderr, "\b\b\b \n"); - goto resume; - } else { - fprintf(stderr, "Failed to erase block\n"); - exit(1); } - } - /* erase the chunk */ - e += erasesize; + /* erase the chunk */ + e += erasesize; + } } if (!quiet) @@ -479,15 +509,27 @@ static void usage(void) " refresh refresh mtd partition\n" " erase erase all data on device\n" " write |- write (use - for stdin) to device\n" - " jffs2write append to the jffs2 partition on the device\n" + " jffs2write append to the jffs2 partition on the device\n"); + if (mtd_fixtrx) { + fprintf(stderr, + " fixtrx fix the checksum in a trx header on first boot\n"); + } + fprintf(stderr, "Following options are available:\n" " -q quiet mode (once: no [w] on writing,\n" " twice: no status messages)\n" + " -n write without first erasing the blocks\n" " -r reboot after successful command\n" " -f force write without trx checks\n" " -e erase before executing the command\n" " -d directory for jffs2write, defaults to \"tmp\"\n" " -j integrate into jffs2 data when writing an image\n" + " -p write beginning at partition offset\n"); + if (mtd_fixtrx) { + fprintf(stderr, + " -o offset offset of the image header in the partition(for fixtrx)\n"); + } + fprintf(stderr, #ifdef FIS_SUPPORT " -F [:[:]][,...]\n" " alter the fis partition table to create new partitions replacing\n" @@ -518,12 +560,14 @@ int main (int argc, char **argv) int ch, i, boot, imagefd = 0, force, unlocked; char *erase[MAX_ARGS], *device = NULL; char *fis_layout = NULL; + size_t offset = 0, part_offset = 0; enum { CMD_ERASE, CMD_WRITE, CMD_UNLOCK, CMD_REFRESH, - CMD_JFFS2WRITE + CMD_JFFS2WRITE, + CMD_FIXTRX, } cmd = -1; erase[0] = NULL; @@ -531,12 +575,13 @@ int main (int argc, char **argv) force = 0; buflen = 0; quiet = 0; + no_erase = 0; while ((ch = getopt(argc, argv, #ifdef FIS_SUPPORT "F:" #endif - "frqe:d:j:")) != -1) + "frnqe:d:j:p:o:")) != -1) switch (ch) { case 'f': force = 1; @@ -544,6 +589,9 @@ int main (int argc, char **argv) case 'r': boot = 1; break; + case 'n': + no_erase = 1; + break; case 'j': jffs2file = optarg; break; @@ -561,6 +609,26 @@ int main (int argc, char **argv) case 'd': jffs2dir = optarg; break; + case 'p': + errno = 0; + part_offset = strtoul(optarg, 0, 0); + if (errno) { + fprintf(stderr, "-p: illegal numeric string\n"); + usage(); + } + break; + case 'o': + if (!mtd_fixtrx) { + fprintf(stderr, "-o: is not available on this platform\n"); + usage(); + } + errno = 0; + offset = strtoul(optarg, 0, 0); + if (errno) { + fprintf(stderr, "-o: illegal numeric string\n"); + usage(); + } + break; #ifdef FIS_SUPPORT case 'F': fis_layout = optarg; @@ -585,6 +653,9 @@ int main (int argc, char **argv) } else if ((strcmp(argv[0], "erase") == 0) && (argc == 2)) { cmd = CMD_ERASE; device = argv[1]; + } else if (((strcmp(argv[0], "fixtrx") == 0) && (argc == 2)) && mtd_fixtrx) { + cmd = CMD_FIXTRX; + device = argv[1]; } else if ((strcmp(argv[0], "write") == 0) && (argc == 3)) { cmd = CMD_WRITE; device = argv[2]; @@ -647,7 +718,7 @@ int main (int argc, char **argv) case CMD_WRITE: if (!unlocked) mtd_unlock(device); - mtd_write(imagefd, device, fis_layout); + mtd_write(imagefd, device, fis_layout, part_offset); break; case CMD_JFFS2WRITE: if (!unlocked) @@ -657,6 +728,11 @@ int main (int argc, char **argv) case CMD_REFRESH: mtd_refresh(device); break; + case CMD_FIXTRX: + if (mtd_fixtrx) { + mtd_fixtrx(device, offset); + } + break; } sync();