4. 常见分区方案
在嵌入式系统中,Flash 分区方案决定了系统能否稳定启动、升级是否安全、数据是否可恢复。一个成熟的分区表通常不是“随便切几块”,而是围绕启动链、系统镜像、用户数据、恢复机制和配置持久化来设计。本节将围绕 Bootloader、Kernel、Rootfs、Data、Recovery、Config 等典型分区,说明它们的功能、布局顺序和设计要点。
一、核心原理:分区是启动链与数据生命周期的边界
嵌入式设备上电后,CPU 首先执行固化在 ROM 中的引导代码,然后跳转到外部 Flash 的 Bootloader 分区。Bootloader 负责初始化 DDR、时钟、存储控制器,加载 Kernel 到内存并传递启动参数。Kernel 启动后挂载 Rootfs,运行 init 进程和用户空间服务。Data 分区用于保存运行期产生的用户数据、日志、数据库;Config 分区保存设备参数、网络配置、校准数据;Recovery 分区则提供独立的最小系统,用于恢复出厂、OTA 升级失败回滚或紧急修复。
因此,分区方案的本质是:把“不可变”的系统镜像与“可变”的用户数据分开,把“正常启动”与“异常恢复”分开,把“可升级”与“不可升级”分开。这样既能保证启动链的确定性,又能让升级和恢复互不干扰。
二、方法流程:如何规划一张分区表
规划分区表时,建议按以下步骤推进:
- 确认存储介质与容量:NOR Flash、NAND Flash、eMMC、UFS 的分区对齐和擦除块大小不同,直接影响分区边界。
- 列出启动链所需镜像:Bootloader(可能分 SPL、U-Boot)、Kernel、DTB、Rootfs、Recovery、Misc。
- 区分只读与可读写:系统镜像通常只读,Config 和 Data 必须可读写,并考虑磨损均衡和掉电保护。
- 确定升级策略:单分区升级、A/B 双分区升级还是 Recovery 升级,决定是否需要备份分区。
- 预留余量:每个分区至少预留 10%~20% 空间,避免后续功能增加导致分区溢出。
- 固定偏移与大小:在分区表中写死偏移地址和大小,确保 Bootloader 能按固定地址加载镜像。
关键原则:Bootloader 必须知道 Kernel 和 Rootfs 的固定偏移;Kernel 必须知道 Rootfs 的挂载点;Recovery 必须独立于正常系统,不能依赖 Rootfs 中的文件。
三、案例/场景:一个典型 4GB eMMC 分区表
下面是一个常见的嵌入式 Linux 设备分区表,采用 A/B 双分区升级策略,适用于需要 OTA 升级和回滚的产品。
# 典型 4GB eMMC 分区表(单位:MB)
Name Offset Size Mount 说明
bootloader 0 4 - SPL + U-Boot
env 4 1 - 环境变量
boot_a 8 64 - Kernel + DTB A
boot_b 72 64 - Kernel + DTB B
rootfs_a 136 1024 / Rootfs A(只读)
rootfs_b 1160 1024 / Rootfs B(只读)
config 2184 64 /config 设备配置、校准数据
data 2248 1600 /data 用户数据、日志
recovery 3848 128 - Recovery 镜像
misc 3976 16 - 启动标志、升级命令
在这个方案中,Bootloader 首先读取 misc 分区中的启动标志,决定从 boot_a 还是 boot_b 启动。如果正常系统启动失败,Bootloader 会切换到 Recovery 分区,由 Recovery 执行恢复出厂或重新升级。Config 和 Data 分区在升级时通常保留,避免用户数据丢失。
四、误区与复盘
常见误区一:把 Config 和 Data 混在一起。Config 保存的是设备出厂参数和关键配置,升级时不应被覆盖;Data 保存的是用户运行数据,升级时可以保留但允许清理。两者混用会导致升级后配置丢失或用户数据被误删。
常见误区二:Recovery 依赖 Rootfs。如果 Recovery 需要挂载 Rootfs 才能运行,那么 Rootfs 损坏时 Recovery 也会失效。Recovery 必须是独立的最小系统,自带内核和文件系统。
常见误区三:分区没有对齐。NAND Flash 和 eMMC 都有擦除块和页大小,分区起始地址未对齐会导致读写性能下降甚至驱动报错。
常见误区四:忽略 Misc 分区。Misc 虽然很小,但它是 Bootloader 与 Recovery 之间的通信桥梁,缺少它会导致升级标志无法传递,A/B 切换失效。
复盘时,可以用一张清单检查分区方案是否完整:
| 检查项 | 要求 | 常见问题 |
|---|---|---|
| Bootloader | 固定偏移、可串口恢复 | 偏移写错导致无法启动 |
| Kernel + DTB | 与 Bootloader 约定加载地址 | DTB 与内核版本不匹配 |
| Rootfs | 只读挂载、支持 A/B | 根文件系统被写坏 |
| Config | 独立分区、掉电保护 | 与 Data 混用导致丢失 |
| Data | 可读写、预留余量 | 空间不足导致服务异常 |
| Recovery | 独立最小系统 | 依赖 Rootfs 无法恢复 |
| Misc | 保存启动标志和升级命令 | 缺失导致 A/B 切换失败 |
实践建议:在项目早期就把分区表固定下来,并写入 Bootloader 和内核的配置文件中。每次修改分区大小或偏移,都要同步更新烧录脚本、OTA 升级包和恢复工具,避免“分区表不一致”导致的批量故障。
总之,Bootloader、Kernel、Rootfs、Data、Recovery、Config 等分区不是孤立的存储块,而是一条从启动到运行、从升级到恢复的完整链路。合理的分区布局能让系统启动更可靠、升级更安全、数据更可控,也能在出现故障时快速定位和恢复。