Boot Mode Selection - ESP32 (original) (raw)

This guide explains how to select the boot mode correctly and describes the boot log messages of ESP32.

Warning

The ESP32 has a 45k ohm internal pull-up/pull-down resistor at GPIO0 (and other pins). If you want to connect a switch button to enter the boot mode, this has to be a strong pull-down. For example a 10k resistor to GND.

Information about ESP32 strapping pins can also be found in the ESP32 Datasheet, section “Strapping Pins”.

On many development boards with built-in USB/Serial, esptool.py can automatically reset the board into bootloader mode. For other configurations or custom hardware, you will need to check the orientation of some “strapping pins” to get the correct boot mode:

Select Bootloader Mode

GPIO0

The ESP32 will enter the serial bootloader when GPIO0 is held low on reset. Otherwise it will run the program in flash.

GPIO0 Input Mode
Low/GND ROM serial bootloader for esptool
High/VCC Normal execution mode

GPIO0 has an internal pullup resistor, so if it is left unconnected then it will pull high.

Many boards use a button marked “Flash” (or “BOOT” on some Espressif development boards) that pulls GPIO0 low when pressed.

GPIO2

GPIO2 must also be either left unconnected/floating, or driven Low, in order to enter the serial bootloader.

In normal boot mode (GPIO0 high), GPIO2 is ignored.

Other Pins

As well as GPIO0 and GPIO2, the following pins influence the serial bootloader mode:

GPIO Meaning
12 (MTDI) If driven High, flash voltage (VDD_SDIO) is 1.8V not default 3.3V. Has internal pull-down, so unconnected = Low = 3.3V. May prevent flashing and/or booting if 3.3V flash is used and this pin is pulled high, causing the flash to brownout. See the datasheet for more details.
15 (MTDO) If driven Low, silences boot messages printed by the ROM bootloader. Has an internal pull-up, so unconnected = High = normal output.

For more information, consult the ESP32 Datasheet, section “Strapping Pins”.

Automatic Bootloader

esptool.py resets ESP32 automatically by asserting DTR and RTS control lines of the USB to serial converter chip, i.e., FTDI, CP210x, or CH340x. The DTR and RTS control lines are in turn connected to GPIO0 and EN (CHIP_PU) pins of ESP32, thus changes in the voltage levels of DTR and RTS will boot the ESP32 into Firmware Download mode.

Note

When developing esptool.py, keep in mind DTR and RTS are active low signals, i.e., True = pin @ 0V, False = pin @ VCC.

As an example of auto-reset curcuitry implementation, check the schematic of the ESP32 DevKitC development board:

Make the following connections for esptool to automatically enter the bootloader of an ESP32 chip:

ESP Pin Serial Pin
EN RTS
GPIO0 DTR

In Linux serial ports by default will assert RTS when nothing is attached to them. This can hold the ESP32 in a reset loop which may cause some serial adapters to subsequently reset loop. This functionality can be disabled by disabling HUPCL (ie sudo stty -F /dev/ttyUSB0 -hupcl).

(Some third party ESP32 development boards use an automatic reset circuit for EN & GPIO0 pins, but don’t add a capacitor on the EN pin. This results in unreliable automatic reset, especially on Windows. Adding a 1uF (or higher) value capacitor between EN pin and GND may make automatic reset more reliable.)

In general, you should have no problems with the official Espressif development boards. However, esptool.py is not able to reset your hardware automatically in the following cases:

Manual Bootloader

Depending on the kind of hardware you have, it may also be possible to manually put your ESP32 board into Firmware Download mode (reset).

Note

If esptool is able to reset the chip but for some reason the chip is not entering into bootloader mode then hold down the Boot button (or pull down GPIO0) while you start esptool and keep it down during reset.

Boot Log

Boot Mode Message

After reset, the second line printed by the ESP32 ROM (at 115200bps) is a reset & boot mode message:

ets Jun 8 2016 00:22:57 rst:0x1 (POWERON_RESET),boot:0x3 (DOWNLOAD_BOOT(UART0/UART1/SDIO_REI_REO_V2))

rst:0xNN (REASON) is an enumerated value (and description) of the reason for the reset. A mapping between the hex value and each reason can be found in the ESP-IDF source under RESET_REASON enum. The value can be read in ESP32 code via the get_reset_reason() ROM function.

boot:0xNN (DESCRIPTION) is the hex value of the strapping pins, as represented in the GPIO_STRAP register.

The individual bit values are as follows:

If the pin was high on reset, the bit value will be set. If it was low on reset, the bit will be cleared.

A number of boot mode strings can be shown depending on which bits are set:

Note

GPIO_STRAP register includes GPIO 4 but this pin is not used by any supported boot mode and be set either high or low for all supported boot modes.

Later Boot Messages

Later output from the ROM bootloader depends on the strapping pins and the boot mode. Some common output includes:

Early Flash Read Error

Invalid header <value at 0x1000>

This fatal error indicates that the bootloader tried to read the software bootloader header at address 0x1000 but failed to read valid data. Possible reasons for this include:

Software Bootloader Load Segments

load:0x3fff0008,len:8 load:0x3fff0010,len:3680 load:0x40078000,len:8364 load:0x40080000,len:252 entry 0x40080034

These entries are printed as the ROM bootloader loads each segment in the software bootloader image. The load address and length of each segment is printed.

You can compare these values to the software bootloader image by running esptool.py --chip esp32 image-info /path/to/bootloader.bin to dump image info including a summary of each segment. Corresponding details will also be found in the bootloader ELF file headers.

If there is a problem with the SPI flash chip addressing mode, the values printed by the bootloader here may be corrupted.

The final line shows the entry point address of the software bootloader, where the ROM bootloader will call as it hands over control.