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>

SVN-Revision: 24837
This commit is contained in:
Daniel Dickinson 2010-12-26 04:18:08 +00:00
parent 6ee5411686
commit b3bcc483b2
2 changed files with 77 additions and 6 deletions

View file

@ -77,6 +77,77 @@ uint32_t compute_crc32(uint32_t crc, off_t start, size_t compute_len, int fd)
return crc;
}
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)
{

View file

@ -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);