summaryrefslogtreecommitdiffstats
path: root/package/mtd
diff options
context:
space:
mode:
authorcshore <cshore@3c298f89-4303-0410-b956-a3cf2f4a3e73>2010-12-26 04:18:08 +0000
committercshore <cshore@3c298f89-4303-0410-b956-a3cf2f4a3e73>2010-12-26 04:18:08 +0000
commit449cb3140d8b7c1263298b9f0813b327be4cfeb5 (patch)
tree2792b3be1a430936ce94c8ddc34102815ed0f512 /package/mtd
parentc91e2ce7101ceb415797058237fbc3c284563901 (diff)
mtd: Added trx_fixup for brcm63xx imagetag, and made references to fix_trx use the weak reference rather than the brcm47xx ifdef. This fixes a bug in which sysupgrade failed due to changing bad CRC on reboot.
Signed-off-by: Daniel Dickinson <daniel@cshore.neomailbox.net> git-svn-id: svn://svn.openwrt.org/openwrt/trunk@24837 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'package/mtd')
-rw-r--r--package/mtd/src/imagetag.c71
-rw-r--r--package/mtd/src/jffs2.c12
2 files changed, 77 insertions, 6 deletions
diff --git a/package/mtd/src/imagetag.c b/package/mtd/src/imagetag.c
index 71d88ea1a..2080128c1 100644
--- a/package/mtd/src/imagetag.c
+++ b/package/mtd/src/imagetag.c
@@ -78,6 +78,77 @@ uint32_t compute_crc32(uint32_t crc, off_t start, size_t compute_len, int fd)
}
int
+trx_fixup(int fd, const char *name)
+{
+ struct mtd_info_user mtdInfo;
+ unsigned long len;
+ void *ptr, *scan;
+ int bfd;
+ struct bcm_tag *tag;
+ ssize_t res;
+ uint32_t cfelen, imagelen, imagestart, rootfslen;
+ uint32_t imagecrc, rootfscrc, headercrc;
+ uint32_t offset = 0;
+ cfelen = imagelen = imagestart = imagecrc = rootfscrc = headercrc = rootfslen = 0;
+
+
+ if (ioctl(fd, MEMGETINFO, &mtdInfo) < 0) {
+ fprintf(stderr, "Failed to get mtd info\n");
+ goto err;
+ }
+
+ len = mtdInfo.size;
+ if (mtdInfo.size <= 0) {
+ fprintf(stderr, "Invalid MTD device size\n");
+ goto err;
+ }
+
+ bfd = mtd_open(name, true);
+ ptr = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, bfd, 0);
+ if (!ptr || (ptr == (void *) -1)) {
+ perror("mmap");
+ goto err1;
+ }
+
+ tag = (struct bcm_tag *) (ptr);
+
+ cfelen = strntoul(&tag->cfeLength[0], NULL, 10, IMAGE_LEN);
+ if (cfelen) {
+ fprintf(stderr, "Non-zero CFE length. This is currently unsupported.\n");
+ exit(1);
+ }
+
+ headercrc = compute_crc32(CRC_START, offset, offsetof(struct bcm_tag, headerCRC), fd);
+ if (headercrc != *(uint32_t *)(&tag->headerCRC[0])) {
+ fprintf(stderr, "Tag verify failed. This may not be a valid image.\n");
+ exit(1);
+ }
+
+ sprintf(&tag->rootLength[0], "%lu", 0);
+ strncpy(&tag->totalLength[0], &tag->kernelLength[0], IMAGE_LEN);
+
+ imagestart = sizeof(tag);
+ memcpy(&tag->imageCRC[0], &tag->kernelCRC[0], CRC_LEN);
+ memcpy(&tag->fskernelCRC[0], &tag->kernelCRC[0], CRC_LEN);
+ rootfscrc = CRC_START;
+ memcpy(&tag->rootfsCRC[0], &rootfscrc, sizeof(uint32_t));
+ headercrc = crc32(CRC_START, tag, offsetof(struct bcm_tag, headerCRC));
+ memcpy(&tag->headerCRC[0], &headercrc, sizeof(uint32_t));
+
+ msync(ptr, sizeof(struct bcm_tag), MS_SYNC|MS_INVALIDATE);
+ munmap(ptr, len);
+ close(bfd);
+ return 0;
+
+err1:
+ close(bfd);
+err:
+ fprintf(stderr, "Error fixing up imagetag header\n");
+ return -1;
+}
+
+
+int
trx_check(int imagefd, const char *mtd, char *buf, int *len)
{
struct bcm_tag *tag = (const struct bcm_tag *) buf;
diff --git a/package/mtd/src/jffs2.c b/package/mtd/src/jffs2.c
index 512f22278..aaf9be5a9 100644
--- a/package/mtd/src/jffs2.c
+++ b/package/mtd/src/jffs2.c
@@ -244,9 +244,9 @@ int mtd_replace_jffs2(const char *mtd, int fd, int ofs, const char *filename)
pad(erasesize);
free(buf);
-#ifdef target_brcm
- trx_fixup(outfd, mtd);
-#endif
+ if (trx_fixup) {
+ trx_fixup(outfd, mtd);
+ }
return (mtdofs - ofs);
}
@@ -347,9 +347,9 @@ int mtd_write_jffs2(const char *mtd, const char *filename, const char *dir)
err = 0;
-#ifdef target_brcm
- trx_fixup(outfd, mtd);
-#endif
+ if (trx_fixup) {
+ trx_fixup(outfd, mtd);
+ }
done:
close(outfd);