diff mbox

[OpenWrt-Devel] mtd: add -c option for specifying amount of data to be used for checksum

Message ID 1462539013-18188-1-git-send-email-zajec5@gmail.com
State Accepted
Headers show

Commit Message

Rafał Miłecki May 6, 2016, 12:50 p.m. UTC
So far fixtrx was calculating checksum over amount of data matching
partition erase size. It was mostly a workaround of checksum problem
after changing anything in initial TRX content (e.g. formatting JFFS2).
Its main purpose was to make bootloader accept modified TRX. This didn't
provide much protection of flash data against corruption.

This new option lets caller request calculating checksum over a bigger
amount of data. It may be used e.g. to include whole kernel data for
checksum and hopefully make bootloader go info failsafe mode if
something goes wrong.

Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
---
 package/system/mtd/src/mtd.c | 16 +++++++++++++---
 package/system/mtd/src/mtd.h |  2 +-
 package/system/mtd/src/trx.c | 21 ++++++++++++---------
 3 files changed, 26 insertions(+), 13 deletions(-)
diff mbox

Patch

diff --git a/package/system/mtd/src/mtd.c b/package/system/mtd/src/mtd.c
index dae0514..f206c4f 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, datasize = 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;
+				datasize = 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, datasize);
             }
 		case CMD_RESETBC:
 		    if (mtd_resetbc) {
diff --git a/package/system/mtd/src/mtd.h b/package/system/mtd/src/mtd.h
index 751b0d0..52074fc 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 datasize) __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 00c4d6c..2a41e0f 100644
--- a/package/system/mtd/src/trx.c
+++ b/package/system/mtd/src/trx.c
@@ -148,7 +148,7 @@  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 datasize)
 {
 	int fd;
 	struct trx_header *trx;
@@ -165,22 +165,25 @@  mtd_fixtrx(const char *mtd, size_t offset)
 		exit(1);
 	}
 
+	if (!datasize)
+		datasize = erasesize;
+
 	block_offset = offset & ~(erasesize - 1);
 	offset -= block_offset;
 
-	if (block_offset + erasesize > mtdsize) {
+	if (block_offset + datasize > mtdsize) {
 		fprintf(stderr, "Offset too large, device size 0x%x\n", mtdsize);
 		exit(1);
 	}
 
-	buf = malloc(erasesize);
+	buf = malloc(datasize);
 	if (!buf) {
 		perror("malloc");
 		exit(1);
 	}
 
-	res = pread(fd, buf, erasesize, block_offset);
-	if (res != erasesize) {
+	res = pread(fd, buf, datasize, block_offset);
+	if (res != datasize) {
 		perror("pread");
 		exit(1);
 	}
@@ -191,16 +194,16 @@  mtd_fixtrx(const char *mtd, size_t offset)
 		exit(1);
 	}
 
-	if (trx->len == STORE32_LE(erasesize - offset)) {
+	if (trx->len == STORE32_LE(datasize - offset)) {
 		if (quiet < 2)
 			fprintf(stderr, "Header already fixed, exiting\n");
 		close(fd);
 		return 0;
 	}
 
-	trx->len = STORE32_LE(erasesize - offset);
+	trx->len = STORE32_LE(datasize - offset);
 
-	trx->crc32 = STORE32_LE(crc32buf((char*) &trx->flag_version, erasesize - offset - 3*4));
+	trx->crc32 = STORE32_LE(crc32buf((char*) &trx->flag_version, datasize - offset - 3*4));
 	if (mtd_erase_block(fd, block_offset)) {
 		fprintf(stderr, "Can't erease block at 0x%x (%s)\n", block_offset, strerror(errno));
 		exit(1);
@@ -209,7 +212,7 @@  mtd_fixtrx(const char *mtd, size_t offset)
 	if (quiet < 2)
 		fprintf(stderr, "New crc32: 0x%x, rewriting block\n", trx->crc32);
 
-	if (pwrite(fd, buf, erasesize, block_offset) != erasesize) {
+	if (pwrite(fd, buf, datasize, block_offset) != datasize) {
 		fprintf(stderr, "Error writing block (%s)\n", strerror(errno));
 		exit(1);
 	}