找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

3113

积分

0

好友

424

主题
发表于 昨天 22:32 | 查看: 1| 回复: 0

在嵌入式设备中,NAND闪存因其高容量和相对低成本被广泛使用,但其固有的物理特性——坏块,是系统设计与稳定性面临的关键挑战。本文通过一个具体的测试案例,探讨当NAND闪存存在足够多的坏块时,未启用坏块管理(NMBM)的OpenWrt系统为何无法正常启动,并验证NMBM机制在此场景下的关键作用。

NMBM:闪存的“坏块管家”

NMBM(NAND Memory Bad Block Management)是NAND闪存坏块管理的专用技术,属于闪存转换层(FTL)的核心模块。它通过软件/固件算法动态管理闪存的物理缺陷,为操作系统提供可靠、连续的逻辑存储空间。其核心功能包括:

  • 自动映射:动态检测、识别出厂或使用中产生的物理坏块,并将其逻辑地址映射到预留的备用物理块。
  • 寿命优化:结合磨损均衡、垃圾回收等技术,延长闪存使用寿命。
  • 数据保障:通过与ECC(纠错码)协同、掉电保护等技术,保障数据的可靠性。

在工作流程上,NMBM的作用贯穿启动与运行全过程:

  1. U-Boot阶段启用NMBM:Bootloader会识别闪存中已有的物理坏块,建立逻辑地址到正常物理块的映射表。无论是刷写固件还是后续写入数据,都会依据此映射表写入正确的物理位置,遇到新的坏块也会实时标记和重新映射。
  2. OpenWrt内核阶段启用NMBM:系统加载运行时,内核中的NMBM驱动会读取并维护这份映射关系。因此,系统读取的每一个逻辑块都对应着有效的物理数据,系统得以正常启动和运行。
  3. OpenWrt内核未启用NMBM:系统加载时,会按照原始的、线性的逻辑地址去读取物理块。如果某个逻辑地址恰好映射到了之前在U-Boot阶段已被标记为坏块的物理块,由于该块没有有效数据,将导致数据读取异常,进而引发系统启动失败或运行错误。

验证过程:手工制造坏块场景

为了直观验证上述理论,我们在搭载MT7981芯片的平台进行了以下测试。测试的核心思路是:在U-Boot中手工标记大量坏块,然后分别刷写启用和未启用NMBM的OpenWrt固件,观察系统启动结果。

第一步:查看分区布局并标记坏块

首先,需要在U-Boot中使用mtd list命令查看闪存的分区信息。关键是要找到用于存放OpenWrt根文件系统的ubi分区的地址范围。

从识别的信息中,我们可以看到MTD设备 spi0.0 的分区布局如下:

  • bl2: 0x000000000000-0x000000100000
  • u-boot-env: 0x000000100000-0x000000180000
  • Factory: 0x000000180000-0x000000380000
  • fip: 0x000000380000-0x000000580000
  • ubi: 0x000000580000-0x000004580000 (此即系统分区)
  • pdt_data: 0x000004580000-0x000004680000
  • ... (后续还有其他分区)

其中,ubi分区从逻辑地址 0x580000 开始,到 0x4580000 结束。该分区的块大小(block size)为 0x20000(即128 KiB)。

为了模拟坏块足够多且分散的场景(避免因磨损均衡导致固件数据恰好未写入坏块区域),我们选择在ubi分区的起始区域和结束区域各标记10个坏块

在U-Boot命令行中,执行以下命令(每个块的地址递增 0x20000):

nand markbad 0x580000
nand markbad 0x5A0000
nand markbad 0x5C0000
nand markbad 0x5E0000
nand markbad 0x600000
nand markbad 0x620000
nand markbad 0x640000
nand markbad 0x660000
nand markbad 0x680000
nand markbad 0x6A0000
nand markbad 0x4580000
nand markbad 0x4560000
nand markbad 0x4540000
nand markbad 0x4520000
nand markbad 0x4500000
nand markbad 0x44E0000
nand markbad 0x44C0000
nand markbad 0x44A0000
nand markbad 0x4480000
nand markbad 0x4460000

执行 nand bad 命令,可以确认已标记的坏块列表:

MT7981> nand bad
00580000
005a0000
005c0000
005e0000
00600000
00620000
00640000
00660000
00680000
006a0000
04440000
04460000
04480000
044a0000
044c0000
044e0000
04500000
04520000
04560000
04580000

第二步:查看NMBM映射状态

在启用了NMBM的U-Boot中,可以查看具体的映射关系。执行 nmbm nmbm0 mapping 命令,会显示逻辑块与物理块的映射表。例如,以下片段显示逻辑块904至928被映射到了不同的物理块上:

Logical Block Physical Block
904 1022
905 1021
... ...
928 998

这张表正是NMBM工作的核心体现,它将有缺陷的物理块从系统的视野中“隐藏”了起来。

第三步:刷写固件并验证启动结果

接下来是关键的系统启动验证测试

  1. 刷写未启用NMBM的OpenWrt固件:在U-Boot中刷写一个内核未编译NMBM支持的OpenWrt系统。刷写完成后重启,系统无法正常启动。从内核日志中可以清晰看到错误原因:
    ubi0: attaching mtd4
    ubi0: scanning is finished
    ubi0 error: not enough PEBs, required 491, available 457
    ubi0 error: failed to attach mtd4, error -28

    日志表明,UBI(Unsorted Block Images)子系统需要491个可用的物理擦除块(PEB),但实际只找到了457个。这正是因为我们手工标记的20个坏块被系统识别为不可用,导致有效存储空间不足,UBI卷无法正确挂载,系统启动失败。

  2. 刷写启用了NMBM的OpenWrt固件:在同样的硬件和坏块环境下,刷写一个内核启用了NMBM支持的OpenWrt系统。系统可以正常启动并运行。因为内核中的NMBM驱动能够识别U-Boot阶段建立的映射表,所有对逻辑地址的访问都被重定向到了良好的物理块上。

第四步:清理测试环境

测试完成后,由于标记的坏块是“软坏块”(非物理损坏),需要将其清除以恢复闪存状态。在U-Boot中执行强制擦除命令:

  1. 擦除ubi分区,清除其中的坏块标记:
    nand erase.force 0x580000 0x4000000
  2. 擦除NMBM管理数据区(通常位于闪存末尾):
    nand erase.force 0x7800000 0x800000

    执行后,再次使用 nmbm nmbm0 state 命令查看,确认坏块标记已被清除。

结论与建议

本次测试清晰地验证了NMBM在保障使用NAND闪存的嵌入式系统稳定性中不可或缺的作用。对于基于OpenWrt的路由器等设备,尤其是采用SPI NAND闪存的方案,在编译系统时强烈建议启用内核的NMBM支持CONFIG_MTD_NMBM 及相关选项)。这能有效应对闪存随使用产生的累积坏块问题,提升产品的长期运行可靠性。对于开发者而言,在设计和测试阶段就充分考虑坏块管理策略,是确保系统韧性的重要一环。

参考资料

[1] 验证测试:nand 闪存有坏块时(足够多)运行不了没有启用 nmbm 的 openwrt 系统, 微信公众号:mp.weixin.qq.com/s/Ua8ohlyvBUhM12DwOPMc_g

版权声明:本文由 云栈社区 整理发布,版权归原作者所有。




上一篇:校园卡系统权限绕过漏洞挖掘:从403绕过到通杀400+学校
下一篇:解析MP4文件交错问题:如何避免Chrome播放引发的CDN带宽激增
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-2-10 02:22 , Processed in 0.353301 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表