diff --git a/package/system/mtd/src/mtd.c b/package/system/mtd/src/mtd.c
index c5115a794cc9e0d1a4f6ea6354b0a69834d5a050..a8464947f3549c71564edbd2205a8401d00888a3 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 751b0d09f6c8339425c9e359609485801ccfd119..0a8b1ae0fd392f9d66af1581df199afdc511ee24 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 f310f51087e5f8eec99565e42a7cc3697fe7aec1..816f0eba5f0e88aba16952d10b1799cd97df0150 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);