diff --git a/package/system/mtd/src/mtd.c b/package/system/mtd/src/mtd.c index c5115a794c..a8464947f3 100644 --- a/package/system/mtd/src/mtd.c +++ b/package/system/mtd/src/mtd.c @@ -737,6 +737,8 @@ static void usage(void) if (mtd_fixtrx) { fprintf(stderr, " -o offset offset of the image header in the partition(for fixtrx)\n"); + fprintf(stderr, + " -c datasize amount of data to be used for checksum calculation (for fixtrx)\n"); } fprintf(stderr, #ifdef FIS_SUPPORT @@ -769,7 +771,7 @@ 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, dump_len = 0; + size_t offset = 0, data_size = 0, part_offset = 0, dump_len = 0; enum { CMD_ERASE, CMD_WRITE, @@ -793,7 +795,7 @@ int main (int argc, char **argv) #ifdef FIS_SUPPORT "F:" #endif - "frnqe:d:s:j:p:o:l:")) != -1) + "frnqe:d:s:j:p:o:c:l:")) != -1) switch (ch) { case 'f': force = 1; @@ -853,6 +855,14 @@ int main (int argc, char **argv) usage(); } break; + case 'c': + errno = 0; + data_size = strtoul(optarg, 0, 0); + if (errno) { + fprintf(stderr, "-d: illegal numeric string\n"); + usage(); + } + break; #ifdef FIS_SUPPORT case 'F': fis_layout = optarg; @@ -967,7 +977,7 @@ int main (int argc, char **argv) break; case CMD_FIXTRX: if (mtd_fixtrx) { - mtd_fixtrx(device, offset); + mtd_fixtrx(device, offset, data_size); } break; case CMD_RESETBC: diff --git a/package/system/mtd/src/mtd.h b/package/system/mtd/src/mtd.h index 751b0d09f6..0a8b1ae0fd 100644 --- a/package/system/mtd/src/mtd.h +++ b/package/system/mtd/src/mtd.h @@ -25,7 +25,7 @@ extern void mtd_parse_jffs2data(const char *buf, const char *dir); /* target specific functions */ extern int trx_fixup(int fd, const char *name) __attribute__ ((weak)); extern int trx_check(int imagefd, const char *mtd, char *buf, int *len) __attribute__ ((weak)); -extern int mtd_fixtrx(const char *mtd, size_t offset) __attribute__ ((weak)); +extern int mtd_fixtrx(const char *mtd, size_t offset, size_t data_size) __attribute__ ((weak)); extern int mtd_fixseama(const char *mtd, size_t offset) __attribute__ ((weak)); extern int mtd_resetbc(const char *mtd) __attribute__ ((weak)); #endif /* __mtd_h */ diff --git a/package/system/mtd/src/trx.c b/package/system/mtd/src/trx.c index f310f51087..816f0eba5f 100644 --- a/package/system/mtd/src/trx.c +++ b/package/system/mtd/src/trx.c @@ -36,6 +36,8 @@ #include "crc32.h" #define TRX_MAGIC 0x30524448 /* "HDR0" */ +#define TRX_CRC32_DATA_OFFSET 12 /* First 12 bytes are not covered by CRC32 */ +#define TRX_CRC32_DATA_SIZE 16 struct trx_header { uint32_t magic; /* "HDR0" */ uint32_t len; /* Length of file including header */ @@ -148,8 +150,9 @@ trx_check(int imagefd, const char *mtd, char *buf, int *len) #endif int -mtd_fixtrx(const char *mtd, size_t offset) +mtd_fixtrx(const char *mtd, size_t offset, size_t data_size) { + size_t data_offset; int fd; struct trx_header *trx; char *first_block; @@ -166,10 +169,16 @@ mtd_fixtrx(const char *mtd, size_t offset) exit(1); } + data_offset = offset + TRX_CRC32_DATA_OFFSET; + if (data_size) + data_size += TRX_CRC32_DATA_SIZE; + else + data_size = erasesize - TRX_CRC32_DATA_OFFSET; + block_offset = offset & ~(erasesize - 1); offset -= block_offset; - if (block_offset + erasesize > mtdsize) { + if (data_offset + data_size > mtdsize) { fprintf(stderr, "Offset too large, device size 0x%x\n", mtdsize); exit(1); } @@ -192,28 +201,28 @@ mtd_fixtrx(const char *mtd, size_t offset) exit(1); } - if (trx->len == STORE32_LE(erasesize - offset)) { + if (trx->len == STORE32_LE(data_size + TRX_CRC32_DATA_OFFSET)) { if (quiet < 2) fprintf(stderr, "Header already fixed, exiting\n"); close(fd); return 0; } - buf = malloc(erasesize); + buf = malloc(data_size); if (!buf) { perror("malloc"); exit(1); } - res = pread(fd, buf, erasesize, block_offset); - if (res != erasesize) { + res = pread(fd, buf, data_size, data_offset); + if (res != data_size) { perror("pread"); exit(1); } - trx->len = STORE32_LE(erasesize - offset); + trx->len = STORE32_LE(data_size + offsetof(struct trx_header, flag_version)); - trx->crc32 = STORE32_LE(crc32buf((char*) &trx->flag_version, erasesize - offset - 3*4)); + trx->crc32 = STORE32_LE(crc32buf(buf, data_size)); if (mtd_erase_block(fd, block_offset)) { fprintf(stderr, "Can't erease block at 0x%x (%s)\n", block_offset, strerror(errno)); exit(1);