aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--package/system/mtd/src/mtd.c16
-rw-r--r--package/system/mtd/src/mtd.h2
-rw-r--r--package/system/mtd/src/trx.c25
3 files changed, 31 insertions, 12 deletions
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);