SQUASHFS 错误:无法读取页面、...、大小

jba*_*cic 5 linux embedded u-boot squashfs

我正在使用带有内置 NAND 闪存的嵌入式 ARM 平台。我的屋顶分区是 squashfs。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'
Run Code Online (Sandbox Code Playgroud)

我应该如何调试这个?我还没有擦除闪存,所以仍然可以对其进行一些测试。

到目前为止我所做的:

  1. 我在坏分区上使用了 nanddump(带 -o,读取 oob 数据),我注意到三个 ecc 更正警告。当我将此转储写入另一块板时,它启动没有问题。

  2. 当我使用带有附加选项 -n(--noecc,无纠错读取)的 nanddump 并将其写入另一块板(使用 nandwrite -n)时,第二块板无法启动。

在我看来,这些错误是可以恢复的,这就是 nanddump 在第一种情况下纠正它们的原因。我比较了这 2 个转储,它们只有三个不同(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
Run Code Online (Sandbox Code Playgroud)

问题是:为什么这些错误没有被系统自动纠正?是因为 squashfs 不是“mtd-aware”文件系统,不应该在 mtd 设备上使用吗?如果是这样,我应该在 UBI 上使用 squashfs 吗?那么内核呢(据我所知,它必须是原始映像才能从 u-boot 引导)?

谢谢你的帮助!

elb*_*ero 0

事实上,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    |
---------------------
Run Code Online (Sandbox Code Playgroud)

虽然它的画面很吓人,但效果很好;)

请查看这张来自 free- electronics 的幻灯片以获取更多信息(图片来自幻灯片 47)。

关于内核,我不确定,但我认为 U-Boot 确实支持 UBI。虽然从来没有尝试过...