Flash Multiple Binaries
A typical ESP-IDF build produces three separate binaries that must land at specific flash addresses: the bootloader, the partition table, and your application. Using esp_flash_multi, you can write all three in a single esptool invocation — one connection, one flash cycle, faster than flashing each file individually.
Standard address layout
Section titled “Standard address layout”Every ESP chip family uses a slightly different bootloader offset. The partition table and application offsets remain consistent across most configurations.
| Binary | Address |
|---|---|
| Bootloader | 0x1000 |
| Partition table | 0x8000 |
| Application | 0x10000 |
| Binary | Address |
|---|---|
| Bootloader | 0x0 |
| Partition table | 0x8000 |
| Application | 0x10000 |
| Binary | Address |
|---|---|
| Bootloader | 0x0 |
| Partition table | 0x8000 |
| Application | 0x10000 |
Flash all three binaries at once
Section titled “Flash all three binaries at once”-
Locate the build artifacts from your ESP-IDF or PlatformIO build. For ESP-IDF, they are typically in
build/:build/bootloader/bootloader.binbuild/partition_table/partition-table.binbuild/my_app.bin -
Call
esp_flash_multiwith the files array. Each entry needs anaddressand apath:esp_flash_multi({"port": "/dev/ttyUSB0","files": [{ "address": "0x1000", "path": "build/bootloader/bootloader.bin" },{ "address": "0x8000", "path": "build/partition_table/partition-table.bin" },{ "address": "0x10000", "path": "build/my_app.bin" }],"verify": true,"compress": true}) -
The tool connects once, writes all three binaries with compression enabled, then verifies each region. The response includes the total bytes written and per-file sizes.
Add a filesystem image
Section titled “Add a filesystem image”If your project includes a SPIFFS or LittleFS partition, add it to the same flash operation:
esp_flash_multi({ "port": "/dev/ttyUSB0", "files": [ { "address": "0x1000", "path": "build/bootloader/bootloader.bin" }, { "address": "0x8000", "path": "build/partition_table/partition-table.bin" }, { "address": "0x10000", "path": "build/my_app.bin" }, { "address": "0x290000", "path": "build/storage.bin" } ]})The filesystem address must match the offset defined in your partition table. Use esp_partition_analyze to read the current table from a device, or check your partitions.csv.
Verify after flashing
Section titled “Verify after flashing”If you need to confirm the flash contents without re-flashing, use esp_verify_flash for each binary:
esp_verify_flash({ "port": "/dev/ttyUSB0", "firmware_path": "build/my_app.bin", "address": "0x10000"})The tool reads flash at the specified address and compares byte-for-byte against the file. A verified: true response confirms the contents match.
Use with QEMU
Section titled “Use with QEMU”The same esp_flash_multi call works against a QEMU virtual device. Pass the socket URI instead of a serial port:
esp_flash_multi({ "port": "socket://localhost:5555", "files": [ { "address": "0x0", "path": "build/bootloader/bootloader.bin" }, { "address": "0x8000", "path": "build/partition_table/partition-table.bin" }, { "address": "0x10000", "path": "build/my_app.bin" } ]})See the Flash Operations reference for full parameter details.