嵌入式产品设计时,需要在启动可靠性与应用运行需求之间找到平衡。合理的存储分区与目录规划,是确保系统稳定、数据安全及后期维护便捷的关键基础。
常见分区角色与规划
| 分区/区域 |
作用 |
建议属性/挂载 |
典型内容 |
| Bootloader |
上电引导 |
只读 |
u-boot/SPL/引导脚本 |
| Kernel |
内核镜像 |
只读 |
zImage/Image + 设备树(DTB) |
| RootFS (A/B) |
系统根文件系统 |
只读/RO+verity |
/usr、/bin、/sbin、基础库 |
| App/Opt |
应用程序与第三方库 |
读写/可选只读 |
/opt、/usr/local、应用可执行文件 |
| Config |
配置文件与持久化参数 |
读写 |
/etc(若单独分区),/data/conf |
| Data |
运行数据、数据库、缓存 |
读写 |
/data、/var、数据库文件、缓存 |
| Log |
日志与故障转储文件 |
读写 |
/var/log、/data/log |
| OTA/Update |
升级包缓存与解压区域 |
读写 |
/ota、/cache/update |
| Factory/Calib |
校准数据与出厂信息 |
只读/限写 |
序列号、校准参数、设备证书 |
| Tmpfs |
内存临时目录 |
tmpfs |
/tmp、/run |
典型分区布局参考
1. 单系统 + 数据分离 (常见于 eMMC/NAND)
| Bootloader | Kernel | RootFS(ro) | App(rw) | Config(rw) | Data(rw) | Log(rw) | OTA(rw) |
特点:根文件系统保持只读,实现系统与应用的解耦。适用于资源有限且无需A/B系统冗余升级的产品。
2. A/B 系统冗余 + 数据分离 (高可靠性设计)
| Bootloader | KernelA | KernelB | RootA(ro) | RootB(ro) | App(rw) | Config(rw) | Data(rw) | Log(rw) | OTA(rw) |
特点:内核与根文件系统分区双冗余,配合启动标志位与健康状态检测可实现升级失败自动回滚,极大提升系统可靠性。
3. Squashfs + OverlayFS (只读根 + 可写层)
| Bootloader | Kernel | RootFS.squashfs(ro) | Overlay(rw) | Data/Log(rw) | OTA(rw) |
特点:根文件系统以Squashfs只读压缩镜像形式存放,提高了存储利用率和系统安全性;通过OverlayFS提供统一的可写层,易于系统恢复。
目录规划与挂载实践
系统只读层
- 目录:
/usr, /bin, /sbin, /lib, /lib64。这些是系统基础命令和库,通常放置在只读根分区或Squashfs镜像中,避免运行时被意外修改。
- /etc处理:如果需要频繁修改配置文件,可将
/etc目录单独挂载到config分区,或通过OverlayFS叠加到可写层;若根文件系统只读,通常将/etc软链接或绑定挂载到可写区。
应用与第三方库
- 目录:
/opt 或 /usr/local。用于放置自研应用程序、第三方库或插件。可以考虑为其单独分区,便于应用的独立升级、回滚和管理。
- 权限控制:可执行文件通常设置为
0755,配置文件为0644。应严格控制应用目录的写入权限,防止应用文件被意外篡改。
配置与持久化参数
- 目录:
/data/conf 或单独挂载的可写版/etc。
- 内容:设备唯一标识、网络与业务配置、密钥引用(密钥本身建议存储在安全元件或可信执行环境中)。
- 保护:对重要配置可采用校验和或加密存储;同时应限制写入频率,以减缓对NAND Flash或eMMC存储介质的损耗。
数据与数据库
- 目录:
/data,数据库文件可存放在/data/db等子目录中。
- 文件系统:挂载时选择ext4、F2FS等支持日志与掉电一致性的文件系统,并启用
noatime挂载选项以减少不必要的写入操作,这是Linux系统优化中常见的IO调优手段。
- 管理策略:对历史数据实施定期压缩或归档;根据访问频率实行分级存储策略,区分热数据与冷数据。
日志与故障转储
- 目录:
/var/log 或 /data/log;内核崩溃转储文件可存放在/var/crash。
- 大小与轮转:必须配置logrotate或基于大小的日志轮转策略,限制日志的写入速率和总大小,以防止日志写满存储空间或过度消耗Flash寿命。
- 分级管理:区分运行日志、调试日志、升级日志等;关键日志可配置异步上报机制。
OTA升级缓存
- 目录:
/ota 或 /cache/update。
- 要求:预留足够空间存放完整升级包;升级包需经过完整性校验(如SHA256)和签名验证;下载区与解包区最好分离。
- 清理:升级成功后应及时删除旧版本升级包,释放存储空间。
临时与运行时目录
- 目录:
/tmp, /run。建议使用tmpfs(内存文件系统)挂载,掉电后数据自动丢失,避免将临时文件写入持久化存储。
- 用途:IPC通信文件、PID文件、Socket文件等应放在
/run目录,防止污染持久化数据分区。
出厂/校准/证书存储
- 目录:
/factory 或 /calib,应设置为只读或严格限制写入权限。
- 内容:设备序列号、硬件校准参数、设备证书、非对称加密的公钥等。
- 保护:文件权限可设置为
0400或0500;必要时可使用dm-crypt加密或交由TEE(可信执行环境)保护。
安全与可靠性设计要点
- 只读根文件系统:采用Squashfs/EROFS + OverlayFS的方案,从根源上阻断运行时对系统文件的篡改。结合dm-verity可以进一步检测文件系统完整性。
- A/B冗余与回滚:为内核和根分区维护A/B两套副本,升级后通过健康探测程序验证新系统。若验证失败,Bootloader应能根据预设策略自动回滚至旧版本,并记录失败次数。
- 权限最小化原则:每个分区、目录都按需设置为只读或读写,文件权限遵循最小化原则。日志与数据分区应避免存放具有setuid权限的程序。
- 控制写入放大:通过日志轮转、使用
noatime挂载选项、合并小写入请求等方式减少对Flash的写入量。对于数据库,应根据数据重要性合理配置WAL(Write-Ahead Logging)和FSync策略,这与后端服务中数据库的持久化配置思路相通。
- 完整性与签名校验:内核镜像、根文件系统镜像、OTA升级包等关键固件都应进行数字签名校验,确保来源可信与内容完整。关键配置文件也可附加哈希校验值。
- 备份与恢复机制:对重要配置和用户数据建立定期备份机制。同时提供恢复出厂设置功能,该功能应能清空可写分区但保留
factory分区的原始信息。
挂载方案配置示例
以下是一个结合了只读根、OverlayFS和独立数据分区的/etc/fstab配置示例:
# 1. 挂载只读的根文件系统(Squashfs镜像)
/dev/mmcblk0p3 /ro_root squashfs ro,defaults 0 0
# 2. 使用OverlayFS将可写层叠加到只读根上,形成最终根目录
overlay / overlay lowerdir=/ro_root,upperdir=/overlay/upper,workdir=/overlay/work 0 0
# 3. 挂载应用与数据分区
/dev/mmcblk0p4 /opt ext4 rw,noatime 0 2 # 应用分区
/dev/mmcblk0p5 /data ext4 rw,noatime 0 2 # 主数据分区
/dev/mmcblk0p6 /data/log ext4 rw,noatime 0 2 # 日志目录,作为数据子目录挂载
/dev/mmcblk0p7 /ota ext4 rw,noatime 0 2 # OTA分区
# 4. 使用tmpfs挂载临时目录
tmpfs /tmp tmpfs defaults,size=64m 0 0
tmpfs /run tmpfs defaults,size=16m 0 0
此方案清晰划分了系统、应用、数据和临时区域,良好的目录结构规划是构建稳定系统的基石,便于维护且提升了整体可靠性。
|