4、RMC存储系统:eMMC与NVMe SSD的选择、启动引导流程、文件系统选型(UBIFS vs ext4)
存储系统,说白了就是RMC的“记忆体”。它既要存代码,又要存数据,还得保证掉电不丢。我这些年经手的项目,至少有一半的稳定性问题,最后都追查到了存储选型或配置上。这一章,咱们就把eMMC、NVMe SSD、启动引导和文件系统这几个硬骨头啃下来。
4.1 eMMC vs NVMe SSD:选谁?
先问个问题:你的RMC是跑在工业现场,还是数据中心?这个问题的答案,基本就决定了你的存储方向。
eMMC,全称是embedded MultiMediaCard。它把Flash控制器和NAND Flash颗粒封装在一起,对外提供标准接口。我习惯把它看作“大号SD卡”,但可靠性高得多。
- 优点:成本低、体积小、接口简单(通常是8线并行或SDIO)。
- 缺点:性能上限低(顺序读写约300MB/s)、寿命受制于NAND颗粒。
- 适用场景:工业控制、边缘网关、车载设备。这些地方对成本敏感,对性能要求不高。
NVMe SSD,Non-Volatile Memory Express,走的是PCIe通道。它把延迟压到了微秒级,吞吐量能到GB/s级别。
- 优点:性能炸裂、延迟极低、支持多队列并行。
- 缺点:贵、功耗高、需要PCIe控制器支持。
- 适用场景:AI推理服务器、高速数据采集、核心网络设备。
我的选型原则:
- 如果系统启动时间要求小于5秒,且需要频繁写入日志,我建议直接上NVMe。
- 如果成本是第一约束,且写入量不大(每天几十MB级别),eMMC完全够用。
- 千万别在eMMC上跑数据库!我曾经见过一个项目,用eMMC存SQLite,三个月后eMMC就挂了。
| 对比项 | eMMC | NVMe SSD |
|---|---|---|
| 接口 | MMC/SDIO | PCIe |
| 顺序读 | ~300 MB/s | ~3500 MB/s |
| 随机IOPS | ~10K | ~500K |
| 典型功耗 | 0.5W - 1W | 3W - 8W |
| 成本(每GB) | 低 | 高 |
| 寿命 | 中等(取决于TBW) | 长(通常有DRAM缓存) |
4.2 启动引导流程:从ROM到Kernel
RMC的启动,不是一蹴而就的。它像接力赛,一棒接一棒。我画了一张图,帮你理清这个流程。
嗯,这里要注意几个细节:
- ROM Boot:芯片上电后,CPU从ROM中执行固化代码。它初始化最基本的硬件(比如时钟、引脚),然后去固定的位置找SPL。这个位置通常是eMMC的boot分区,或者NAND的block 0。
- SPL:Secondary Program Loader。它很小,因为此时DDR还没初始化,只能在芯片内部的SRAM里跑。SPL的任务就是初始化DDR,然后把U-Boot从存储介质加载到DDR中。
- U-Boot:这才是真正的引导加载程序。它提供命令行,可以设置启动参数、加载Kernel、设备树(DTB)。我习惯在U-Boot里加一个“启动计数”功能,用于系统升级失败后的回滚。
- Kernel:最后,U-Boot把控制权交给Kernel。Kernel挂载根文件系统,启动init进程。
避坑指南:我曾经在eMMC的boot分区里放SPL,结果因为eMMC的boot分区默认是只读的,导致第一次烧录后无法更新。后来我改用U-Boot的“mmc bootbus”命令,把boot分区配置为可写。记住,eMMC的boot分区需要手动设置“Extended CSD”寄存器才能写入。
4.3 文件系统选型:UBIFS vs ext4
文件系统选型,说白了就是“你打算怎么管这些数据”。我见过太多人直接在NAND上跑ext4,结果没几个月就出现坏块导致系统崩溃。这里面的门道,我跟你聊聊。
4.3.1 UBIFS:NAND Flash的亲生儿子
UBIFS是专门为NAND Flash设计的。它直接运行在MTD(Memory Technology Device)层之上,不需要FTL(Flash Translation Layer)。
- 优点:支持磨损均衡、坏块管理、掉电安全。压缩是内置的,能省不少空间。
- 缺点:不支持快照、不支持文件追加写优化。挂载速度比ext4慢。
- 适用场景:eMMC、NAND Flash作为根文件系统。
UBIFS的挂载命令很简单:
# 假设MTD分区是mtdblock2
mount -t ubifs /dev/ubi0_0 /mnt/rootfs
# 或者通过UBI设备
ubiattach -m 2 -d 0
mount -t ubifs ubi0:rootfs /mnt/rootfs
4.3.2 ext4:通用型选手
ext4是Linux上最成熟的文件系统。它需要底层块设备支持随机读写,所以通常跑在NVMe SSD或SD卡上。
- 优点:性能好、支持日志、支持快照、工具链成熟。
- 缺点:不支持坏块管理(依赖底层设备)、掉电时日志恢复可能丢数据。
- 适用场景:NVMe SSD、SD卡、SATA硬盘。
我的建议:
- 如果存储介质是eMMC或NAND Flash,必须用UBIFS。别问我为什么,我见过太多ext4在NAND上跑出坏块后整个分区挂掉的案例。
- 如果存储介质是NVMe SSD,用ext4。NVMe SSD自带FTL和坏块管理,ext4的日志功能反而能提供更好的数据一致性。
- 如果存储介质是SD卡,用ext4 + noatime。SD卡的随机写入性能很差,noatime可以减少不必要的写操作。
| 对比项 | UBIFS | ext4 |
|---|---|---|
| 底层依赖 | MTD + UBI | 块设备(MMC/SD/NVMe) |
| 坏块管理 | 内置 | 无(依赖底层) |
| 磨损均衡 | 支持 | 不支持 |
| 掉电安全 | 好(日志结构) | 中等(日志可能损坏) |
| 压缩 | 内置(LZO/zlib) | 不支持 |
| 挂载速度 | 慢(需扫描) | 快 |
| 典型应用 | eMMC根文件系统 | NVMe SSD数据分区 |
警告:不要在UBIFS上使用“sync”挂载选项。UBIFS的日志结构设计本身已经保证了掉电安全,加sync反而会大幅降低性能。我曾经在一个项目中加了sync,结果写入速度从5MB/s掉到了200KB/s,排查了三天才发现是这个问题。
最后说一句,文件系统的选型没有绝对的对错,但一定要匹配你的硬件特性。eMMC配UBIFS,NVMe配ext4,这是最稳妥的组合。如果你非要在eMMC上跑ext4,记得加上“discard”选项,让文件系统主动通知eMMC哪些块可以回收。嗯,就这样。