Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Application Startup and Bootloader

Upon power up, many embedded devices will just start executing code from an address in flash memory. Espressif chips are a bit more complicated, and require some steps to setup flash memory, a cache and some other miscellaneous operations. For this, we require a bootloader which is a simple application that sets up the aforementioned operations, then jumps to executing other code.

To boot an application, Espressif devices use 2 bootloaders:

  • First Stage Bootloader (ROM Bootloader): Sets up architecture-specific registers, checks the boot mode and reset reason, and loads the second stage bootloader. This bootloader is burned into ROM, and exists as part of SoC and therefore doesn't need to be flashed, nor can it be changed.
  • Second Stage Bootloader: Loads your application and sets up the memory(RAM, PSRAM or flash).

The second stage bootloader whilst not technically required, is advised as it allows OTA support (the first stage bootloader only loads applications from a fixed offset in flash) and also enables flash encryption and secure boot. For more information, see the OTA section.

For more information about the startup process, please check ESP-IDF documentation. However, note that some aspects may be ESP-IDF specific.

Second Stage Bootloader

At the moment, only ESP-IDF Bootloader is supported as a second stage bootloader, this will change in the future as we plan to add support for other bootloaders, such as MCUBOOT.

ESP-IDF Bootloader

Uses the ESP image format, see more information in ESP-IDF documentation. The ESP-IDF bootloader is used with a partition table to know where to place the binary.

Partition Tables

Flash memory of the Espressif devices can store multiple applications along with various types of data, such as calibration data, filesystems, and parameter storage. To manage this, a partition table is flashed at the default offset device.

The ESP-IDF second stage bootloader will know where to place the binary by looking at the partition table. Each entry in the partition table has a name (label), type (app, data, or something else), subtype and the offset in flash where the partition is loaded.

When working with espflash, if you don't provide a second stage bootloader or partition table, espflash will use a default bootloader and partition table, but you can also create a custom partition table.

Building a Custom ESP-IDF Bootloader

The espflash and cargo-espflash include pre-built ESP-IDF bootloaders that are compiled using the default settings, making it easy to get started without additional configuration. However, if you require more advanced functionality or custom settings, you will need to build the bootloader yourself to tailor it to your specific needs.

To build a custom ESP-IDF bootloader:

  1. Install ESP-IDF.
  2. Create a new project or go to an already existing one.
    • Using any examples under the esp-idf/examples directory is the easiest way.
  3. Make desired bootloader changes using idf.py menuconfig or editing the sdkconfig file.
  4. Build the bootloader with idf.py set-target <CHIP_TARGET> build bootloader.
    • The resulting bootloader binary will be placed under build/bootloader/bootloader.bin.
  5. Use the built bootloader binary in espflash/cargo-espflash with the --bootloader flag or with the configuration file.