我正在使用内置NAND闪存的嵌入式ARM平台。我屋顶的隔板被压扁了。u-boot和内核都使用OMAP_ECC_BCH8_CODE_HW。问题是一些配电板(不仅仅是一个)在停电后停止工作(它们使用了大约2个月)。
这些错误可以在引导时看到:
[ 8.270507] end_request: I/O error, dev mtdblock9, sector 25184
[ 8.278930] SQUASHFS error: squashfs_read_data failed to read block 0xc40396
[ 8.286376] SQUASHFS error: Unable to read fragment cache entry [c40396]
[ 8.293579] SQUASHFS error: Unable to read page, block c40396, size d696
[ 8.300628] SQUASHFS error: Unable to read fragment cache entry [c40396]
[ 8.307647] SQUASHFS error: Unable to read page, block c40396, size d696
[ 8.314819] SQUASHFS error: Unable to read fragment cache entry [c40396]
[ 8.321838] SQUASHFS error: Unable to read page, block c40396, size d696
[ 8.328887] SQUASHFS error: Unable to read fragment cache entry [c40396]
[ 8.335906] SQUASHFS error: Unable to read page, block c40396, size d696
[ 8.343017] SQUASHFS error: Unable to read fragment cache entry [c40396]
[ 8.350006] SQUASHFS error: Unable to read page, block c40396, size d696
/usr/sbin/lighttpd: '/usr/lib/libpcre.so.1' is not an ELF file
/usr/sbin/lighttpd: can't load library 'libpcre.so.1'
我应该如何调试它?我还没有擦除闪光灯,所以仍然可以对它进行一些测试。
到目前为止我所做的:
我在坏分区上使用了nanddump(带-o,读取oob数据),我注意到了三个ecc更正警告。当我把这个转储写入另一个板时,它启动时没有问题。
当我使用带有附加选项-n的nanddump(--noecc,Read without error correction)并将其写入另一个板(使用nandwrite-n)时,第二个板无法启动。
在我看来,这些错误是可以恢复的,这就是为什么nanddump在第一种情况下纠正了它们。我比较了这两个转储,它们只有三个差异(nanddump报告的3个ecc校正?)
# diff mtd_without_ecc.hex mtd_with_ecc.hex
486347c486347
< 076bca0: 59d2 d8bc 3e89 1c67 a6c2 74a0 bc38 4873 Y...>..g..t..8Hs
---
> 076bca0: 59d2 d8bc 3e09 1c67 a6c2 74a0 bc38 4873 Y...>..g..t..8Hs
783769c783769
< 0bf5980: e31e f50a e5b5 6ae5 5a67 8be1 7636 9cf2 ......j.Zg..v6..
---
> 0bf5980: e31e f50a e5b5 6aa5 5a67 8be1 7636 9cf2 ......j.Zg..v6..
1315929c1315929
< 1414580: a9ec ef89 ac52 c8a5 61f5 5d0b 6ee2 af41 .....R..a.].n..A
---
> 1414580: a9ec af89 ac52 c8a5 61f5 5d0b 6ee2 af41 .....R..a.].n..A
问题是:为什么这些错误没有被系统自动纠正?是因为squashfs不是"mtd感知"文件系统,不应该在mtd设备上使用吗?如果是,我应该在UBI上使用南瓜吗?那么内核呢(据我所知,它必须是原始映像才能从u-boot启动)?
谢谢你的帮助!
实际上,Linux MTD层不对NAND/NOR内存进行任何维护。
例如,当NAND上发生位翻转时,ECC会对其进行校正。MTD层意识到了这一点,但它对此没有采取任何措施。它只是返回错误。
所以你需要在MTD上再加一层来处理这个问题。
一种解决方案是使用UBI,它旨在解决这类问题。看看linux mtd上的UBI文档。如果你想坚持使用squashfs,可以在UBI(gluebi)之上添加另一个MTD抽象,然后在它之上运行squashfs。结果看起来是这样的:
---------------------
| SquashFS |
---------------------
| MTD block |
---------------------
| MTD API (gluebi) |
---------------------
| UBI |
---------------------
| MTD driver |
---------------------
| Flash Chip |
---------------------
这是一张恐怖的照片,但效果很好;)
请看自由电子的这张幻灯片,了解更多信息(图片来自幻灯片47)。
关于内核,我不确定,但我认为U-Boot确实支持UBI。但从未尝试过。。。