1. 课程导入

在嵌入式产品开发中,很多工程师第一次真正被“分区”绊住,往往不是在写驱动的时候,而是在烧录失败、OTA 升级变砖、量产镜像无法启动、日志区把文件系统写满的那一刻。分区设计看似只是把 Flash 切成几块,实际上它同时约束了启动流程、升级策略、数据持久化、安全校验和产线烧录方式。本课程的目标,是让“分区”从经验性操作变成可推导、可验证、可复用的工程设计能力。

一、学习目标:从会烧录到会设计

本课程不满足于让读者记住某款芯片的分区表格式,而是建立一套跨平台通用的分区设计方法。完成学习后,应达到以下四个层次的目标:

  • 认知层:理解 BootROM、SPL、U-Boot、Kernel、RootFS、DTB、环境变量、用户数据等典型镜像在存储介质上的角色与依赖关系。
  • 设计层:能根据存储容量、升级方式、掉电安全等级和量产工艺,推导出合理的分区数量、顺序、大小与对齐方式。
  • 实现层:能编写分区表、配置 U-Boot 环境、生成镜像包,并完成分区烧录与启动验证。
  • 排障层:能通过启动日志、分区表读取结果和校验值,定位“分区偏移错、大小越界、A/B 切换失败、环境变量丢失”等典型问题。

二、核心概念:分区不是切蛋糕,而是定义契约

分区(Partition)是存储介质上一段具有明确起止地址、用途和访问规则的连续区域。它本质上是一份“契约”:引导程序按契约找内核,内核按契约挂载根文件系统,升级程序按契约写入新镜像,产线工具按契约烧录。契约一旦被破坏,系统就无法启动或无法升级。

与分区紧密相关的核心概念包括:

概念 含义 典型对象
分区表 描述各分区偏移、大小、名称和属性的元数据 MBR、GPT、MTD partition、Rockchip parameter
镜像 写入某个分区的二进制内容 u-boot.bin、boot.img、rootfs.img
槽位 A/B 升级中互为备份的两组分区 boot_a / boot_b、rootfs_a / rootfs_b
环境变量区 保存启动参数和升级状态的可读写区域 U-Boot env、misc、persist
对齐 分区起始地址按擦除块或页大小对齐 4KB、64KB、128KB、2MB
分区设计的三个不变量:启动链上的分区必须按依赖顺序可寻址;可升级分区必须成对或可回滚;可写分区必须与只读分区隔离。

三、整体框架:一张图看清分区在系统中的位置

下图给出嵌入式系统分区设计的整体框架。左侧是存储介质上的物理分区布局,中间是启动与运行时的访问路径,右侧是升级、校验和产线工具对分区的操作入口。理解这张图,就能把后续章节中的启动流程、镜像制作、OTA 升级和故障排查串成一条线。

嵌入式系统分区设计整体框架 存储介质分区布局 BootROM / SPL 区 U-Boot 引导区 Kernel + DTB 区 RootFS 根文件系统 Env / Misc 状态区 UserData 用户数据区 A/B 备份槽位 启动与运行时访问 BootROM 加载 SPL U-Boot 读取分区表 加载 Kernel 与 DTB 挂载 RootFS 读取 Env 启动参数 挂载 UserData 升级 / 校验 / 产线 OTA 升级写入槽位 A/B 切换与回滚 签名与哈希校验 产线烧录工具 日志与故障诊断 恢复出厂设置 分区表是启动链、升级链与产线链的共同契约

四、实战路线图:从需求到可启动镜像

本课程按“需求分析 → 分区规划 → 镜像制作 → 烧录验证 → 升级与回滚 → 排障复盘”的路线推进。每一步都有明确的输入、输出和验收标准,避免只停留在概念层面。

  1. 需求分析:确认存储类型(NOR/NAND/eMMC/UFS)、容量、擦除块大小、是否支持 A/B、是否需要加密分区。
  2. 分区规划:确定分区数量、顺序、偏移、大小和对齐,输出分区表文件。
  3. 镜像制作:将 U-Boot、Kernel、DTB、RootFS 打包为可烧录镜像,并计算校验值。
  4. 烧录验证:使用产线工具写入分区,读取回校验,确认启动日志中分区识别正确。
  5. 升级与回滚:实现 A/B 槽位切换、升级状态标记和失败回滚。
  6. 排障复盘:针对启动失败、分区越界、环境变量丢失等问题建立检查清单。
建议在项目早期就固定分区表版本号,并把分区表纳入版本管理。分区表一旦量产后再调整,往往需要同步修改引导程序、升级包和产线工具,代价远高于前期规划。

五、案例场景:一次典型的启动失败

某工业网关使用 eMMC 存储,分区顺序为 boot、kernel、rootfs、data。工程师在调试阶段把 rootfs 镜像从 180MB 增大到 260MB,但没有调整后续 data 分区的偏移。烧录后系统卡在 U-Boot,日志显示:

Loading Kernel from mmc 0:2 ...
** Unable to read file boot.img **
Bad Linux ARM zImage magic!

表面看是内核镜像损坏,实际原因是 rootfs 分区扩大后覆盖了 kernel 分区尾部,导致 kernel 镜像被截断。这个案例说明:分区大小不是孤立的参数,任何一个分区的调整都会影响后续分区的偏移和边界。正确的做法是先计算所有分区总容量,预留升级余量,再统一生成分区表。

六、常见误区与复盘要点

  • 误区一:分区越多越好。分区过多会增加管理复杂度,且每个分区都要对齐,浪费空间。应按功能合并,如将只读系统资源合并进 rootfs。
  • 误区二:忽略擦除块对齐。NAND 擦除块通常为 128KB,分区起始地址未对齐会导致读写异常或性能下降。
  • 误区三:把环境变量区放在可写文件系统内。一旦文件系统损坏,启动参数丢失,设备无法恢复。Env 应独立分区并保留备份。
  • 误区四:A/B 槽位只做镜像备份,不做状态标记。没有升级状态位,设备无法判断当前应启动哪个槽位,也无法回滚。
  • 误区五:量产前不验证分区表。应在样机阶段用读回校验和启动日志双重确认分区边界。
分区设计中最危险的错误不是“分区太小”,而是“分区边界没有校验”。建议在烧录工具中加入分区表合法性检查:偏移递增、大小非零、总容量不越界、关键分区对齐。