Skip to content

Add esp_image: bootable ESP32 C3/C6/P4 images with Espressif's pinned ROM - #15

Merged
ShahriarAhnaf merged 1 commit into
mainfrom
agent/espimage-3b7d
Sep 12, 2026
Merged

ShahriarAhnaf merged 1 commit into
mainfrom
agent/espimage-3b7d

Conversation

@ShahriarAhnaf

Copy link
Copy Markdown
Contributor

Closes #14

What

simantic.esp_image plus two CLI commands:

simantic esp-image --chip esp32c3 \
    --part 0x0:bootloader.bin --part 0x8000:partitions.bin --part 0x10000:firmware.bin \
    --flash-size 16MB -o image.elf
simantic esp-rom --chip esp32p4      # download ahead of time, print the cached path
  • One layout table for C3 (with its DROM alias), C6 and P4, replacing three copy-pasted mcu-lib scripts.
  • The mask ROM is never bundled. It downloads once from Espressif's repositories, pinned by commit and SHA-256, and is cached in ~/.simantic/esp-rom. C3 and C6 come from espressif/qemu pc-bios at febae182. P4 comes from the esp-rom-elfs 20241011 release, with the tarball and member both hash-checked. --rom overrides for offline use.
  • The P4 ROM window is rebuilt from the ROM ELF in pure Python, including the .data initialisers from the ROM copy table. Users no longer need objcopy or the --rom-elf patch step.
  • Flash parts merge with 0xFF fill, matching esptool merge_bin.
  • Guards: the known-bad C3 dump (zeroed PHY jump table at 0x40001c34, which crashes every radio enable), a debug ELF passed where a raw dump is needed, and a bare objcopy P4 extract.

Verification

Byte-identical output against real artefacts, with ROMs fetched live from the pinned URLs:

check result
C3 rebuild of the CrossPoint feat-ble sim payload (17 MB) identical
P4 image vs the mcu-lib-esp32p4 hello image.elf identical
P4 rebuilt ROM vs the known-good 0x20000 bin identical
P4 section layout vs riscv32-esp-elf-objcopy -O binary identical
new vs old mcu-lib script, same inputs: C3, C6, P4 identical
C3 image built from PlatformIO parts vs the payload bootloader, partitions, otadata and fill identical
qemu-open-mac's broken C3 dump refused

pytest tests/: 158 passed, 4 skipped (engine-only session tests). That includes SIMANTIC_NETWORK_TESTS=1 downloads for all three chips and the P4 rebuild from a local ESP-IDF install. In CI both of those skip, and every other test is offline.

Follow-up, not in this PR

Point mcu-lib's ESP READMEs and scripts/esp32*_build_image.py at this module.

🤖 Generated with Claude Code

…ressif's pinned mask ROM

The ESP32 platforms boot the real mask ROM, so `sim --elf` needs one ELF
carrying the ROM plus the whole flash image. That packing lived in three
near-identical scripts in mcu-lib, which external users do not have, and
each asked the user to find the ROM themselves.

simantic.esp_image (and `simantic esp-image` / `simantic esp-rom`):
- One layout table for C3 (with its DROM alias), C6 and P4.
- ROMs download once from Espressif's own repositories, pinned by commit and
  SHA-256, cached in ~/.simantic/esp-rom: C3/C6 raw dumps from
  espressif/qemu pc-bios, the P4 ROM ELF from esp-rom-elfs 20241011.
- The P4 ROM window is rebuilt from the ROM ELF in pure Python: code
  sections, the .data initialisers from the ROM copy table, and the
  interface table at the top of the window. No objcopy needed.
- Flash images merge from OFFSET:PATH parts with 0xFF fill, or pass a
  merged image.
- Refuses the known-bad C3 dump with a zeroed PHY jump table, debug ELFs
  where a raw dump is needed, and an objcopy-only P4 extract.

Verified byte for byte: C3 rebuild of the CrossPoint featble payload, the
mcu-lib-esp32p4 hello image, the old mcu-lib scripts for all three chips on
identical inputs, and the P4 section layout against riscv32-esp-elf-objcopy.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@ShahriarAhnaf
ShahriarAhnaf merged commit 79cf34b into main Sep 12, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Build bootable ESP32 image ELFs from the SDK, with Espressif's ROM fetched and pinned

1 participant