下面是一个比较符合 ESP32-S31/ESP-IDF 架构的启动与分区表关系图。
ESP32-S31 启动流程图
┌──────────────────────┐
│ Power On │
│ 上电复位 │
└──────────┬───────────┘
│
▼
┌──────────────────────┐
│ ROM Boot │
│ 芯片内部固化代码 │
└──────────┬───────────┘
│
│ 通过 SPI0/1(MSPI)
▼
┌──────────────────────┐
│ Flash 0x0000 │
│ Bootloader │
└──────────┬───────────┘
│
▼
┌──────────────────────┐
│ Flash 0x8000 │
│ Partition Table │
│ (分区表) │
└──────────┬───────────┘
│
▼
┌──────────────────────┐
│ 解析所有分区信息 │
└──────────┬───────────┘
│
▼
┌──────────────────────┐
│ OTA Data 分区 │
│ 当前激活镜像? │
└───────┬───────┬──────┘
│ │
Factory OTA_0/1
│ │
└───┬───┘
▼
┌──────────────────────┐
│ 选择应用分区 │
│ Factory/OTA0/OTA1 │
└──────────┬───────────┘
│
▼
┌──────────────────────┐
│ MMU建立Flash映射 │
│ 0x42000000(IROM) │
│ 0x3C000000(DROM) │
└──────────┬───────────┘
│
▼
┌──────────────────────┐
│ Jump To App │
│ app_main() │
└──────────┬───────────┘
│
▼
┌──────────────────────┐
│ 应用运行阶段 │
│ │
│ NVS │
│ SPIFFS/LittleFS │
│ User Data │
│ OTA Upgrade │
└──────────────────────┘
Flash分区布局示意图
以 16MB Flash 为例:
Flash
0x000000
│
├─────────────────────────────┐
│ Bootloader │
│ 约32KB │
└─────────────────────────────┘
0x008000
├─────────────────────────────┐
│ Partition Table │
│ 4KB │
└─────────────────────────────┘
0x009000
├─────────────────────────────┐
│ NVS │
│ WiFi配置 │
│ SN │
│ Calibration │
└─────────────────────────────┘
0x00F000
├─────────────────────────────┐
│ OTA Data │
│ 当前启动镜像信息 │
└─────────────────────────────┘
0x010000
├─────────────────────────────┐
│ Factory App │
│ 出厂固件 │
└─────────────────────────────┘
0x210000
├─────────────────────────────┐
│ OTA_0 │
│ 当前运行版本 │
└─────────────────────────────┘
0x410000
├─────────────────────────────┐
│ OTA_1 │
│ 新下载版本 │
└─────────────────────────────┘
0x610000
├─────────────────────────────┐
│ SPIFFS / FATFS │
│ 配置文件 │
│ 图片资源 │
│ 字库资源 │
└─────────────────────────────┘
0xF00000
├─────────────────────────────┐
│ User Data │
│ 日志 │
│ 产品信息 │
└─────────────────────────────┘
OTA升级切换流程
当前运行 OTA_0
│
▼
下载新固件
到 OTA_1
│
▼
校验镜像
│
▼
更新 OTA Data
│
▼
重启
│
▼
Bootloader
读取分区表
│
▼
发现 OTA_1 有效
│
▼
启动 OTA_1
│
▼
运行成功 ?
┌──┴──┐
│ │
YES NO
│ │
▼ ▼
保持 回滚
OTA_1 OTA_0
软件访问分区关系
app_main()
│
├── nvs_open()
│ │
│ ▼
│ NVS分区
│
├── esp_ota_begin()
│ │
│ ▼
│ OTA_1分区
│
├── esp_partition_read()
│ │
│ ▼
│ User Data分区
│
└── esp_vfs_spiffs_register()
│
▼
SPIFFS分区
一句话理解:
ROM
↓
Bootloader
↓
Partition Table
↓
选择APP
↓
MMU映射Flash
↓
运行APP
↓
APP再根据Partition Table访问
NVS / OTA / 文件系统 / 用户数据
所以在 ESP32-S31 中,分区表既是 Bootloader 的"启动导航表",也是应用软件管理整个 Flash 资源的"目录索引表"。