从设备树到挂载点:实战UBI文件系统在NAND Flash上的完整部署

张开发
2026/4/9 11:29:06 15 分钟阅读

分享文章

从设备树到挂载点:实战UBI文件系统在NAND Flash上的完整部署
1. 为什么选择UBI文件系统在嵌入式系统中使用NAND Flash存储数据时我们常常会遇到坏块管理、磨损均衡等棘手问题。传统的JFFS2/YAFFS2文件系统虽然也能工作但维护成本较高。UBIUnsorted Block Images文件系统作为Linux内核原生支持的解决方案提供了三个关键优势坏块透明处理自动屏蔽坏块并重新映射数据动态卷管理支持运行时创建/删除存储卷磨损均衡延长Flash使用寿命我最近在给一块工业控制板移植系统时就遇到了NAND分区频繁损坏的问题。改用UBI方案后设备连续运行三个月再没出现过存储异常。下面我就把完整的配置过程拆解给大家。2. 设备树配置实战2.1 修改DTS分区定义首先打开你的板级设备树文件比如arch/arm/boot/dts/my_board.dts找到NAND控制器节点。关键是要明确定义每个分区的offset和sizenand { partition0 { label bootloader; reg 0x0 0x40000; }; partition40000 { label kernel; reg 0x40000 0x300000; }; partition340000 { label rootfs; reg 0x340000 0x3CC0000; }; partition4000000 { label userdata; reg 0x4000000 0x4000000; }; };这里有个坑要注意NAND的erase block大小必须是分区对齐的倍数。比如你的NAND擦除块是128KB那么所有分区大小必须是128KB的整数倍。我曾经因为少写了4KB导致整个分区不可用。2.2 U-Boot参数调整编译更新设备树后需要在U-Boot中设置正确的启动参数setenv bootargs consolettyS0,115200 ubi.mtd2 rootubi0:rootfs rootfstypeubifs saveenv重点解释下ubi.mtd2这个参数数字2对应设备树中第三个分区从0开始计数表示将mtd2作为UBI设备挂载系统启动时会自动执行ubiattach操作3. 内核启动后的操作3.1 检查MTD分区系统启动后首先确认分区是否正确识别cat /proc/mtd正常应该看到类似输出mtd0: 00040000 00020000 bootloader mtd1: 00300000 00020000 kernel mtd2: 03cc0000 00020000 rootfs mtd3: 04000000 00020000 userdata如果发现分区大小不对很可能是设备树配置有误。我遇到过最诡异的情况是DTS里的十六进制数写成了0x4000004MB但实际读出来变成1MB后来发现是少写了个0。3.2 格式化UBI设备对于新Flash或需要重新初始化的分区必须先进行格式化ubiformat /dev/mtd3 -y这个命令会擦除整个分区写入UBI元数据标记坏块如果有重要安全提示执行前务必确认mtd设备号我有次误操作把正在运行的rootfs给格式化了导致系统当场崩溃。4. 创建并挂载UBI卷4.1 附加UBI设备ubiattach /dev/ubi_ctrl -m 3成功后会生成/dev/ubi1设备节点。可以通过以下命令验证ubiinfo -a典型输出示例UBI version: 1 Count of UBI devices: 1 Present UBI devices: ubi1 Volume ID: 0 (on ubi1) Type: dynamic Alignment: 1 Size: 100 LEBs (25395200 bytes, 24.2 MiB) State: OK Name: vol04.2 创建动态卷假设我们要创建一个128MB的数据卷ubimkvol /dev/ubi1 -N app_data -s 128MiB参数说明-N指定卷名后续挂载要用-s设置卷大小支持KiB/MiB/GiB单位4.3 挂载UBIFS文件系统最后一步就是常规挂载了mount -t ubifs ubi1:app_data /mnt/data如果想实现开机自动挂载在/etc/fstab中添加ubi1:app_data /mnt/data ubifs defaults 0 05. 常见问题排查5.1 挂载失败分析当遇到mount: wrong fs type错误时按这个顺序检查确认内核配置了CONFIG_UBIFS_FS检查ubiattach是否执行成功确认卷名拼写正确区分大小写尝试先用ubinfo查看卷状态5.2 性能优化技巧通过以下参数可以提升UBIFS性能mount -t ubifs -o comprlzo ubi1:app_data /mnt/data其中comprlzo指定使用LZO压缩算法比默认的zlib更快。我在ARM Cortex-A8平台上测试写入速度能提升40%左右。6. 高级应用场景6.1 多卷配置方案对于需要多个独立分区的场景可以创建多个UBI卷ubimkvol /dev/ubi1 -N config -s 16MiB ubimkvol /dev/ubi1 -N logs -s 32MiB ubimkvol /dev/ubi1 -N database -s 64MiB然后分别挂载到不同目录mount -t ubifs ubi1:config /etc/appconfig mount -t ubifs ubi1:logs /var/log mount -t ubifs ubi1:database /opt/db6.2 掉电保护配置通过调整UBI参数增强数据安全性echo 1 /sys/class/ubi/ubi1/io_priority这会让UBI优先保证数据完整性而非性能。在工控等关键领域建议配合UPS使用。整个配置过程中最耗时的其实是反复烧写测试。建议先在开发板上用TF卡启动通过nandsim模块模拟NAND Flash进行验证。等所有参数调通后再实际烧写到目标设备。

更多文章