保姆级教程:在SAMA5D27开发板上为NAND Flash新增一个MTD分区(UBI/UBIFS实战)

张开发
2026/4/17 7:25:05 15 分钟阅读

分享文章

保姆级教程:在SAMA5D27开发板上为NAND Flash新增一个MTD分区(UBI/UBIFS实战)
SAMA5D27开发板NAND Flash扩展实战从设备树到UBIFS挂载全解析当你的嵌入式系统需要更多存储空间时NAND Flash的灵活分区能力就派上了大用场。不同于简单的SD卡扩容在开发板上为NAND Flash新增MTD分区需要跨越硬件抽象层、引导加载程序和文件系统的多重考验。本文将带你深入SAMA5D27平台的存储扩展实战重点解决三个核心问题如何安全划分剩余空间为什么UBI/UBIFS是NAND的最佳拍档以及遇到坏块时该怎么优雅处理1. 开发环境准备与硬件基础在开始操作之前我们需要先搭建好开发环境并理解硬件特性。SAMA5D27 SOM1 EK开发板搭载的是一颗256MB的SLC NAND Flash芯片默认分区方案通常只使用了部分空间。我手头的这块板子原始配置留下了约504MB的未使用区域这正是我们要征服的新大陆。必备工具链检查交叉编译工具链arm-linux-gnueabihf-最新版U-Boot源码建议v2023.04以上Linux内核源码与开发板版本匹配串口调试工具minicom或picocom硬件连接方面除了常规的12V电源和串口线外建议准备一个可靠的TFTP服务器用于快速传输镜像。我在初期测试时曾因为网络配置不当浪费了大量时间在文件传输上。# 检查当前MTD分区布局 cat /proc/mtd dev: size erasesize name mtd0: 00040000 00040000 bootstrap mtd1: 000c0000 00040000 uboot ... mtd6: 0fc00000 00040000 rootfs提示记录下每个分区的起始地址和大小这对后续计算新分区位置至关重要。特别是rootfs分区的结束地址将作为我们新分区的起点。2. 设备树与U-Boot的协同配置修改设备树是存储扩展的第一步但很多开发者容易忽略U-Boot参数与之的关联性。在Microchip的官方文档中SAMA5D27的NAND控制器被定义为atmel_nand节点我们需要在其分区表中添加新条目。设备树关键修改点位于arch/arm/boot/dts/at91-sama5d27_som1_ek.dts:nand { partitions { compatible fixed-partitions; #address-cells 1; #size-cells 1; bootstrap0 { label bootstrap; reg 0x0 0x40000; read-only; }; // ... 其他原有分区保持不变 rootfsa80000 { label rootfs; reg 0xa80000 0xfc00000; }; data10c00000 { label data; reg 0x10c00000 0xfc00000; }; }; };这个修改将原本的504MB rootfs分区拆分为两个252MB的分区。注意地址计算必须精确到擦除块大小通常256KB否则会导致后续操作失败。U-Boot参数调整对比表参数项原值修改后值作用说明mtdpartsatmel_nand:...,252M(rootfs)atmel_nand:...,252M(rootfs),252M(data)定义内存分区布局ubi.mtd66,7指定UBI管理的MTD设备号rootubi0:rootfsubi0:rootfs保持根文件系统不变在U-Boot中使用saveenv保存修改后建议先用mtd list和ubi part命令验证新分区是否被正确识别。我曾遇到过因为环境变量存储空间不足导致参数截断的情况这时需要精简其他参数或扩大环境变量存储区。3. UBI/UBIFS的创建与挂载实战进入系统后真正的挑战才开始。NAND Flash的特性决定了我们不能像操作普通块设备那样直接创建文件系统。UBIUnsorted Block Images层的存在就是为了解决坏块管理、磨损均衡等NAND特有的问题。操作流程分解格式化新分区ubiformat /dev/mtd7 -y这个命令会扫描所有擦除块标记坏块并初始化UBI元数据。注意观察输出中的坏块计数如果超过总块数的2%就需要考虑更换芯片了。附加UBI设备ubiattach /dev/ubi_ctrl -m 7成功后会在/dev下生成ubi1设备节点。如果遇到Invalid argument错误通常是前面的格式化步骤不完整导致的。创建UBI卷ubimkvol /dev/ubi1 -N app_data -m-m参数让卷自动占用所有剩余空间。如果想创建固定大小的卷可以用-s 128MiB指定。卷名app_data将在挂载时使用。挂载UBIFSmount -t ubifs ubi1:app_data /mnt/data这里使用的是UBI设备号加卷名的引用方式比直接使用ubi1_0更可靠因为设备号可能在重启后变化。常见问题处理技巧挂载失败检查内核配置是否启用CONFIG_UBIFS_FS以及/sys/class/ubi/ubi1_0/name中的卷名是否匹配空间不足使用ubinfo /dev/ubi1查看实际可用PEB数量考虑保留5%空间给磨损均衡性能优化在ubimkvol时添加-O sparse参数可提升小文件写入速度4. 系统集成与自动化管理要让新分区真正融入系统还需要考虑启动顺序和故障恢复。我的方案是在/etc/fstab中添加以下条目ubi1:app_data /mnt/data ubifs defaults,noatime 0 0同时创建/etc/udev/rules.d/10-local.rules规则文件确保设备节点权限KERNELubi1_*, MODE0664, GROUPstorage对于关键数据存储建议实现定期ubiupdatevol备份。下面是一个简单的备份脚本示例#!/bin/sh BACKUP_DIR/mnt/data/backups VOLUMEapp_data DATE$(date %Y%m%d) if [ ! -d $BACKUP_DIR ]; then mkdir -p $BACKUP_DIR fi ubireader/ubi_dump -v /dev/ubi1_0 $BACKUP_DIR/${VOLUME}_${DATE}.img在电源管理方面NAND Flash对意外掉电特别敏感。可以在系统关机脚本中添加sync操作或者考虑启用UBI的fastmap特性加速挂载过程。

更多文章