Флеш-стаб esptool (flasher stub)
Когда esptool подключается к ESP32, первое, что он делает, — заливает в оперативную память чипа собственную маленькую программу и дальше разговаривает уже с ней, а не с загрузчиком из ПЗУ. Эта программа и есть флеш-стаб.
Обновлено Редакция GAW
Флеш-стаб (flasher stub, stub loader, в ESP-IDF — download stub) — небольшая программа, которую esptool при каждом подключении загружает в оперативную память чипа Espressif и которая дальше заменяет собой встроенный в ПЗУ загрузчик. Все последующие операции — запись, чтение, стирание флеш, запрос идентификаторов — выполняет уже стаб. Отключается аргументом --no-stub, после чего esptool общается с загрузчиком ПЗУ напрямую. Как устроена сама прошивка через esptool и как чип попадает в загрузчик по strapping-выводам, разобрано в статье «Прошивка ESP32 через esptool».
Зачем он нужен
Загрузчик ПЗУ записан на заводе и обновить его нельзя — новая версия появляется только вместе с новой ревизией кремния. Стаб снимает это ограничение: по документации esptool он ведёт себя так же, как загрузчик ПЗУ, но:
- использует оптимизированные процедуры UART, поэтому запись и чтение флеш заметно быстрее;
- даёт сжатую загрузку (compressed download) — так описывает его опция
CONFIG_ESPTOOLPY_NO_STUBв ESP-IDF; - позволяет обходить ошибки конкретной версии ПЗУ;
- стирает флеш «на лету»: по описанию протокола загрузчик ПЗУ стирает всю область по команде FLASH_BEGIN, а стаб стирает блоки по 4 КБ и 64 КБ по мере записи, принимая следующий блок по UART, пока пишется предыдущий. Размер блока esptool — 16 КБ.
Стаб разрабатывается в отдельном проекте esp-flasher-stub, готовые бинарники идут в составе esptool. В esptool 4.13.0 (release notes от 2 ноября 2026) стаб обновлён до версии 1.4.0.
Отличия в протоколе
| Что | Загрузчик ПЗУ | Стаб |
|---|---|---|
| Где выполняется | ПЗУ чипа | IRAM, загружается esptool при каждом подключении |
| Статус ответа | зависит от чипа (у ESP32-S3 — 4 байта) | всегда 2 байта |
| Коды ошибок | свои | 0xC*, 0xFF — нереализованная команда |
| MD5 области флеш (ESP32-S3) | 32 ASCII-символа | 16 байт |
| Стирание | вся область по FLASH_BEGIN | блоками 4 и 64 КБ по ходу записи |
Когда стаб не нужен или невозможен
--no-stub— esptool говорит только с ПЗУ. Часть опций отключается, потому что не все команды реализованы в ПЗУ каждого чипа; командеread-flashможет понадобиться явный--flash-size. Документация называет такой режим вариантом для отладки.- Secure Download Mode — загрузка кода в RAM запрещена, поэтому ESP-IDF требует запускать esptool с
--no-stub. load-ram— стаб занимает часть IRAM и DRAM, и программа, которую вы загружаете в память, не должна с ним пересекаться; esptool выдаст ошибку, а с--no-stubограничения нет. Зато без стаба ранний вывод программы в UART может потеряться — документация советует поставитьets_delay_us(1)первой строкой после точки входа.
Чтобы не загружать стаб перед каждой командой, есть --after no-reset-stub (оставить чип в стабе) и --before no-reset-no-sync (не сбрасывать и не синхронизироваться заново).
С чем не путать
Стаб живёт только в RAM и исчезает при сбросе. Он не имеет отношения к загрузчику второй ступени ESP-IDF, который у ESP32 лежит во флеш по адресу 0x1000 и запускает приложение, и не меняет режим SPI-флеш, записанный в заголовке образа.
Частые вопросы
Зачем esptool загружает стаб, если в чипе уже есть загрузчик?
Загрузчик ПЗУ записан при производстве и не обновляется — новая версия появляется только с новой ревизией чипа. Стаб позволяет обойти это ограничение: по документации esptool он ведёт себя как загрузчик ПЗУ, но с оптимизированными процедурами UART, поэтому запись и чтение флеш идут быстрее, работает сжатая загрузка, а ошибки ПЗУ можно обойти. По протоколу стаб стирает флеш «на лету» блоками 4 и 64 КБ, принимая следующий блок данных, пока пишется предыдущий.
Когда нужен ключ --no-stub?
В двух случаях по документации Espressif. Первый — отладка: нужно проверить, не в стабе ли проблема, и поговорить напрямую с ПЗУ. Второй — Secure Download Mode: там загрузка кода в RAM запрещена, и ESP-IDF прямо указывает, что esptool работает только с --no-stub. При этом часть опций станет недоступна, потому что не всё реализовано в ПЗУ каждого чипа, а команде read-flash может понадобиться явный --flash-size.
Можно ли не загружать стаб заново при каждой команде?
Да. Опция --after no-reset-stub оставляет чип в стабе после операции без сброса, а --before no-reset-no-sync при следующем вызове пропускает сброс по DTR/RTS и команду синхронизации — esptool сразу продолжает работать с уже запущенным стабом. Это удобно, когда подряд выполняется несколько команд.
Источники
- Espressif. esptool Documentation (latest), ESP32: Flasher Stub, Advanced Options, Basic Commands, Advanced Commands — Flasher Stub: esptool общается с загрузчиком ПЗУ; ПЗУ записано при производстве и не обновляется, новая версия только с новой ревизией чипа; стаб (stub loader) — небольшая программа, временная замена или расширение ПЗУ; при подключении esptool сначала загружает стаб, он подменяет загрузчик, дальнейшие операции идут через него; поведение то же, но с оптимизированными процедурами UART — быстрее запись и чтение флеш, обход ошибок ПЗУ; отключается аргументом --no-stub (например, для отладки); разработка в проекте esp-flasher-stub, готовые бинарники в составе esptool; есть legacy stub для сравнения при ошибках; Advanced Options: --no-stub отключает загрузку стаба, часть опций недоступна, так как не все реализованы в ПЗУ каждого чипа; --before no-reset-no-sync — если чип уже выполняет стаб; --after no-reset-stub — оставить чип в стабе; Basic Commands: с --no-stub команде read-flash может понадобиться --flash-size; Advanced Commands: load-ram с --no-stub, стаб занимает IRAM и DRAM и ограничивает область загрузки; с --no-stub ранний вывод программы в UART может теряться — ets_delay_us(1) первой строкой
- Espressif. esptool Documentation (latest), ESP32-S3: Serial Protocol — по умолчанию esptool загружает стаб в IRAM, после чего стаб заменяет загрузчик ПЗУ для всех операций; коды ошибок стаба 0xC*, 0xFF — нереализованная команда; статус ответа стаба всегда 2 байта; загрузчик ПЗУ стирает область по FLASH_BEGIN, стаб стирает «на лету» во время записи — блоки по 4 КБ и 64 КБ, следующий блок принимается по UART, пока пишется предыдущий; блок esptool 16 КБ; ESP32-S3 ROM возвращает MD5 32 ASCII-символами, стаб — 16 байтами
- Espressif. ESP-IDF Programming Guide v6.1, ESP32-S3: Security Overview; ESP32: Configuration Options Reference; esptool v4.13.0 release notes (2 ноября 2026) — в Secure UART Download mode esptool работает только с --no-stub; CONFIG_ESPTOOLPY_NO_STUB: стаб даёт сжатую загрузку и другие возможности, обычно отключать не нужно; release notes v4.13.0 (github.com/espressif/esptool/releases/tag/v4.13.0): стаб обновлён до v1.4.0, учёт работы стирания стабом в таймаутах сжатой записи, для ESP32-H4 убрано предупреждение о флеш больше 16 МБ при работе со стабом
Нашли ошибку? ·
Смотрите также
- Прошивка ESP32Загрузчик ПЗУ, GPIO0 и автосброс, write-flash и адреса, ошибки esptool и питание
- Загрузчик (bootloader)Прошивка МК без программатора через UART или USB
- Загрузчик второй ступени ESP-IDFbootloader.bin по адресу 0x1000: таблица разделов, выбор приложения, флеш, secure boot
- Secure Download ModeУрезанный загрузчик ПЗУ: запись флеш, стирание, get-security-info — и ничего больше
- Режимы SPI-флеш (QIO, QOUT, DIO, DOUT)Сколько линий и какие команды чтения использует ESP32 для флеш, когда выбирать dio
- USB Serial/JTAGВстроенный в ESP32 контроллер USB: COM-порт и JTAG без внешних микросхем
- Strapping-выводы ESP32Какие GPIO читаются при сбросе: загрузка, напряжение флеш-памяти, JTAG — для ESP32, S2, S3, C2, C3, C5, C6, H2, P4