2. rootfs分区布局设计:双分区(A/B)方案、单分区+备份方案、分区表与挂载点规划
分区布局这事儿,说白了就是给系统找个「安全屋」。我做了这么多年嵌入式,见过太多因为分区设计不合理导致升级变砖的惨案。今天咱们就把这块硬骨头啃下来。
2.1 双分区(A/B)方案:工业级标配
双分区方案,也叫A/B分区。简单说就是准备两套完整的rootfs,一套运行,一套待命。我个人习惯叫它「影子系统」。
核心思想:任何时候都有两个可启动的系统副本。升级时写入备用分区,下次启动切换。
分区布局示例
/dev/mmcblk0p1 → boot_a (内核+dtb)
/dev/mmcblk0p2 → rootfs_a (系统A)
/dev/mmcblk0p3 → boot_b (内核+dtb)
/dev/mmcblk0p4 → rootfs_b (系统B)
/dev/mmcblk0p5 → data (用户数据)
/dev/mmcblk0p6 → misc (元数据)
我在项目中遇到过一个问题:某次升级写到一半断电了,系统A损坏。但因为有B分区,设备重启后自动回滚到B,用户完全无感。这就是双分区的价值。
工作流程
- 正常启动:uboot读取misc分区,决定从A还是B启动
- 升级触发:系统运行时,将新版本写入非活动分区
- 校验切换:写入完成后,更新misc分区标记,下次启动切换
- 回滚机制:如果新系统启动失败,uboot自动切回旧分区
避坑指南:我曾经遇到过misc分区写坏导致无法切换的情况。后来我强制要求misc分区使用独立物理块,并且每次写入前做CRC校验。嗯,这招很管用。
2.2 单分区+备份方案:轻量级选择
双分区虽好,但存储成本高。对于资源受限的设备(比如8MB Flash),单分区+备份方案更实际。
说白了就是:一个主分区跑系统,一个压缩包存备份。升级时先解压备份到临时区,再覆盖主分区。
典型布局
/dev/mtdblock0 → bootloader (uboot)
/dev/mtdblock1 → rootfs (主系统)
/dev/mtdblock2 → backup (压缩的系统备份)
/dev/mtdblock3 → config (配置参数)
升级流程
- 下载新固件到内存
- 将当前rootfs压缩备份到backup分区
- 擦除rootfs分区,写入新固件
- 重启验证
- 如果启动失败,从backup分区恢复
注意:单分区方案有个致命弱点——升级过程中断电,系统就挂了。你想想看,擦除一半断电,rootfs就没了。所以必须配合看门狗和掉电保护电路。
2.3 分区表与挂载点规划
分区表设计,我建议遵循「最小权限」原则。每个分区只挂载它需要的东西,别搞大杂烩。
推荐分区表
| 分区 | 大小 | 文件系统 | 挂载点 | 说明 |
|---|---|---|---|---|
| boot | 64MB | ext4 | /boot | 内核、dtb、uboot环境 |
| rootfs | 512MB | squashfs | / | 只读系统,防篡改 |
| data | 剩余 | ext4 | /data | 用户数据、日志、配置 |
| overlay | 128MB | ext4 | /overlay | overlayfs上层,可写 |
为什么rootfs用squashfs?因为它是只读的,能防止意外修改。我见过有人用ext4做rootfs,结果一次误操作rm -rf /,系统直接废了。squashfs就没这问题。
挂载点规划示例
# /etc/fstab
/dev/mmcblk0p1 /boot ext4 defaults 0 0
/dev/mmcblk0p2 / squashfs ro 0 0
/dev/mmcblk0p3 /data ext4 defaults 0 0
/dev/mmcblk0p4 /overlay ext4 defaults 0 0
overlay / overlay lowerdir=/,upperdir=/overlay/upper,workdir=/overlay/work 0 0
个人经验:我习惯把日志和临时文件挂载到tmpfs上,减少对Flash的写入。比如/var/log用tmpfs,重启就清空,省心。
2.4 核心逻辑流程图
下面这张图,是我自己总结的分区决策流程。你一看就明白什么时候该用哪种方案。
2.5 避坑总结
做了这么多年,我踩过的坑能写本书。这里挑几个最要命的说说:
- 分区大小别卡太死:我曾经给rootfs只留了256MB,结果一次日志暴涨直接撑爆。现在我都留30%余量。
- uboot环境变量要备份:有一次升级把uboot环境搞乱了,设备变砖。后来我强制要求环境变量存两份。
- 挂载顺序有讲究:overlayfs必须先挂载底层,再挂载上层。顺序错了系统都起不来。
最后提醒一句:分区设计不是一劳永逸的。产品迭代过程中,分区大小、布局都可能需要调整。我建议在硬件设计阶段就预留分区扩展接口,比如用GPT分区表而不是MBR,方便以后调整。
好了,分区布局这块就聊到这儿。下一章咱们聊聊升级包的制作和签名,那又是另一番天地。