What are the files boot_app0.bin and bootloader_dio_80m.bin for? (ESP32 - Arduino IDE)
The ESP32 flash command, as executed by the Arduino IDE, seems to flash two bootloader files: boot_app0.bin
at offset 0xe000
and bootloader_dio_80m.bin
at offset 0x1000
. I wonder what these two bootloader files actually do, and why there are two of them. Below I give some more information.
1. Context
I'm part of a team developing a new, free IDE for microcontrollers: Embeetle IDE. We're planning to support the ESP32 microcontroller family in the near future. Therefore, I'm now studying the ESP32 build system - both the ESP-IDF
tool and the Arduino IDE approach to ESP32 projects.
2. Arduino IDE flash procedure for ESP32 projects
After building the .elf
file, the Arduino IDE launches a command to convert it into a binary:
python esptool.py --chip esp32 elf2image
--flash_mode dio
--flash_freq 80m
--flash_size 4MB
-o /tmp/arduino_build_852524/WiFiScan.ino.bin
/tmp/arduino_build_852524/WiFiScan.ino.elf
Finally, this WiFiScan.ino.bin
file is flashed to the board, alongside two bootloader files and the partitions table:
python esptool.py --chip esp32
--port /dev/ttyUSB0
--baud 921600
--before default_reset
--after hard_reset write_flash
-z
--flash_mode dio
--flash_freq 80m
--flash_size detect
0xe000 ~/.arduino15/packages/esp32/hardware/esp32/1.0.6/tools/partitions/boot_app0.bin
0x1000 ~/.arduino15/packages/esp32/hardware/esp32/1.0.6/tools/sdk/bin/bootloader_dio_80m.bin
0x10000 /tmp/arduino_build_852524/WiFiScan.ino.bin
0x8000 /tmp/arduino_build_852524/WiFiScan.ino.partitions.bin
The default partitions table, as used by Arduino IDE, looks like this (in csv format):
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x140000,
app1, app, ota_1, 0x150000,0x140000,
spiffs, data, spiffs, 0x290000,0x170000,
The binary equivalent of this csv-file gets flashed to address 0x8000
. There are also two bootloader files being flashed to addresses 0xe000
and 0x1000
respectively (see next paragraph).
3. Bootloader files
The two bootloader files being flashed are:
# flashed at 0xe000
~/.arduino15/packages/esp32/hardware/esp32/1.0.6/tools/partitions/boot_app0.bin
and:
# flashed at 0x1000
~/.arduino15/packages/esp32/hardware/esp32/1.0.6/tools/sdk/bin/bootloader_dio_80m.bin
Question 1: What do these two bootloader files do?
It's also interesting to observe their locations. The first one, boot_app0.bin
is located in a folder named 'partitions'
. It sits there alongside several partition .csv
files. Why? But maybe that gets clear when Question 1 is answered.
The other one, bootloader_dio_80m.bin
is located in a folder named 'sdk/bin/'
and sits alongside other files that all start their name with the 'bootloader_'
prefix:
Question 2: As for the bootloader file flashed at address
0x1000
, I think the'_40m'
and'_80m'
suffixes stand for the flash speed in MHz. But I've no idea what the'_dio'
,'_dout'
and'_qout'
suffixes stand for.
Please enlighten me ^_^
Answer
Thanks to @Juraj, I now get a better insight into the startup procedure of an ESP32 chip. I believe it looks like this:
-
FIRST STAGE BOOTLOADER:
The hardwired ROM-bootloader runs first. This first stage bootloader is outside the Flash memory and cannot be programmed. It loads the second stage bootloader (see next step). -
SECOND STAGE BOOTLOADER:
The first stage ROM-bootloader loads the second stage ESP-IDF Software bootloader at address0x1000
in Flash. The code here is thebootloader_dio_80m.bin
executable, which can be found in thecomponents/bootloader
directory of the ESP-IDF framework. This second stage bootloader reads the partition table found by default at offset0x8000
. If OTA app partitions are found in the partition table, the bootloader consults theota_data
partition to determine which one should be booted. -
BOOT SWITCH
Theota_data
section can be considered as merely a switch, located at0xe000
in Flash. It determines if eitherapp0
orapp1
should boot. The switch itself is theboot_app0.bin
binary. As Juraj says, the 2kB size is also used to take notes during OTA flashing. -
APPLICATION
The application atapp0
orapp1
executes.
Thank you also for pointing me at these resources:
- ESP32 bootloader
- ESP32 startup procedure
The binary at 0x1000 is the bootloader. Arduino ESP32 has bootloader binaries corresponding to boards options in Tools menu in Arduino IDE (built from boards.txt).
The bootloader functions are documented here.
The ESP-IDF Software Bootloader performs the following functions:
- Minimal initial configuration of internal modules;
- Initialize Flash Encryption and/or Secure features, if configured;
- Select the application partition to boot, based on the partition table and ota_data (if any);
- Load this image to RAM (IRAM & DRAM) and transfer management to it.
The boot_app0.bin is the OTA data partition initial content. It is documented here.
The OTA data partition is two flash sectors (0x2000 bytes) in size, to prevent problems if there is a power failure while it is being written. Sectors are independently erased and written with matching data, and if they disagree a counter field is used to determine which sector was written more recently.
DIO, QIO, DOUT, QOUT are SPI modes for the flash memory. Different esp32 modules have different flash memory chips and their connection. (D is double, Q is quad)