This patch fixes the issue I was having with sysupgrade failing due to bad nand flash blocks.
It uses the MEMGETBADBLOCK ioctl to determine if the block is bad before attempting to erase / write it. Thanks, Matt Index: package/system/mtd/src/mtd.c =================================================================== --- package/system/mtd/src/mtd.c (revision 38980) +++ package/system/mtd/src/mtd.c (working copy) @@ -107,6 +107,19 @@ return fd; } +int mtd_block_is_bad(int fd, int offset) +{ + int r; + loff_t o = offset; + r = ioctl(fd, MEMGETBADBLOCK, &o); + if (r < 0) + { + fprintf(stderr, "Failed to get erase block status\n"); + exit(1); + } + return r; +} + int mtd_erase_block(int fd, int offset) { struct erase_info_user mtdEraseInfo; @@ -236,10 +249,17 @@ for (mtdEraseInfo.start = 0; mtdEraseInfo.start < mtdsize; mtdEraseInfo.start += erasesize) { - - ioctl(fd, MEMUNLOCK, &mtdEraseInfo); - if(ioctl(fd, MEMERASE, &mtdEraseInfo)) - fprintf(stderr, "Failed to erase block on %s at 0x%x\n", mtd, mtdEraseInfo.start); + if (mtd_block_is_bad(fd, mtdEraseInfo.start)) + { + if (!quiet) + fprintf(stderr, "\nSkipping bad block at %u ", mtdEraseInfo.start); + } + else + { + ioctl(fd, MEMUNLOCK, &mtdEraseInfo); + if(ioctl(fd, MEMERASE, &mtdEraseInfo)) + fprintf(stderr, "Failed to erase block on %s at 0x%x\n", mtd, mtdEraseInfo.start); + } } close(fd); @@ -324,6 +344,7 @@ ssize_t skip = 0; uint32_t offset = 0; int jffs2_replaced = 0; + int skip_bad_blocks = 0; #ifdef FIS_SUPPORT static struct fis_part new_parts[MAX_ARGS]; @@ -466,10 +487,22 @@ /* need to erase the next block before writing data to it */ if(!no_erase) { - while (w + buflen > e) { + while (w + buflen > e - skip_bad_blocks) { if (!quiet) fprintf(stderr, "\b\b\b[e]"); + if (mtd_block_is_bad(fd, e)) + { + if (!quiet) + fprintf(stderr, "\nSkipping bad block at %u ", e); + + skip_bad_blocks += erasesize; + e += erasesize; + + // Move the file pointer along over the bad block. + lseek(fd, erasesize, SEEK_CUR); + continue; + } if (mtd_erase_block(fd, e) < 0) { if (next) { From: openwrt-devel [mailto:openwrt-devel-boun...@lists.openwrt.org] On Behalf Of Matthew Redfearn Sent: 29 November 2013 11:59 To: openwrt-devel@lists.openwrt.org Subject: [OpenWrt-Devel] sysupgrade fails due to bad nand flash blocks Hi all, I have a problem with sysupgrade failing prematurely because my nand flash contains bad blocks. This results in an incomplete rootfs image in flash upon reboot from sysupgrade. I am running an attitude adjustment derivative (svn r35400) for custom hardware. Uboot / the kernel seem to deal with bad flash blocks correctly, this only occurs when using mtd via sysupgrade. This is what I see: # sysupgrade openwrt-lpc32xx-JNRD6040--jffs2-sysupgrade.bin Saving config files... Sending TERM to remaining processes ... syslogd klogd hotplug2 ubusd netifd mrd6 dbus-daemon dnsmasq avahi-daemon Sending KILL to remaining processes ... Switching to ramdisk... Performing system upgrade... Unlocking firmware ... Writing from <stdin> to firmware ... [e][ 502.560000] nand_erase_nand: attempt to erase a bad block at page 0x00002080 Failed to erase block Upgrade completed Rebooting system... [ 502.580000] Restarting system. I found this ticket from a while ago that seems to cover this: https://dev.openwrt.org/ticket/11749 Looking at the latest version of mtd in trunk I can't see anything to address this issue - is this something that is not that common and so hasn't been observed on other hardware? Thanks, Matt
mtd-bad-nand-blocks-trunk.patch
Description: mtd-bad-nand-blocks-trunk.patch
_______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel