几天前尝试不关机把移动版的F7607P内核分区替换为电信版,由于粗心直接覆写了正在使用中的kernel2分区,导致该分区被标记大量坏块,无法使用,尝试在uboot下擦除也无济于事。

当时以为这个分区就这么挂了,不敢再继续折腾,直到今天看到了这里:https://github.com/u-boot/u-boot/blob/master/doc/README.nand

"scrub [offset length]"
	like "erase" but don't skip bad block. Instead erase them.
	DANGEROUS!!! Factory set bad blocks will be lost. Use only
	to remove artificial bad blocks created with the "markbad" command.

猜想被标记的坏块并不是真的坏了,而只是因为在覆写的过程中,正在运行的linux内核因为读写错误误以为该块已坏从而错误地将其标记成了坏块。中兴系统内的nand命令就内置了手动标记坏块的功能,即nand mark,但并不能unmark,似乎linux内核层面都无法unmark一个坏块标记。但是uboot里的nand工具提供了nand scrub命令,scrub顾名思义即擦洗之意,比nand erase更彻底一点,连坏块标记也一并擦洗了。需要注意大写的DANGEROUS!!!后面的文字:闪存出厂时真正坏了的坏块标记也会一并被清洗掉,如果分区内有真的坏块的话,坏块标记被清除掉后可能会造成不可预料的问题,因此只能用来清除用户错误标记的坏块标记, 没事千万别用这条命令!但我的这块美光SLC闪存的mtd8这个分区,我依稀记得之前写入的时候从没有提示过有坏块。

再次开盖接上TTL适配器,进入uboot,中兴的uboot内的nand命令也提供了scrub功能

=> help nand
nand - NAND sub-system

Usage:
nand info - show available NAND devices
nand device [dev] - show or set current device
nand read - addr off|partition size
nand write - addr off|partition size
    read/write 'size' bytes starting at offset 'off'
    to/from memory address 'addr', skipping bad blocks.
nand read.raw - addr off|partition [count]
nand write.raw - addr off|partition [count]
    Use read.raw/write.raw to avoid ECC and access the flash as-is.
nand erase[.spread] [clean] off size - erase 'size' bytes from offset 'off'
    With '.spread', erase enough for given file size, otherwise,
    'size' includes skipped bad blocks.
nand erase.part [clean] partition - erase entire mtd partition'
nand erase.chip [clean] - erase entire chip'
nand bad - show bad blocks
nand dump[.oob] off - dump page
nand scrub [-y] off size | scrub.part partition | scrub.chip
    really clean NAND erasing bad blocks (UNSAFE)
nand markbad off [...] - mark bad block(s) at offset (UNSAFE)
nand biterr off - make a bit error at offset (UNSAFE)

使用nand bad可以查看闪存上标记的所有坏块,看了下我的,大量连续的坏块都在mtd8分区内,其他地方都没有,看来这块SLC闪存出厂品质还不错。

nand scrub的用法,nand scrub [-y] off size,后面跟上偏移量和长度,对我的mtd8而言的话,就是:

=> nand scrub 0x3e00000 0x2800000

NAND scrub: device 0 offset 0x3e00000, size 0x2800000
Warning: scrub option will erase all factory set bad blocks!
         There is no reliable way to recover them.
         Use this command only for testing purposes if you
         are sure of what you are doing!

Really scrub this NAND flash? <y/N>
y
Erasing at 0x65e0000 -- 100% complete.
OK

再使用nand bad查看下坏块标记,一个也没有了!接下来就把正常使用的mtd7分区复制到清除坏块标记的mtd8:

nand read 0x88000000 0x1600000 0x2800000
nand write 0x88000000 0x3e00000 0x2800000

没有看到错误提示,很好,reset启动进入mtd7系统后使用upgradetest switchver 1将下次启动的分区设置为修复后的mtd8,reboot,TTL下看到mtd8分区顺利通过CRC校验和RSA验证,内核加载成功,系统顺利启动

又抢救回一条命