diff --git a/README.md b/README.md index 7fc5ec9..3d2f2d7 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,7 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi | DTA | | [`patterns/max_v104.hexpat`](patterns/max_v104.hexpat) | Mechanized Assault and Exploration v1.04 (strategy game) save file format | | DTED | | [`patterns/dted.hexpat`](patterns/dted.hexpat) | Digital Terrain Elevation Data (DTED) | | ELF | `application/x-executable` | [`patterns/elf.hexpat`](patterns/elf.hexpat) | ELF header in elf binaries | +| ESP32 Image | | [`patterns/esp32_image.hexpat`](patterns/esp32_image.hexpat) | Firmware image format for the ESP32 chip family | | EVTX | `application/x-ms-evtx` | [`patterns/evtx.hexpat`](patterns/evtx.hexpat) | MS Windows Vista Event Log | | EXFAT | | [`patterns/fs/exfat.hexpat`](patterns/fs/exfat.hexpat) | Extensible File Allocation Table (exFAT) | | EXT4 | | [`patterns/fs/ext4.hexpat`](patterns/fs/ext4.hexpat) | Ext4 File System | diff --git a/patterns/esp32_image.hexpat b/patterns/esp32_image.hexpat new file mode 100644 index 0000000..f35daf9 --- /dev/null +++ b/patterns/esp32_image.hexpat @@ -0,0 +1,119 @@ +#pragma author timschneeb +#pragma description ESP32 Firmware Image Format + +#pragma endian little + +// Reference: https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/app_image_format.html + +import std.mem; + +enum esp_chip_id_t : u16 { + ESP_CHIP_ID_ESP32 = 0x0000, + ESP_CHIP_ID_ESP32S2 = 0x0002, + ESP_CHIP_ID_ESP32C3 = 0x0005, + ESP_CHIP_ID_ESP32S3 = 0x0009, + ESP_CHIP_ID_ESP32C2 = 0x000C, + ESP_CHIP_ID_ESP32C6 = 0x000D, + ESP_CHIP_ID_ESP32H2 = 0x0010, + ESP_CHIP_ID_ESP32P4 = 0x0012, + ESP_CHIP_ID_ESP32C5 = 0x0017, + ESP_CHIP_ID_ESP32C61 = 0x0014, + ESP_CHIP_ID_ESP32H21 = 0x0019, + ESP_CHIP_ID_ESP32H4 = 0x001C, + ESP_CHIP_ID_INVALID = 0xFFFF +}; + +enum esp_image_spi_mode_t : u8 { + QIO, + QOUT, + DIO, + DOUT, + FAST_READ, + SLOW_READ +}; + +enum esp_image_spi_freq_t : u8 { + DIV_2, + DIV_3, + DIV_4, + DIV_1 = 0xF +}; + +enum esp_image_flash_size_t : u8 { + FLASH_1MB, + FLASH_2MB, + FLASH_4MB, + FLASH_8MB, + FLASH_16MB, + FLASH_32MB, + FLASH_64MB, + FLASH_128MB, + FLASH_MAX +}; + +bitfield spi_config_t { + esp_image_spi_freq_t spi_speed : 4; + esp_image_flash_size_t spi_size : 4; +}; + +const u32 ESP_APP_DESC_MAGIC_WORD = 0xABCD5432; + +struct esp_app_desc_t { + u32 magic_word; // ESP_APP_DESC_MAGIC_WORD + u32 secure_version; + u32 reserv1[2]; + char version[32]; + char project_name[32]; + char compile_time[16]; + char compile_date[16]; + char idf_ver[32]; + u8 app_elf_sha256[32]; + u16 min_efuse_blk_rev_full; + u16 max_efuse_blk_rev_full; + u8 mmu_page_size; // in log2 format + u8 reserv3[3]; + u32 reserv2[18]; +}; + +struct esp_image_header_t { + u8 magic; // 0xE9 + u8 segment_count; + esp_image_spi_mode_t spi_mode; + spi_config_t spi_cfg; + u32 entry_addr; + u8 wp_pin [[comment("Write protect pin")]]; + u8 spi_pin_drv[3] [[comment("Drive settings for the SPI flash pins")]]; + esp_chip_id_t chip_id; + u8 min_chip_rev [[comment("Deprecated, replaced by min_chip_rev_full")]]; + u16 min_chip_rev_full [[comment("Minimal revision (major*100+minor)")]]; + u16 max_chip_rev_full [[comment("Maximal revision (major*100+minor)")]]; + u8 reserved[4]; + + u8 hash_appended [[comment("If 1, a SHA256 digest 'simple hash' (of the entire image) is appended after the checksum")]]; +}; + +struct esp_image_segment_header_t { + u32 load_addr; + u32 data_len; +}; + +union esp_image_segment_data_t { + u8 data[parent.header.data_len] [[hidden]]; + + // Application segment + if (std::mem::read_unsigned(addressof(data), 4) == ESP_APP_DESC_MAGIC_WORD) { + esp_app_desc_t app_descriptor; + } +}; + +struct esp_image_segment_t { + esp_image_segment_header_t header; + esp_image_segment_data_t data; +}; + +struct esp_image_t { + esp_image_header_t header; + esp_image_segment_t segments[header.segment_count]; +}; + +esp_image_t image @ 0x0; diff --git a/tests/patterns/test_data/esp32_image.hexpat.bin b/tests/patterns/test_data/esp32_image.hexpat.bin new file mode 100644 index 0000000..fcf755e Binary files /dev/null and b/tests/patterns/test_data/esp32_image.hexpat.bin differ