> ## Documentation Index
> Fetch the complete documentation index at: https://totem-cb8b3887.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Firmware image

> The ESP32 application image: header, segments, footer, and build metadata.

## Image format

`firmware_v5.0.3.bin` is a standard **ESP-IDF application image** (`esp_image_header_t`),
not a raw binary. By the ESP-IDF format it begins with the magic byte `0xE9` and is loaded
by the second-stage bootloader into the OTA app partition.

```text theme={null}
Offset  Bytes            Meaning
0x00    E9               magic (ESP-IDF image)
0x01    07               segment count = 7
0x02    02               SPI mode = DIO
0x03    20               flash size 4 MB / freq 40 MHz
0x04    44 11 08 40      entry point = 0x40081144
0x08..  extended header  chip_id = 0 (ESP32), hash appended
0x20    32 54 CD AB      esp_app_desc_t magic (0xABCD5432)
```

<Note>
  Every header field above is read directly from the image file with `esptool image-info`
  (magic `0xE9`, 7 segments, entry `0x40081144`, DIO / 4 MB / 40 MHz, `chip_id` 0). The
  independent re-analysis from the carved segments corroborates the segment count, entry
  point, and the `esp_app_desc_t` at `0x20`; the SPI/flash bytes also match the
  `ESP32_GENERIC-OTA` board default.
</Note>

## Build metadata (`esp_app_desc_t`)

The application descriptor sits at the start of the first mapped segment.

| Field                    | Value                     | Notes                                                                                                                                               |
| ------------------------ | ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `magic_word`             | `0xABCD5432`              | ESP-IDF app descriptor                                                                                                                              |
| `project_name`           | *(blank)*                 | not set (all-zero) at build time                                                                                                                    |
| `version`                | *(blank)*                 | field is empty (all-zero); the `5.0.3` version appears as a standalone string in DROM (`f_ota/system.py` `release_code`), not in the OTA descriptor |
| `time` / `date`          | `16:11:34`, `Sep 12 2026` | build timestamp (v5.0.2: `15:08:47`, `Aug 27 2026`)                                                                                                 |
| `idf_ver`                | `v5.4-dirty`              | ESP-IDF v5.4 with local modifications                                                                                                               |
| `secure_version`         | `0`                       | anti-rollback secure version counter is unused                                                                                                      |
| `min_efuse_blk_rev_full` | `0`                       | minimum eFuse block revision (value confirmed from bytes; semantics per ESP-IDF layout)                                                             |
| `max_efuse_blk_rev_full` | `99` (`0x0063`)           | maximum eFuse block revision 0.99 (value confirmed from bytes; semantics inferred)                                                                  |
| `mmu_page_size`          | `16` → 64 KiB             | flash MMU page size; the 64-KiB page matches the `+0x20`-into-a-page flash mapping (value confirmed from bytes; semantics inferred)                 |
| `app_elf_sha256`         | `97a29359…a37b5777`       | hash of the source ELF (not the .bin file)                                                                                                          |

<Note>
  `v5.4-dirty` means the ESP-IDF tree had uncommitted local changes when the image was
  built. This is normal for vendor firmware and does not indicate tampering.
</Note>

## Integrity

The image carries two integrity mechanisms, both validated with `esptool`:

* A one-byte **XOR checksum** over the segment data: `0xb2` (valid).
* An appended **SHA-256** (`hash_appended` set): `a6c392bf…3e622dcd` (valid), which the
  bootloader verifies before boot. This is an image-integrity hash, not a cryptographic
  signature; no Secure Boot signature block was observed in this image.

<Note>
  These three hashes are distinct: the **image-file** SHA-256 (`bfe1f5a4…`, the whole `.bin`,
  listed by the release API), the **appended validation** hash (`a6c392bf…`, inside the image),
  and the **app ELF** hash (`97a29359…`, in `esp_app_desc_t`, pinning the source ELF).
  For v5.0.2 they were `a6d05597…`, `2a01e0f5…` and `311224…`.
</Note>

## Runtime: MicroPython

The native Xtensa code in the image is almost entirely the **MicroPython v1.25.0**
interpreter plus ESP-IDF components (WiFi, NimBLE Bluetooth, mbedTLS, FreeRTOS,
LittleFS/VFS). Totem's application is written in Python and frozen into the image.

```text theme={null}
MicroPython v1.25.0-dirty on 2026-09-16
MPY version : v1.25.0-dirty on 2026-09-16
```

The presence of `webrepl.py`, `upysh.py`, and `mip` (the MicroPython package installer)
in the frozen set indicates a developer-oriented build lineage, though whether WebREPL
is enabled at runtime depends on boot configuration held in bytecode/NVS.

See [architecture](/firmware/architecture) for the module breakdown and
[memory map](/firmware/memory-map) for the segment layout.
