18、存储系统移植:eMMC/UFS驱动适配、F2FS文件系统优化、存储性能测试、加密存储(FBE/FDE)配置
存储系统,说白了就是车机的大脑记忆体。Android Automotive 对存储的要求比手机还苛刻——你想想看,车机要连续跑好几年,不能卡顿,不能掉电丢数据。我这些年调过的存储问题,从 eMMC 到 UFS,从 ext4 到 F2FS,踩过的坑真不少。今天咱们就把这块彻底讲透。
18.1 eMMC vs UFS:选型与驱动适配
先聊硬件选型。eMMC 和 UFS 都是 NAND Flash 的封装方案,但差异很大。
| 对比项 | eMMC 5.1 | UFS 2.1/3.1 |
|---|---|---|
| 接口协议 | 并行(8位) | 串行(M-PHY) |
| 全双工 | 不支持 | 支持 |
| 典型顺序读 | ~250 MB/s | ~800 MB/s(UFS 2.1) |
| 随机读写 IOPS | ~10K | ~30K+ |
| Linux 驱动 | mmc_block / mmc_core | ufshcd / ufs-qcom |
我在一个项目中遇到过客户坚持用 eMMC 做 4K 视频录制。结果呢?写入延迟一高,掉帧严重。后来换了 UFS 3.1,问题直接解决。所以我的建议是:如果车机有高码率视频或频繁 OTA 场景,别省那几块钱,直接上 UFS。
eMMC 驱动适配要点
Linux 内核里,eMMC 走的是 MMC 子系统。你需要关注这几个点:
- 设备树配置:在
arch/arm64/boot/dts/里添加 mmc 节点,设置 bus-width、non-removable、no-sd 等属性。 - HS400 模式:i.MX8 系列支持 HS400,但需要 tuning。我建议先降级到 HS200 验证稳定性,再切 HS400。
- Cache 与 Packed Command:eMMC 5.0 以上支持,能提升写入性能。但注意——有些旧批次芯片有 bug,开了会丢数据。
UFS 驱动适配要点
UFS 驱动相对复杂,因为涉及 UniPro 和 M-PHY 两层协议。以 i.MX8QM 为例:
// 内核配置
CONFIG_SCSI_UFSHCD=y
CONFIG_SCSI_UFS_QCOM=y
CONFIG_SCSI_UFSHCD_PLATFORM=y
// 设备树示例
&ufs {
status = "okay";
ref-clk-freq = <38400000>;
lanes-per-direction = <2>;
};
嗯,这里要注意:UFS 的参考时钟必须精确,否则链路训练会失败。我调试时吃过这个亏,折腾了两天才发现是晶振偏差超了 50ppm。
18.2 F2FS 文件系统优化
Android 从 8.0 开始推荐 F2FS 替代 ext4。为什么?因为 F2FS 是专门为 NAND Flash 设计的,能减少写放大,提升随机性能。
我个人习惯在 /data 分区用 F2FS,/system 和 /vendor 用 ext4(只读分区没必要上 F2FS)。
F2FS 挂载参数优化
# 推荐挂载参数
mount -t f2fs /dev/block/mmcblk0p4 /data \
-o noatime,nodiratime,inline_xattr,inline_data,flush_merge,extent_cache
inline_xattr:将小文件的扩展属性内联到 inode,减少 I/O。flush_merge:合并多个 flush 命令,降低延迟。extent_cache:缓存 extent 映射,提升大文件顺序读性能。
f2fs 的 reserved-blocks 设大一点。
F2FS 与 OTA 升级
OTA 升级时,系统要解压并写入大量小文件。F2FS 在这方面比 ext4 快 30%~50%。但有个坑——如果升级中途掉电,F2FS 的恢复速度比 ext4 慢。我建议在 OTA 脚本里先执行 fsck.f2fs -f 做一次强制检查。
18.3 存储性能测试
光调参数不行,得用数据说话。我常用的测试工具和指标:
| 测试项 | 工具 | 目标值(UFS 2.1) |
|---|---|---|
| 顺序读 | fio --rw=read --bs=1M | > 700 MB/s |
| 顺序写 | fio --rw=write --bs=1M | > 400 MB/s |
| 随机读 4K | fio --rw=randread --bs=4K | > 20K IOPS |
| 随机写 4K | fio --rw=randwrite --bs=4K | > 15K IOPS |
| 混合读写 | fio --rw=randrw --rwmixread=70 | 延迟 < 5ms |
跑测试时,我建议用 --direct=1 绕过 page cache,测出真实硬件性能。另外,记得先 echo 3 > /proc/sys/vm/drop_caches 清空缓存,否则数据不准。
18.4 加密存储:FBE 与 FDE
Android Automotive 要求全盘加密,但有两种方案:FDE(全盘加密)和 FBE(基于文件的加密)。
FDE(Full Disk Encryption)
FDE 是旧方案,加密整个 /data 分区。启动时输入密码,解密整个分区。缺点很明显——开机慢,而且一旦解锁,所有文件都可见。
配置方式:在 BoardConfig.mk 里设置 BOARD_USES_QCOM_FDE := true,并在 fstab 里加 encryptable=footer。
FBE(File Based Encryption)
FBE 是 Google 推荐的新方案。每个文件有自己的密钥,不同用户/配置文件之间隔离。车机里特别有用——你可以让导航数据加密,但媒体库不加密,提升性能。
配置 FBE 需要内核支持:
# 内核必须开启
CONFIG_FS_ENCRYPTION=y
CONFIG_DM_DEFAULT_KEY=y
CONFIG_KEY_DH_OPERATIONS=y
# fstab 示例
/dev/block/mmcblk0p4 /data f2fs noatime,nosuid,nodev,fileencryption=aes-256-xts
Android 12 以上还支持 metadata encryption,用单独的密钥加密文件系统元数据。我建议开启,因为元数据泄露也能暴露文件结构。
vold.decrypt 属性,导致开机后 vold 无法启动,卡在加密界面。排查了一整天,最后发现是 sepolicy 没给 vold 访问密钥环的权限。
18.5 知识体系总览
下面这张图总结了存储系统移植的核心模块和流程:
这张图把整个存储移植的脉络理清了。从左到右,从硬件到软件,从性能到安全。你移植的时候,就按这个顺序一步步来,基本不会漏项。
好了,存储系统这块内容不少,但核心就三点:选对硬件、调好驱动、配好加密。下一节咱们聊显示系统移植,那又是另一番天地了。