Заметка для себя: Как шить .bin файл при помощи “сырого” gdb

На первый взгляд очень простая задача, но когда работаешь с микроконтроллером через какой-нибудь gdb стаб/openocd, а память в которую подгружаем файл на самом деле флеш память микроконтроллера, (например, stm32) возникают нюансы. Решил собрать все шаманства в одном посте.

Типичный стартовый набор: китайский stlink перешитый в black magic probe и stm32f4 discovery

Итак, загрузку файла в память штатно gdb может делать двумя командами: load и restore. Если gdb подцепляется к openocd серверу, то у нас также есть пара команд монитора для программирования флеша.

  • load – понимает только elf файлы, подгружает все секции по адресам, в т.ч. во флеш.
  • restore – может загружать bin файлы по произвольному адресу. Но в случае попытки прогрузить во флеш-память кидает ошибку.
  • monitor flash write_bank – поддерживается только если мы подключаемся через OpenOCD. Но может грузить бинарные файлы.

Неприятность заключается в том, что команда monitor flash write_bank доступна только если мы работаем через OpenOCD, а restore на опробованных мною комбинациях отладчик/таргет всегда кидал ошибку. В итоге оставалась только команда load.

Проблем никаких, если мы собираем прошивку сами, и у нас есть исходники. Проблемы начинаются, если нам нужно прописать во флешку данные (например, конфиг), или готовую, скачанную из интернета прошивку, которая доступна только в виде bin файла.

В этом случае потребуются шаманства, а именно сделать из .bin elf, при этом меняя адрес единственной в этом файле секции .data на адрес флеша, куда мы будем загружать файл. На примере stm32, это можно сделать вот таким вот заклинанием. Оно скушает app.bin и выплюнет нам app.elf

arm-none-eabi-objcopy -I binary -O elf32-littlearm –change-section-address=.data=0x8000000 -B arm -S app.bin app.elf

Для других архитектур/микроконтроллеров придется поменять адрес секции .data (выделено курсивом), выходную архитектуру и вариант (выделены жирным). objcopy тоже лучше использовать из состава тулчейна для этого микроконтроллера.

Прогрузка файла через gdb (На примере black magic probe) будет выглядеть так:

target extended-remote /dev/ttyACM0
mon swdp_scan
att 1
load app.elf

Если эта команда ругается на Error erasing flash with vFlashErase packet, (например, если перед этим мы стирали option bytes’ы), то надо передернуть питание целевого мк и сделать mon_swdpscan заново.

Добавить комментарий

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.