用于 OTA 升级的 .bin 固件格式

ESP-IDF 编译生成的 .bin 固件文件由以下几个部分组成:

整体结构

[文件头 (8字节)] + [扩展文件头 (16字节)] + [若干数据段] + [页脚]

所有多字节字段均为小端序(little-endian)。 [ESP32 固件格式]


1. 文件头(File Header,8字节)

字节 说明
0 魔术字节,固定为 0xE9
1 数据段数量
2 SPI Flash 模式(0=QIO, 1=QOUT, 2=DIO, 3=DOUT)
3 高4位:Flash 大小;低4位:Flash 频率
4–7 程序入口地址

这就是为什么 OTA 校验时要求第一个字节必须是 0xE9


2. 扩展文件头(Extended File Header,16字节)

字节 说明
0 WP 引脚配置
1–3 SPI Flash 引脚驱动设置
4–5 芯片 ID(标识该固件适用于哪款 ESP 芯片)
6 最低芯片版本(已废弃)
7–8 最低芯片版本(格式:major × 100 + minor)
9–10 最高芯片版本(格式:major × 100 + minor)
11–14 保留字节
15 是否附加 SHA256 哈希(1 = 附加)

这就是为什么芯片 ID 不匹配时会报 mismatch chip ID 错误。 [ESP32C3 固件格式]


3. 数据段(Segment)

每个段的格式:

字节 说明
0–3 内存加载地址
4–7 段数据大小
8…n 段数据内容

4. 页脚(Footer)

  • 文件用零填充,直到大小为 16 字节的倍数减 1。
  • 最后一个字节是所有段数据的校验和(所有字节与 0xEF 的异或值)。
  • 若扩展头中 hash_appended = 0x01,则在校验和之后附加整个镜像的 SHA256 摘要(用于检测数据损坏,与 Secure Boot 无关)。
  • 若启用了 Secure Boot,还会在 SHA256 之后附加签名块。 [ESP32 固件格式]

5. 应用程序描述符(App Descriptor)

在应用程序镜像偏移 0x20 处,还有一个应用描述符,包含版本号、项目名称、编译时间、IDF 版本、安全版本等信息:

typedef struct {
    uint32_t magic_word;        // 魔术字
    uint32_t secure_version;    // 安全版本(用于防回滚)
    uint32_t reserv1[2];
    char version[32];           // 固件版本
    char project_name[32];      // 项目名称
    char time[16];              // 编译时间
    char date[16];              // 编译日期
    char idf_ver[32];           // IDF 版本
    uint8_t app_elf_sha256[32]; // ELF 文件的 SHA256
    uint32_t reserv2[20];
} esp_app_desc_t;

[OTA 框架]


分析固件文件

可以使用 esptoolimage_info 命令查看固件的完整头部和段信息:

esptool.py image_info your_firmware.bin

[ESP32C3 固件格式]

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐