1、分区表是什么
基本概念:一张藏在芯片里的“地图”
分区表,说白了就是一张表格。它告诉系统:“你的存储空间被分成了几块,每块从哪开始、到哪结束、用来干什么。”
我刚开始接触嵌入式时,觉得分区表就是个简单的地址列表。后来踩过坑才明白——它其实是整个存储系统的“宪法”。没有它,BootROM 不知道去哪找代码,操作系统不知道去哪挂文件系统,甚至连你存的一张照片都可能把启动代码给覆盖掉。
一个典型的分区表条目,通常包含这些信息:
| 字段 | 含义 | 我见过的坑 |
|---|---|---|
| 分区名称 | 标识用途,如 boot、system、data | 名字别乱起,BootROM 只认固定名称 |
| 起始地址 | 在 Flash 中的偏移量 | 对齐问题,我曾经因为没 4K 对齐导致擦除失败 |
| 分区大小 | 该分区占用的空间 | 留太小,OTA 升级时空间不够 |
| 属性标志 | 可读、可写、可执行、加密等 | 忘了设可执行,CPU 直接跳飞 |
| 校验信息 | CRC 或哈希值 | 不加校验,坏块让你死得不明不白 |
核心理解:分区表就是存储设备的“目录索引”。BootROM 上电后第一件事就是读它,然后才知道“我该去哪找启动代码”。
为什么需要分区表?没有它会怎样?
你想想看,一块 Flash 芯片,上电后就是一片空白。CPU 怎么知道哪段存的是 bootloader、哪段是内核、哪段是文件系统?
没有分区表,只有两种结局:
- 硬编码地址——把每个模块的地址写死在代码里。换个 Flash 容量或布局,就得重新编译整个固件。我见过一个老项目,换了个同型号不同批次的 Flash,地址偏移变了 128 字节,整机变砖。
- 全盘扫描——BootROM 从头到尾搜一遍,找启动标记。这效率低得可怕,而且容易误判。我记得有款 IoT 芯片就是这么干的,启动时间长达 3 秒,客户直接退货。
分区表解决了三个核心问题:
- 隔离性——不同模块互不干扰。系统崩溃了,不会把 bootloader 也带崩。
- 可维护性——升级某个分区,不影响其他分区。OTA 升级就是靠这个。
- 可移植性——换 Flash 芯片,改分区表就行,不用动代码。
我的经验:做产品定义时,一定要预留一个“备用分区”。我曾经因为没留,遇到 Flash 坏块时只能降级发货,被客户骂了三个月。
分区表在存储设备中的角色
分区表不是“可有可无”的配置,它是存储系统的“交通警察”。
具体来说,它扮演了这几个角色:
- 地址翻译器——把逻辑分区名映射到物理地址范围。你写“写数据到 system 分区”,分区表告诉你“从 0x100000 到 0x200000”。
- 权限守卫——控制谁可以读写哪个区域。BootROM 只能读启动分区,普通应用不能碰安全分区。
- 坏块管理器——NAND Flash 天生有坏块,分区表要记录哪些块是坏的,避免写入。
- 升级保障——双分区备份(A/B 系统)就是靠分区表实现的。一个分区升级失败,回滚到另一个。
下面这张图,是我画的分区表在系统启动流程中的位置:
⚠️ 重要提醒:分区表一旦损坏,整个系统就废了。BootROM 找不到启动代码,连救砖模式都进不去。我处理过一起客诉,就是 Flash 某个坏块正好落在分区表区域,整批 2000 台设备全部变砖。从那以后,我坚持做分区表备份——在 Flash 末尾再存一份。
分区表的物理位置
分区表放在哪?这取决于芯片和 BootROM 的设计。常见的有三种:
- Flash 头部固定偏移——比如偏移 0x0000 或 0x0400。BootROM 硬编码了这个地址,上电直接读。最简单,也最脆弱。
- Flash 末尾备份——头部存一份,末尾存一份。头部坏了,BootROM 去末尾找。我现在的项目都这么干。
- 芯片内部 OTP——一次性可编程存储器,出厂就烧好。改不了,但最安全。适合量产定型的产品。
嗯,这里要注意:分区表本身也要有校验。我见过一个方案,分区表没有 CRC,结果 Flash 读出来错了一位,系统把数据分区当成了 bootloader,直接死机。
避坑指南:分区表最好用固定格式,不要用可变长度。我曾经用过一个可变长度分区表,解析代码里有个 off-by-one 错误,某些分区组合下会越界读取。查了三天才找到原因。从那以后,我只用固定 128 字节条目的分区表。
小结
分区表不是什么高深的东西。它就是一张表,告诉系统“哪块地种什么庄稼”。但就是这么一张表,决定了你的系统能不能稳定启动、能不能安全升级、能不能在 Flash 坏块面前活下来。
我个人习惯,做新项目时第一件事就是画分区布局图。把每个分区的大小、位置、属性、备份策略都写清楚。这个习惯帮我避了无数坑。