Skip to content

Commit 4fc11f1

Browse files
timschneebWerWolv
andauthored
patterns: Add ESP32 image pattern (#449)
Co-authored-by: Nik <[email protected]>
1 parent 7a9a509 commit 4fc11f1

File tree

3 files changed

+120
-0
lines changed

3 files changed

+120
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi
7070
| DTA | | [`patterns/max_v104.hexpat`](patterns/max_v104.hexpat) | Mechanized Assault and Exploration v1.04 (strategy game) save file format |
7171
| DTED | | [`patterns/dted.hexpat`](patterns/dted.hexpat) | Digital Terrain Elevation Data (DTED) |
7272
| ELF | `application/x-executable` | [`patterns/elf.hexpat`](patterns/elf.hexpat) | ELF header in elf binaries |
73+
| ESP32 Image | | [`patterns/esp32_image.hexpat`](patterns/esp32_image.hexpat) | Firmware image format for the ESP32 chip family |
7374
| EVTX | `application/x-ms-evtx` | [`patterns/evtx.hexpat`](patterns/evtx.hexpat) | MS Windows Vista Event Log |
7475
| EXFAT | | [`patterns/fs/exfat.hexpat`](patterns/fs/exfat.hexpat) | Extensible File Allocation Table (exFAT) |
7576
| EXT4 | | [`patterns/fs/ext4.hexpat`](patterns/fs/ext4.hexpat) | Ext4 File System |

patterns/esp32_image.hexpat

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
#pragma author timschneeb
2+
#pragma description ESP32 Firmware Image Format
3+
4+
#pragma endian little
5+
6+
// Reference: https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/app_image_format.html
7+
8+
import std.mem;
9+
10+
enum esp_chip_id_t : u16 {
11+
ESP_CHIP_ID_ESP32 = 0x0000,
12+
ESP_CHIP_ID_ESP32S2 = 0x0002,
13+
ESP_CHIP_ID_ESP32C3 = 0x0005,
14+
ESP_CHIP_ID_ESP32S3 = 0x0009,
15+
ESP_CHIP_ID_ESP32C2 = 0x000C,
16+
ESP_CHIP_ID_ESP32C6 = 0x000D,
17+
ESP_CHIP_ID_ESP32H2 = 0x0010,
18+
ESP_CHIP_ID_ESP32P4 = 0x0012,
19+
ESP_CHIP_ID_ESP32C5 = 0x0017,
20+
ESP_CHIP_ID_ESP32C61 = 0x0014,
21+
ESP_CHIP_ID_ESP32H21 = 0x0019,
22+
ESP_CHIP_ID_ESP32H4 = 0x001C,
23+
ESP_CHIP_ID_INVALID = 0xFFFF
24+
};
25+
26+
enum esp_image_spi_mode_t : u8 {
27+
QIO,
28+
QOUT,
29+
DIO,
30+
DOUT,
31+
FAST_READ,
32+
SLOW_READ
33+
};
34+
35+
enum esp_image_spi_freq_t : u8 {
36+
DIV_2,
37+
DIV_3,
38+
DIV_4,
39+
DIV_1 = 0xF
40+
};
41+
42+
enum esp_image_flash_size_t : u8 {
43+
FLASH_1MB,
44+
FLASH_2MB,
45+
FLASH_4MB,
46+
FLASH_8MB,
47+
FLASH_16MB,
48+
FLASH_32MB,
49+
FLASH_64MB,
50+
FLASH_128MB,
51+
FLASH_MAX
52+
};
53+
54+
bitfield spi_config_t {
55+
esp_image_spi_freq_t spi_speed : 4;
56+
esp_image_flash_size_t spi_size : 4;
57+
};
58+
59+
const u32 ESP_APP_DESC_MAGIC_WORD = 0xABCD5432;
60+
61+
struct esp_app_desc_t {
62+
u32 magic_word; // ESP_APP_DESC_MAGIC_WORD
63+
u32 secure_version;
64+
u32 reserv1[2];
65+
char version[32];
66+
char project_name[32];
67+
char compile_time[16];
68+
char compile_date[16];
69+
char idf_ver[32];
70+
u8 app_elf_sha256[32];
71+
u16 min_efuse_blk_rev_full;
72+
u16 max_efuse_blk_rev_full;
73+
u8 mmu_page_size; // in log2 format
74+
u8 reserv3[3];
75+
u32 reserv2[18];
76+
};
77+
78+
struct esp_image_header_t {
79+
u8 magic; // 0xE9
80+
u8 segment_count;
81+
esp_image_spi_mode_t spi_mode;
82+
spi_config_t spi_cfg;
83+
u32 entry_addr;
84+
u8 wp_pin [[comment("Write protect pin")]];
85+
u8 spi_pin_drv[3] [[comment("Drive settings for the SPI flash pins")]];
86+
esp_chip_id_t chip_id;
87+
u8 min_chip_rev [[comment("Deprecated, replaced by min_chip_rev_full")]];
88+
u16 min_chip_rev_full [[comment("Minimal revision (major*100+minor)")]];
89+
u16 max_chip_rev_full [[comment("Maximal revision (major*100+minor)")]];
90+
u8 reserved[4];
91+
92+
u8 hash_appended [[comment("If 1, a SHA256 digest 'simple hash' (of the entire image) is appended after the checksum")]];
93+
};
94+
95+
struct esp_image_segment_header_t {
96+
u32 load_addr;
97+
u32 data_len;
98+
};
99+
100+
union esp_image_segment_data_t {
101+
u8 data[parent.header.data_len] [[hidden]];
102+
103+
// Application segment
104+
if (std::mem::read_unsigned(addressof(data), 4) == ESP_APP_DESC_MAGIC_WORD) {
105+
esp_app_desc_t app_descriptor;
106+
}
107+
};
108+
109+
struct esp_image_segment_t {
110+
esp_image_segment_header_t header;
111+
esp_image_segment_data_t data;
112+
};
113+
114+
struct esp_image_t {
115+
esp_image_header_t header;
116+
esp_image_segment_t segments[header.segment_count];
117+
};
118+
119+
esp_image_t image @ 0x0;
14.8 KB
Binary file not shown.

0 commit comments

Comments
 (0)