diff options
author | cshore <cshore@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2010-12-26 04:18:08 +0000 |
---|---|---|
committer | cshore <cshore@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2010-12-26 04:18:08 +0000 |
commit | 449cb3140d8b7c1263298b9f0813b327be4cfeb5 (patch) | |
tree | 2792b3be1a430936ce94c8ddc34102815ed0f512 /package/mtd | |
parent | c91e2ce7101ceb415797058237fbc3c284563901 (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.c | 71 | ||||
-rw-r--r-- | package/mtd/src/jffs2.c | 12 |
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); |