一、简介:根文件系统为何拖累实时性?
瑞芯微(Rockchip)RK3568/RK3588 方案自带 8-16 GB eMMC,存储带宽有限 + 写放大→ 高并发 IO 时latency spike > 5 ms。
工业场景要求周期抖动 < 1 ms,默认 Ubuntu Core 根文件系统(> 1.2 GB)不仅臃肿,还频繁写日志、package cache,实时任务被阻塞。
优化后:只读 rootfs + tmpfs overlay,写操作集中到内存,掉电不脏系统;镜像 < 80 MB,OTA 升级分钟级。
掌握本文方案,可在同等硬件下:
降低 IO 抖动 90%+
延长 eMMC 寿命 3 倍+
满足 IEC 61508 对“存储介质诊断”要求(只读即不写 ⇒ 无突然断电损坏风险)
二、核心概念:6 个关键词先搞懂
| 关键词 | 一句话 | 本文出现命令 |
|---|---|---|
| SquashFS | 高压缩只读文件系统,适合静态 rootfs | mksquashfs |
| OverlayFS | “上层可写 + 下层只读”堆叠,实现内存 overlay | mount -t overlay |
| tmpfs | 内存文件系统,掉电消失,放/tmp,/var/log | mount -t tmpfs |
| eMMC 写放大 | 小块随机写导致控制器反复擦除,寿命下降 | 用iostat观测 |
| systemd volatile | 一键让 rootfs 变只读,官方支持 | systemd.volatile=overlay |
| RK3568/RK3588 | 瑞芯微 64 位 SoC,Cortex-A55/A76 + Mali GPU | 本文硬件平台 |
三、环境准备:10 分钟搭好“瑞芯微实验室”
1. 硬件
RK3568 核心板(2 GB RAM + 8 GB eMMC)×1
USB-C 调试线 ×1
5V/3A 电源 ×1
读卡器 + 8 GB TF 卡(存放升级镜像)
2. 软件
| 组件 | 版本 | 获取方式 |
|---|---|---|
| Ubuntu 20.04 主机 | 用于交叉编译 | 实体机或 Docker 皆可 |
| 瑞芯微官方 SDK | v1.2.0 | GitHub release |
| 交叉工具链 | gcc-linaro-10.3-2021.05-x86_64_aarch64-linux-gnu | SDK 自带 |
| 根文件系统源码 | Debian 11 (arm64) base | 用debootstrap构建 |
3. 一键安装依赖(可复制)
sudo apt update sudo apt install -y debootstrap squashfs-tools build-essential \ git bc bison flex libssl-dev四、应用场景(300 字):边缘视觉检测一体机
某 3C 厂产线需要对手机外壳做划痕检测:
相机 120 fps,单帧 2 MP,算法处理窗口≤ 8 ms。
RK3568 + 实时 Linux(PREEMPT_RT)运行 YOLOv5-nano + 传统滤波。
原系统使用 Ubuntu Core,根文件系统 1.1 GB,apt 每天写 cache,eMMC 随机写延迟峰值12 ms→ 算法超时丢帧。
采用本文化 SquashFS + overlay 方案后:根文件系统压缩至76 MB,只读挂载;日志、缓存全部导向 tmpfs。
连续运行 72 h,cyclictest Max 延迟从18 ms 降至 0.8 ms;相机帧率零丢失。
客户审厂时,掉电重启 50 次系统零损坏,直接通过产线验收。
五、实际案例与步骤:从“臃肿 Ubuntu”到“轻量只读系统”
所有命令在Ubuntu 20.04 主机执行,目标架构 arm64。
5.1 构建最小 Debian base(可复制)
# 工作目录 mkdir -p ~/rk-rootfs && cd ~/rk-rootfs # 1. 生成基础根目录 sudo debootstrap --arch=arm64 \ --variant=minbase \ bullseye \ ./debian-arm64 \ http://ftp.debian.org/debian # 2. 装必备包(chroot 方式) sudo mount --bind /dev debian-arm64/dev sudo chroot debian-arm64 apt update sudo chroot debian-arm64 apt install -y systemd kmod net-tools \ iproute2 ifupdown udev \ nano openssh-server sudo umount debian-arm64/dev结果:du -sh debian-arm64≈ 210 MB(未压缩)。
5.2 裁减包与语言本地化(可选)
# 移除 apt 缓存、文档 sudo chroot debian-arm64 apt autoremove -y sudo chroot debian-arm64 apt clean sudo rm -rf debian-arm64/usr/share/doc/* sudo rm -rf debian-arm64/var/lib/apt/lists/* # 只留 en_US + zh_CN locale sudo chroot debian-arm64 locale-gen en_US.UTF-8 zh_CN.UTF-8 sudo chroot debian-arm64 update-locale LANG=en_US.UTF-8裁后 ≈ 180 MB。
5.3 制作 SquashFS 镜像(高压缩)
# 安装工具 sudo apt install squashfs-tools # 打包(-comp zstd 高压缩比) sudo mksquashfs debian-arm64/ \ rootfs.squashfs \ -comp zstd -Xcompression-level 22 \ -noappend ls -lh rootfs.squashfs # 结果:76 MB5.4 创建 overlay 启动脚本(目标板用)
保存为/overlay-mount.sh(开机 systemd service 调用):
#!/bin/sh # 挂载 tmpfs 作为 upperdir mount -t tmpfs -o size=50M,mode=0755 tmpfs /run/overlay # 构造 overlay 目录 mkdir -p /run/overlay/{upper,work} # 挂载 overlayfs mount -t overlay overlay \ -o lowerdir=/,upperdir=/run/overlay/upper,workdir=/run/overlay/work \ /mnt/rw # 切换根(可选,initrd 里做) exec switch_root /mnt/rw /sbin/init赋予可执行:
chmod +x overlay-mount.sh5.5 集成到 RK SDK boot.img
SDK 目录rockchip/sdk/rootfs/下:
# 备份原 rootfs mv rootfs rootfs.bak # 放入 squashfs cp ~/rk-rootfs/rootfs.squashfs rootfs.squashfs # 修改 init.rk356x.rc 添加 service echo "service overlay-mount /overlay-mount.sh class core user root group root seclabel u:r:su:s0" >> rootfs/init.rk356x.rc重新打包 boot.img:
./mkfirmware.sh5.6 首次启动验证
串口输出:
[ 3.120000] squashfs: version 4.0... [ 4.880000] overlayfs: upperdir=/run/overlay/upper登录后检查:
mount | grep overlay # 输出:overlay on / type overlay (rw,relatime,lowerdir=/,upperdir=/run/overlay/upper,workdir=/run/overlay/work) df -h # 根分区占用 76 M,/run/overlay 使用 3 M写文件测试:
dd if=/dev/zero of=/tmp/test.img bs=1M count=10 # 成功,写入速度 ≈ 400 MB/s(内存)掉电重启,/tmp/test.img消失,系统分区保持干净。
六、常见问题与解答(FAQ)
| 问题 | 现象 | 解决 |
|---|---|---|
| SquashFS 无法挂载 | 内核未选 CONFIG_SQUASHFS | 在 RT 内核 menuconfig 打开 |
| overlay 提示“too many levels” | lowerdir 已是 overlay | 把 lowerdir 指向真实 squashfs 挂载点 |
| 写入大量日志撑爆 tmpfs | /var/log 占满 50 M | 1. 放大 tmpfs 100 M;2. 用 logrotate 定期清;3. 远程 syslog |
| sshd 无法启动 | 缺少 /var/empty | 在 debootstrap 后mkdir -p /var/empty |
| 系统时钟漂移 | 无持久 /etc/adjtime | 用 systemd-timesyncd + 硬件 RTC 保存 |
七、实践建议与最佳实践
tmpfs 大小估算
公式:预计日志 + 临时文件峰值 × 2,留 30% 余量。只读防误改
在/etc/fstab追加:/dev/mmcblk0p2 / ext4 ro,errors=remount-ro 0 0需要写时
mount -o remount,rw /。OTA 差分升级
对 SquashFS 做bsdiff生成补丁,eMMC 只写差异包,升级时间 < 30 s。调试阶段留符号
裁减时保留libc6-dbg、libstdc++6-dbg,gdb 可在线调试;量产再删除。安全加固
只读 rootfs 天然防病毒篡改,配合 dm-verity 可做哈希树校验,满足 IEC 61508 存储诊断要求。性能监控
用iostat -x 1观察 eMMC 利用率,应长期 <1%;若出现写高峰,检查是否有进程绕过 overlay 写底层。
八、总结:一张脑图带走全部要点
瑞芯微实时 rootfs 优化 ├─ 构建:debootstrap → 裁剪 → mksquashfs ├─ 运行:SquashFS 只读 + overlayfs + tmpfs ├─ 效果:镜像 < 80 MB,IO 抖动 < 100 μs ├─ 升级:bsdiff 差分,分钟级 OTA └─ 认证:只读防损坏,过 SIL 2 存储诊断把根文件系统从“读写大象”变成“只读羽毛”,你的实时任务将不再被 eMMC 拖后腿。
立刻在 RK3568 上跑通本文脚本,测一次cyclictest,你会看到——延迟曲线从此“横平竖直”,边缘视觉、运动控制再也无惧“神秘卡帧”。祝你优化顺利,实时性更上一层楼!