Conversation
The ROM loads the 2nd stage bootloader before anything has enabled quad mode on the flash chip, so a bootloader whose header says QIO or QOUT ends in a watchdog reset loop (esp-rs#657). ESP-IDF and esptool always mark the bootloader DIO/DOUT; a bootloader built for QIO then switches the flash to quad mode itself, and only the app header carries the quad mode. Do the same: the bootloader header gets the dual counterpart of the requested mode, and for QIO/QOUT the bundled bootloader is one built for QIO where there is one (ESP32-S3 for now). Without one, warn that the flash will be read in dual mode. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #657.
--flash-mode qio(orqout) writes the quad mode into the 2nd-stage bootloader's own header as well as the app's. The ROM loads the bootloader before anything has enabled quad mode on the flash chip. With a quad header it fails atets_loader.c 78and goes into a TG0WDT reset loop.ESP-IDF and esptool always flash the bootloader as DIO/DOUT. A bootloader built with
CONFIG_ESPTOOLPY_FLASHMODE_QIOthen sets the QE bit and switches SPI0 to quad itself (esptool docs).This PR does the same:
qio→dio,qout→dout), and the app header keeps the requested mode. This alone ends the boot loop for every chip, including with a user-supplied--bootloader.qio/qout, espflash uses a bundled bootloader built for QIO where one exists. For now that is onlyesp32s3-qio, built bycargo xtask build-bootloadersfrom the samerelease/v6.1withCONFIG_ESPTOOLPY_FLASHMODE_QIO=y.--bootloader.A QIO-built bootloader cannot become the default. The QIO switch is compile-time, and such a bootloader enables quad mode even when its header says DIO, which would break boards whose flash or pins do not support it. Hence a separate binary per chip, selected only on request.
About the binary:
esp32s3-qio-bootloader.binis built from ESP-IDF14f663f003e(v6.1-beta1-497), the commit the existing bundled bootloaders come from.release/v6.1has moved on since then.esp32s3entry rebuilds byte-identical to the committedesp32s3-bootloader.bin, so the QIO one comes from the same source and config.cargo xtask build-bootloadersas is. The canonicalized\\?\workspace path ends up inIDF_TOOLS_PATHand in theidf.pyarguments, andcmd /Cdoes not handle the escaped quotes. So I ran the same generated project andsdkconfig.defaultsby hand. I can send a separate fix for the xtask on Windows if that is useful.I started with the ESP32-S3 because that is the chip I can test. If you want QIO entries for the other chips as well, I can add them to the manifest. I would rather not ship ones I cannot try on hardware without you saying so.
Testing:
image_format::idf, using the S3 and C3 test ELFs:qioon the S3, the QIO bootloader is used, its header says DIO and its SHA-256 is valid, and the app header says QIO;diokeeps the default bootloader;qioon a chip without a QIO bootloader still gets a DIO bootloader header.espflash flash --flash-mode qio --flash-freq 80mhznow boots withSPI Mode: QIO;CTRLhasfread_qioset;espflash flashstill boots in DIO with the default bootloader.This change was developed with the help of an AI assistant (Claude). I reviewed and tested it on hardware.
🤖 Generated with Claude Code