下面是一个比较符合 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 资源的“目录索引表”。