4. 常见分区方案

在嵌入式系统中,Flash 分区方案决定了系统能否稳定启动、升级是否安全、数据是否可恢复。一个成熟的分区表通常不是“随便切几块”,而是围绕启动链、系统镜像、用户数据、恢复机制和配置持久化来设计。本节将围绕 Bootloader、Kernel、Rootfs、Data、Recovery、Config 等典型分区,说明它们的功能、布局顺序和设计要点。

一、核心原理:分区是启动链与数据生命周期的边界

嵌入式设备上电后,CPU 首先执行固化在 ROM 中的引导代码,然后跳转到外部 Flash 的 Bootloader 分区。Bootloader 负责初始化 DDR、时钟、存储控制器,加载 Kernel 到内存并传递启动参数。Kernel 启动后挂载 Rootfs,运行 init 进程和用户空间服务。Data 分区用于保存运行期产生的用户数据、日志、数据库;Config 分区保存设备参数、网络配置、校准数据;Recovery 分区则提供独立的最小系统,用于恢复出厂、OTA 升级失败回滚或紧急修复。

因此,分区方案的本质是:把“不可变”的系统镜像与“可变”的用户数据分开,把“正常启动”与“异常恢复”分开,把“可升级”与“不可升级”分开。这样既能保证启动链的确定性,又能让升级和恢复互不干扰。

典型嵌入式 Flash 分区布局与启动数据流 Flash 地址空间(从低地址到高地址) Bootloader Kernel Rootfs Config Data Recovery Misc Bootloader 初始化 DDR/时钟 加载 Kernel 与 DTB 传递 bootargs 支持 fastboot/串口下载 Kernel Linux 内核镜像 设备树 DTB 驱动与文件系统挂载 通常只读、可升级 Rootfs 根文件系统 init、库、应用 squashfs/ext4/ubifs A/B 双分区可回滚 Config / Data Config:设备参数、MAC Data:日志、数据库 可读写、需掉电保护 升级时通常保留 Recovery 与 Misc 的异常恢复路径 Recovery 最小系统 / OTA 升级 Misc 启动标志 / 升级命令 Bootloader 判断 读取 misc 决定启动槽位 正常系统 / Recovery 失败则回滚到可用分区

二、方法流程:如何规划一张分区表

规划分区表时,建议按以下步骤推进:

  1. 确认存储介质与容量:NOR Flash、NAND Flash、eMMC、UFS 的分区对齐和擦除块大小不同,直接影响分区边界。
  2. 列出启动链所需镜像:Bootloader(可能分 SPL、U-Boot)、Kernel、DTB、Rootfs、Recovery、Misc。
  3. 区分只读与可读写:系统镜像通常只读,Config 和 Data 必须可读写,并考虑磨损均衡和掉电保护。
  4. 确定升级策略:单分区升级、A/B 双分区升级还是 Recovery 升级,决定是否需要备份分区。
  5. 预留余量:每个分区至少预留 10%~20% 空间,避免后续功能增加导致分区溢出。
  6. 固定偏移与大小:在分区表中写死偏移地址和大小,确保 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 等分区不是孤立的存储块,而是一条从启动到运行、从升级到恢复的完整链路。合理的分区布局能让系统启动更可靠、升级更安全、数据更可控,也能在出现故障时快速定位和恢复。