在嵌入式系统开发中,NAND闪存因其高密度、低成本和非易失性等特性,成为存储解决方案的首选。与NOR闪存不同,NAND采用页式存储结构(通常每页2KB-4KB),需要通过专门的控制器进行访问。这种物理特性决定了它不能像传统硬盘那样直接挂载使用,必须经过特定的格式化处理。
我曾在多个工业控制项目中遇到过NAND初始化问题。有一次,由于忽略了坏块管理,导致系统运行三个月后关键数据丢失。这个教训让我深刻认识到:NAND的格式化不是简单的"擦除-写入"过程,而是需要建立完整的坏块管理机制和文件系统结构。
NAND闪存在出厂时就可能存在坏块,使用过程中还会产生新的坏块。Bad Block Manager(BBM)就是用来标记和管理这些坏块的关键组件。通过以下命令初始化BBM:
bash复制insmod ffxos.ko bbmformat=0,1
这里的参数bbmformat=0,1表示:
重要提示:如果闪存之前被其他系统使用过,必须先用原系统的工具彻底擦除(保留出厂坏块标记)。我曾遇到过因残留数据被误识别为坏块标记,导致格式化失败的情况。
Variable Block Format(VBF)技术解决了NAND闪存不能随机写入的问题。它通过以下机制模拟块设备:
初始化命令:
bash复制insmod flashfx.ko
insmod ffxblk.ko format=0,1
初始化时间取决于闪存容量:
FlashFX驱动加载后,需要检查分配的主设备号:
bash复制cat /proc/devices | grep ffx
典型输出:
code复制253 ffx
手动创建设备节点(适用于无udev的系统):
bash复制mknod /dev/ffx00 b 253 0
对于嵌入式Linux系统,推荐的分区方案:
| 分区 | 文件系统 | 大小 | 用途 |
|---|---|---|---|
| p1 | Reliance | 16MB | 内核和initrd(保留双备份空间) |
| p2 | Reliance | 剩余 | 根文件系统 |
创建分区节点示例:
bash复制mknod /dev/ffx00p1 b 253 1
mknod /dev/ffx00p2 b 253 2
Reliance是为嵌入式设备优化的文件系统,具有:
创建命令:
bash复制mkfs.relfs -k /dev/ffx00p1
-k参数跳过坏块检查(BBM已处理)
通过NFS挂载根文件系统是最便捷的部署方式:
bash复制mount -t nfs 192.168.1.100:/nfsroot /mnt
cd /mnt && find . | cpio -pd /mnt/flash
关键文件检查清单:
将编译好的ffxboot镜像放入TFTP目录后:
bash复制tftp -g -r ffxboot 192.168.1.100
burn 0xa0100000
地址0xa0100000需与链接脚本中的FLASH_BASE一致。我在一次项目中使用错误的地址导致内核解压失败,花费两天才排查出这个问题。
典型的引导参数:
code复制console=ttyAM0,115200 root=/dev/ffx00p2 init=/sbin/init
调试技巧:遇到启动问题时,添加init=/bin/sh进入救援shell:
bash复制exec 0xa0100000 console=ttyAM0,115200 init=/bin/sh
完整的最小化initrd应包含:
code复制.
├── bin
│ ├── busybox
│ ├── insmod -> busybox
│ ├── mount -> busybox
│ └── mknod -> busybox
├── dev
│ ├── console
│ └── ffx00
├── etc
├── linuxrc
└── lib
├── modules
│ ├── ffxblk.ko
│ └── flashfx.ko
└── 动态链接库
典型的linuxrc脚本内容:
bash复制#!/bin/sh
mount -t proc proc /proc
insmod /lib/modules/flashfx.ko
mknod /dev/ffx00 b 253 0
mount /dev/ffx00p2 /newroot
exec switch_root /newroot /sbin/init
压缩initrd镜像:
bash复制gzip -9 initrd
| 现象 | 可能原因 | 解决方法 |
|---|---|---|
| 内核panic无法挂载根文件系统 | 设备节点未创建 | 检查/dev下是否存在ffx00p2 |
| 启动卡在"Freeing init memory" | initrd中的init路径错误 | 检查linuxrc权限和内容 |
| 写入速度突然下降 | 坏块数量超过阈值 | 用flash_eraseall彻底擦除 |
调整VBF参数:
bash复制insmod ffxblk.ko cache_size=512
增加缓存可提升小文件写入性能
定期维护:
bash复制fsck.relfs -f /dev/ffx00p2
每月执行一次完整检查
预留空间:
保持至少5%的剩余空间,避免性能陡降
在实际项目中,NAND闪存的稳定运行离不开这三个关键环节:正确的初始化流程、合理的分区设计、定期的维护检查。特别是在工业现场环境中,这些预防性措施能显著降低现场故障率。