ESP32固件信息查看
ESP32 .bin 固件除可执行代码外,还嵌入镜像头、段描述和应用信息等结构化元数据。
固件文件结构
二进制结构详解
Image Header(偏移 0,共 8 字节)
| 偏移 | 大小 | 字段 | 说明 |
|---|---|---|---|
| 0 | 1 B | magic | 固定为 0xE9,识别 ESP32 镜像格式 |
| 1 | 1 B | segment_count | 镜像中的段数量 |
| 2 | 1 B | spi_mode | SPI Flash 读取模式(见下表) |
| 3 | 1 B | spi_speed[3:0] | spi_size[7:4] | Flash 时钟(低4位)与容量(高4位) |
| 4–7 | 4 B | entry_addr | 固件入口地址,小端序 |
| spi_mode | |
|---|---|
0 | QIO — 四线输入输出 |
1 | QOUT — 四线输出 |
2 | DIO — 双线输入输出 |
3 | DOUT — 双线输出 |
| spi_speed | |
|---|---|
0x0 | 40 MHz |
0x1 | 26 MHz |
0x2 | 20 MHz |
0xF | 80 MHz |
| spi_size | |
|---|---|
0x0 | 1 MB |
0x1 | 2 MB |
0x2 | 4 MB |
0x3 | 8 MB |
0x4 | 16 MB |
0x5 | 32 MB |
0x6 | 64 MB |
0x7 | 128 MB |
Extended Header(偏移 8,共 16 字节)
| 偏移 | 大小 | 字段 | 说明 |
|---|---|---|---|
| 8 | 1 B | wp_pin | WP 引脚编号(0xEE = 未通过 eFuse 设置) |
| 9–11 | 3 B | spi_pin_drv[3] | SPI CLK / Q / WP 引脚驱动强度 |
| 12–13 | 2 B | chip_id | 目标芯片 ID,小端序(见下表) |
| 14 | 1 B | min_chip_rev | 最低芯片版本(旧格式,已废弃) |
| 15–16 | 2 B | min_chip_rev_full | 最低支持版本(major×100+minor) |
| 17–18 | 2 B | max_chip_rev_full | 0xFFFF = 不限 |
| 19–22 | 4 B | reserved | 保留,应为零 |
| 23 | 1 B | hash_appended | 1 = 文件末尾附加整镜像 SHA256 |
当 hash_appended = 1 时,工具链会在 .bin 文件末尾追加一段 32 字节的 SHA256(哈希本身不计入计算范围)。设备启动或 OTA 升级时会重新算一遍、对一对,对不上就直接丢掉这个固件。文件布局如下:
[ 镜像数据 ... ] [ SHA256 (32 B) ]chip_id 取值:
chip_id | 芯片 |
|---|---|
0x0000 | ESP32 |
0x0002 | ESP32-S2 |
0x0005 | ESP32-C3 |
0x0009 | ESP32-S3 |
0x000C | ESP32-C2 |
0x000D | ESP32-C6 |
0x0010 | ESP32-H2 |
0x0011 | ESP32-C61 |
0x0012 | ESP32-P4 |
0x0014 | ESP32-C5 |
0x0016 | ESP32-H4 |
系列兼容性
所有现代 ESP32 变体(ESP32、S2、S3、C3、C6、H2、P4 等)使用相同的二进制格式。chip_id 字段标识目标芯片,固件不可跨芯片运行。min/max_chip_rev_full 可限定支持的硅版本范围。Flash 模式与速度的可用值因芯片而异(如部分芯片不支持 QIO 模式)。
Segment Header(每段 8 字节,共 segment_count 个)
| 偏移 | 大小 | 字段 | 说明 |
|---|---|---|---|
| 0–3 | 4 B | load_addr | 段运行时加载地址(IRAM / DRAM / Flash 映射) |
| 4–7 | 4 B | data_len | 段数据字节数 |
load_addr 内存区域:
| 地址前缀 | 区域 | 说明 |
|---|---|---|
0x3FF… | DRAM | 数据 RAM —— 段数据在启动时复制到此 |
0x400… | IRAM | 指令 RAM —— 代码在启动时复制到此,可从 CPU 直接执行 |
0x3F4… / 0x400D… | DROM / IROM | Flash 直接映射 —— 不复制,XIP(就地执行) |
// esp_image_format.h (ESP-IDF)
typedef struct {
uint32_t load_addr; // runtime load address
uint32_t data_len; // segment length in bytes
} esp_image_segment_header_t; // 8 BSegment Data
每个 Segment Header 之后紧跟 data_len 字节的段原始数据,无额外头部。bootloader 根据 load_addr 将数据复制(或映射)到对应内存区域:
- DRAM / IRAM 段:启动时由 bootloader 复制到 RAM,CPU 可直接访问。
- DROM / IROM 段(Flash 映射):不复制,通过 MMU 直接从 Flash 读取(XIP)。
所有段依次排列:[Segment Header₁][Segment Data₁][Segment Header₂][Segment Data₂] …
App Description(esp_app_desc_t,共 256 字节)
位于第一个 DRAM 段的数据起始位置,因此其在文件中的偏移为 24 B(Image Header)+ 8 B(第一个 Segment Header)= 32 B 起(若存在 Flash 映射段则更靠后)。
自定义应用描述(Custom App Description)
ESP-IDF 支持在 esp_app_desc_t 之后附加用户自定义元数据(如硬件版本、生产信息)。
代码模式:
const __attribute__((section(".rodata_custom_desc")))
esp_custom_app_desc_t custom_app_desc = { ... };在 CMakeLists.txt 中确保链接器保留该符号:
target_link_libraries(${COMPONENT_TARGET} "-u custom_app_desc")从文件起始的偏移:24 B(esp_image_header_t)+ 8 B(esp_image_segment_header_t)+ 256 B(esp_app_desc_t)= 288 B
由于布局因项目而异,工具在该位置显示原始字节;全零表示固件不含自定义描述。
在线查看工具
固件信息查看工具 在浏览器中本地解析 .bin 文件(不上传服务器),支持:
- 芯片类型、Flash 模式、Flash 大小、入口地址
- WP 引脚、SPI 引脚驱动强度、芯片版本范围、附加哈希标志
- 各段的加载地址与大小
- 项目名称、版本号、编译时间、IDF 版本、ELF SHA256、安全版本
