- PVSM.RU - https://www.pvsm.ru -
Поддавшись общей волне энтузиазма относительно систем «Умный дом», а также имея профильное образование инженера АСУ ТП, с удовольствием занимаюсь данной темой в виде хобби. В этой статье поделюсь с вами своим опытом реверс-инжиниринга популярного модуля ESP8266.

В основном меня интересовали внутреннее устройство SoC, архитектура и система команд процессора, процедура старта и загрузки прошивки и другие не менее интересные вещи. Начав изучение данного модуля, я столкнулся с тем, что нужной информации по нему не много, и зачастую она достаточно противоречива. Поэтому многое приходилось перепроверять, что-то выяснять опытным путем, а о чем-то просто догадываться. Буду рад вашим комментариям и дополнениям.
Чтобы систематизировать всю полученную информацию и была написана эта статья.
Не буду приводить технические характеристики, про это уже много написано, в том числе и на Хабре. Желающие могут ознакомиться, например, здесь [7].

Начнем с общей архитектуры системы. Модуль представляет собой Soc, в основе которого лежит процессор семейства Xtensa – Tensilica’s L106 Diamond series производства американской компании Cadence [8], а также микросхему флеш-памяти на 512кБ. Сам модуль разработан китайской компанией Espressif Systems [9]. Таким образом, основная официальная информация по ESP8266 поступает от Espressif (на китайском языке и в переводе), а некоторые общие данные можно получать от Cadence.
Особенностью данного семейства процессоров является то, что они представляют собой конструктор, из которого заказчик с помощью предлагаемого инструмента Xtensa Processor Generator может собрать чип с нужными ему характеристиками и заказать его у производителя. Поэтому различные модификации могут сильно отличаться, например, количеством ядер, дополнительными инструкциями, модулями DSP и так далее.
Как я уже говорил выше, модель состоит из flash ROM размером 512 КБ и SoC, который, по неподтвержденным данным имеет RAM до 248 КБ.
Вообще все, что касается памяти – расположения, свойств и атрибутов сегментов – это изыскания сообщества. В оригинальной китайской документации этот вопрос почему-то обойден стороной.
Один из вариантов (имеются противоречия с другими источниками) известной на сегодняшний день карты памяти можно посмотреть здесь [10]. Приведу лишь наиболее интересные адреса:
Внутренняя память:
| Диапазон | Описание |
|---|---|
| 3FFE8000h — 3FFFBFFFh | оперативная память для пользовательских приложений. При старте модуля может инициализироваться значениями из пользовательской прошивки. |
| 3FFFC000h — 3FFFFFFFh | системная оперативная память |
| 40000000h — 4000FFFFh | системный ROM. Отсюда стартует процессор, загружается пользовательская прошивка и здесь находятся основные системные библиотеки. |
| 40100000h — 4010FFFFh | оперативная память, содержит пользовательскую прошивку |
| 40240000h — 40271FFFh | вторая часть пользовательской прошивки. Здесь находятся код подключенных библиотек и SDK. Подмаплено к flash по адресу 40000h. |
Различные сегменты адресного пространства могут быть RAM, ROM или подмаплены непосредственно к flash. Подмапленные области кэшируются для скорости работы.
Flash:
| Диапазон | Описание |
|---|---|
| 00000h — 3DFFFh | адрес загрузки пользовательской прошивки |
| 40000h — 7BFFFh | адрес загрузки библиотек SDK (также может являться частью пользовательской прошивки) |
Теперь, перед тем, как перейти к процессу запуска модуля, рассмотрим формат прошивки. Для загрузки пользовательской прошивки обычно достаточно записать 2 блока данных: по адресу 00000h и 40000h. Остальные блоки могут потребовать перепрошивки для сброса конфигурации, например, при заливке новой прошивки с несовместимым форматом данных.
Блок, начинающийся с 40000h содержит простой бинарный код, который загружается и работает в неизменном виде. А вот блок, начинающийся с 00000h, представляет собой структурированные данные о находящихся в нем сегментах и выглядит следующим образом:
| Смещение | Описание |
|---|---|
| 0 | идентификатор прошивки, всегда `0xE9` |
| 1 | количество сегментов в прошивке |
| 2,3 | параметры SPI Flash |
| 4-7 | адрес запуска прошивки (Entry Point) |
| 8... | далее идут данные сегментов |
Структура сегмента:
| Смещение | Описание |
|---|---|
| 0-3 | адрес для загрузки сегмента |
| 4-7 | размер сегмента |
| 8... | далее идут данные сегмента |
Завершающий блок:
Заполнен нулями для выравнивания до границы 16 байт минус 1 байт. После этого добавляется последний байт, представляющий собой контрольную сумму данных всех сегментов, вычисляемая функцией xor над всеми байтами и константой `0xEF`.
Формат прошивки взят из описания к утилите esptool [11].
Теперь, вооружившись этими знаниями, рассмотрим процесс старта модуля ESP8266 с точки зрения инициализации и запуска прошивки.
При подаче питания или поступлении сигнала сброса процессор начинает выполнение инструкций с адреса 40000080h (системный ROM). По адресу 40001308h располагается процедура, которая считывает блок 00000h flash и копирует сегменты, хранящиеся в ней по заданным адресам.

На схеме этот процесс показан фиолетовым цветом. Здесь видно, что часть прошивки является исполняемым кодом, а часть инициализирует данные в ОЗУ. Зеленым обозначен блок, напрямую подмапленный в адресное пространство процессора.
После всех инициализаций управление передается по адресу, указанному в заголовке прошивки. Обычно это адрес пользовательского кода 40100000h.
Что ж, теперь, когда мы разобрались с архитектурой и процедурой старта модуля ESP8266, давайте перейдем к изучению его программного кода. Какие ресурсы и инструменты у нас есть для этого?
Для проектирования, разработки и отладки продуктов на базе SoC Xtensa существует пакет Xtensa Xplorer от производителя процессора, в состав которого входит множество утилит, включая TurboXIM – симулятор SoC. Теоретически, эта утилита могла бы быть полезной, но даже бесплатная версия требует лицензионных ключей, выдаваемых по запросу. Написав такой запрос я не получил ответа, поэтому воспользоваться симулятором не удалось. Скачать весь набор инструментов можно здесь [12], возможно, вам повезет больше.
Для разработки, сборки прошивок и выгрузки отладочной информации нам будет полезно развернуть среду разработки, как описано здесь [13].
Из традиционных инструментов воспользуемся IDA Pro и HIEW.
Для изучения кода процессора Xtensa необходимо использовать IDA Pro версии 6.6 и выше со встроенным интерпретатором питона для выполнения скриптов. В перечень стандартно поддерживаемых процессоров Xtensa не входит, поэтому каждый раз при запуске IDA Pro перед открытием исследуемого файла необходимо загружать скрипт “xtensa.py”, который можно взять здесь [14].
Также для автоматического создания сегментов и наименования функций системного ROM нам понадобится скрипт для IDA Pro. Скрипт и дамп системной прошивки можно скачать здесь [15].
HIEW будет полезен для исследования структуры ELF- и готовых двоичных файлов прошивки.
В следующей части мы рассмотрим процесс загрузки прошивки для исследования.
Автор: codezero
Источник [16]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/diy/88150
Ссылки в тексте:
[1] Введение: #Intro
[2] Архитектура ESP8266: #Architecture
[3] Карта памяти (адресного пространства): #MemoryMap
[4] Формат прошивки: #Firmware
[5] Процесс запуска: #Startup
[6] Инструменты: #Tools
[7] здесь: http://habrahabr.ru/company/coolrf/blog/238443
[8] Cadence: http://ip.cadence.com
[9] Espressif Systems: http://espressif.com/en/products/esp8266
[10] здесь: https://github.com/esp8266/esp8266-wiki/wiki/Memory-Map
[11] esptool: https://github.com/themadinventor/esptool
[12] здесь: http://ip.cadence.com/support/sdk-download-test
[13] здесь: http://geektimes.ru/post/241842
[14] здесь: https://github.com/themadinventor/ida-xtensa
[15] здесь: https://yadi.sk/d/TmDYcWb2fmbb7
[16] Источник: http://habrahabr.ru/post/255135/
Нажмите здесь для печати.