Flash Layout¶
Espilon uses a custom 4 MB partition table that supports dual-slot OTA and isolates the provisioned master key in a dedicated, OTA-safe factory partition. No module is ever written to flash.
Partition table¶
| Partition | Offset | Size | Purpose |
|---|---|---|---|
| bootloader | 0x1000 (Xtensa) / 0x0 (RISC-V) | variable | First-stage bootloader |
| partition table | 0x8000 | variable | Partition definitions |
| nvs | 0x9000 | 32 KB | WiFi driver cache + encrypted config |
| otadata | 0x11000 | 8 KB | OTA slot selection metadata |
| phy_init | 0x13000 | 4 KB | RF calibration |
| fctry | 0x14000 | 24 KB | Master key + device id (never erased by OTA) |
| nvs_key | 0x1a000 | 4 KB | NVS encryption key |
| ota_0 | 0x20000 | ~1.9 MB | Firmware slot A |
| ota_1 | 0x200000 | ~1.9 MB | Firmware slot B |
The fctry partition is sacred
fctry (offset 0x14000) holds the device-unique 32-byte master key and device id. It sits
outside both OTA regions and is written once at provisioning. A
firmware update never touches it, so OTA cannot brick a device's identity or keys.
flowchart LR
subgraph FLASH["4 MB flash"]
BL["bootloader"] --> PT["partition table"] --> NVS["nvs (32 KB)"]
NVS --> OD["otadata"] --> PHY["phy_init"]
PHY --> FC["fctry 0x14000<br/>master_key (OTA-safe)"]
FC --> NK["nvs_key"]
NK --> O0["ota_0 0x20000"]
O0 --> O1["ota_1 0x200000"]
end
Dual-slot OTA¶
Firmware updates use the A/B slots ota_0 and ota_1. An update is downloaded over HTTPS and written to the inactive slot; on success the bootloader switches to it, leaving the previous slot intact for rollback. The otadata partition records which slot is active.
The firmware exposes OTA as built-in ota_update <url> and ota_status commands. OTA validates the image header before flashing and aborts on a 30-second stall.
Encrypted NVS config¶
WiFi credentials and the Management Protocol server address are stored encrypted in the NVS config namespace, protected with the device's config_key. At boot nvs_config_load() decrypts them. The nvs_key partition holds the NVS encryption key. The master key itself lives in the crypto namespace of the fctry partition under the key name master_key.
No modules in flash¶
ESPM modules exist only in RAM during execution. They are never written to flash unless explicitly persisted to the encrypted NVS config (up to 8 modules), so by default a power cycle leaves the device a clean hollow shell.