Skip to main content

Segments

The v5.0.3 image contains seven segments. DROM grew by 6,528 bytes and IROM by 996 bytes over v5.0.2; IRAM and the RTC segments are unchanged in size. Executable code lives in IROM (flash-mapped) and IRAM; constants and the frozen Python bytecode live in DROM. Segments 1 and 6 address the same RTC FAST memory through different buses: seg 1 is the data-bus view (.rtc.data) and seg 6 the instruction-bus view (.rtc.text). RTC SLOW memory (0x500000000x50002000) is not used by any segment.
Structural details of the layout above:
  • DROM starts with the OTA descriptor. The first 256 bytes of segment 0 are the esp_app_desc_t application descriptor (build date, IDF version, ELF SHA-256), ahead of the rodata / qstr pool / frozen bytecode.
  • +0x20 load offset. Both flash-mapped segments (0x3f400020, 0x400d0020) load 0x20 above their 64-KiB-aligned MMU page bases (0x3f400000 / 0x400d0000): the 24-byte esp_image_header_t and the 8-byte segment-0 header occupy the first 0x20 bytes in flash, ahead of the segment payload.
  • Segments 2 and 4 are contiguous in DRAM. 0x3ffbdb60 + 0xd08 = 0x3ffbe868 (seg 4’s start), so the two initialized-data segments form one continuous region even though the IROM segment sits between them in image order. v5.0.2 split the same 23,248-byte region differently (0x2688 + 0x3448 at 0x3ffc01e8).
Entry point is 0x40081144, in IRAM (segment 5). The disassembled prologue is the standard ESP32 startup: entry, a load into the exception vecbase, then a callx8 into early init. The entry routine itself is (inferred) the IDF call_start_cpu0 — the rebuilt ELF has no symbol table, so it cannot be confirmed by symbol.

ESP32 address regions (reference)

Rebuilt ELF

For analysis, the seven segments are reassembled into an EM_XTENSA ELF with each segment placed at its real load address and correct R/W/X permissions. That ELF loads directly into Ghidra (with an Xtensa processor module) or IDA. Capstone 6.0 (CS_ARCH_XTENSA) also disassembles the code segments directly. See methodology.
Analyzing the native ELF reveals the MicroPython interpreter, not Totem’s logic. The application behavior lives in the frozen bytecode inside segment 0 (DROM). Use the recovered symbol table and string constants to understand the Python layer.