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:[email protected]] On Behalf
Of Matthew Redfearn
Sent: 29 November 2013 11:59
To: [email protected]
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 [email protected] https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
