Представление эльфов в HEX

Я работаю над пониманием некоторых основных концепций встроенных систем. Мой вопрос похож на понять hexedit эльфа . Чтобы записать выходные данные компилятора в ПЗУ, файл .out преобразуется в HEX (скажем, intel-hex). Интересно, как следующая информация сохраняется в формате HEX:

  1. Заголовок раздела
  2. Таблицы символов, символы отладки, символы компоновщика и т. д.
  3. Заголовок эльф.
  4. Если они сохранены в HEX-файле, как их можно прочитать из шестнадцатеричного файла?
  5. Немного неясный вопрос, но как микроконтроллер при загрузке узнает, где .data .bss и т. д. существуют в HEX и должны быть скопированы в ОЗУ?

person Aimal    schedule 06.09.2017    source источник
comment
Вы смешиваете две совершенно разные вещи. «Шестнадцатеричный код ELF» будет просто двоичным содержимым файла ELF, представленным в виде шестнадцатеричных байтов для просмотра человеком. Но шестнадцатеричный файл Intel обычно представляет собой представление того, что помещается в программируемую память.   -  person Chris Stratton    schedule 08.09.2017


Ответы (2)


Ничего из этого не сохранилось. Файл HEX содержит только необработанную программу и данные. https://en.wikipedia.org/wiki/Intel_HEX

Микроконтроллер не знает, где находятся .data и .bss — он даже не знает, что они существуют. Начальный код, который выполняется перед вызовом main(), содержит начальные адреса этих секций — адреса жестко запрограммированы в программе. Этот стартовый код будет в HEX-файле, как и все остальное.

person Lundin    schedule 06.09.2017
comment
Вы имеете в виду код запуска, который скрыто связан, или код запуска, который включен в проект (например, keil)? В видимом коде запуска нет такой инструкции memcpy и т.д.?? Также любезно будет высоко оценена любая соответствующая справочная ссылка. С уважением - person Aimal; 06.09.2017
comment
@Aimal Я не знаю, что вы имеете в виду под скрытым или видимым кодом запуска. Этот код сильно зависит от системы, но обычно он предоставляется компилятором как открытый исходный код, написанный либо на ассемблере, либо на C. см. этот код. - person Lundin; 06.09.2017
comment
Под видимым кодом я подразумеваю этот. github.com/hexanaft/stm32f4- открытие-keil-freertos-blink/blob/ - person Aimal; 06.09.2017
comment
Теперь здесь нет инструкции memcpy etc. - person Aimal; 06.09.2017
comment
@Aimal Вам придется спросить своего поставщика компилятора, где в их неприглядном стартовом коде его можно найти. Действительно, кажется, что в связанном коде нет настройки bss или данных. Это довольно распространено, многие компиляторы пропускают инициализацию этих сегментов как минимальный вариант запуска. Однако, пропустив эту инициализацию, программа больше не будет соответствовать стандарту C. Вы прошлись по своей программе и увидели, какой код фактически выполняется? - person Lundin; 06.09.2017
comment
Ну, если честно, он никогда не достигает main, когда я использую одношаговый код, и код ломается. Это означает, что keil не предоставляет исходный код, который отладчик может связать через символы отладки, а не через двоичный код (например, crt0)!! Это то, что я имел в виду как скрытый код начальной загрузки. - person Aimal; 06.09.2017
comment
@Lundin, честно говоря, я думаю, что код запуска keil icky фактически вставляется туда компилятором или компоновщиком автоматически, и никакие явные .a, .o или .s не компилируются или не связываются. (по крайней мере, в версии, которую я пользуюсь) - person Russ Schultz; 07.09.2017
comment
Отладчики часто запускаются до запуска функции main(), а затем прерываются. Тем не менее, это машинный код, поэтому от вас его не скроют. Принудительно сбросить MCU на один шаг оттуда. - person Lundin; 07.09.2017
comment
@Aimal: Keil - это компания, а не компилятор, предоставляющая наборы инструментов для более чем одной архитектуры, и их IDE также можно использовать с GCC; так что непонятно. Конечно, Keil's ARM MDK не скрывает свой код запуска, потому что его необходимо модифицировать в соответствии с вашей целью (например, для внешней памяти и конфигурации часов PLL). Возможно, это правда, что библиотека и инициализация статических данных в объектном коде, но маловероятно, что это сбой, а неправильная конфигурация вашего проекта. Запуск находится в файлах startup_xxxx.s и system_xxxx.c, где xxxx — ваш целевой процессор. - person Clifford; 07.09.2017
comment
@Aimal: также обратите внимание, что при использовании C ++ конструкторы для глобальных объектов запускаются перед main (), поэтому ошибки в этом коде или зависимость от еще не выполненной инициализации также могут привести к сбою. - person Clifford; 07.09.2017
comment
Уважаемый @Clifford, я полностью с вами согласен, но, как Лундин упомянул в своем ответе, что адреса жестко закодированы в коде запуска, поэтому я спрашивал, куда они встраивают эти адреса, я не вижу никаких инструкций по копированию памяти в файлах запуска (.startup_xxxx .s и system_xxxx.c). Не могли бы вы указать мне этот код начальной загрузки, который копирует .data/.bss и т. д. при запуске? - person Aimal; 07.09.2017
comment
@Aimal Возможно, вы можете перепроектировать необработанный машинный код, поищите инструкции по ветке. Первый цикл, с которым вы столкнетесь, скорее всего, будет циклом копирования .data/.bss. - person Lundin; 07.09.2017
comment
@ Aimal: копия памяти является частью инициализации статических данных, которая, как я признал, предоставляется как объектный код, а не источник (он не скрыт). Это может быть проблемой, если вы используете внешнюю память и неправильно настроили контроллер памяти и сигналы шины в коде запуска. В C есть два шага - нулевая инициализация и инициализированное копирование данных. Функции тривиальные, адреса для них по крайней мере появятся в карте ссылок и символы в отладчике. C++ имеет дополнительный шаг вызова статических конструкторов. - person Clifford; 07.09.2017
comment
@Aimal: обратите внимание, я указал на некоторые недостатки в вашем вопросе, в частности на отсутствие ясности в отношении цепочки инструментов. Будет намного проще ответить, если вы отредактируете вопрос, добавив недостающую информацию. Например, для ARMCC (компилятор по умолчанию для Keil ARM-MDK, если вы не используете версию 6) подробная информация находится по адресу infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0241b/ - person Clifford; 07.09.2017
comment
@Clifford, я прошу прощения за то, что не упомянул какую-либо конкретную цепочку инструментов. На самом деле мои намерения состояли в том, чтобы узнать, как именно микроконтроллер знает, какую часть памяти (.data и т. д.) нужно загрузить в оперативную память. Ссылка, которой вы поделились, действительно очень полезна. - person Aimal; 08.09.2017
comment
@Aimal: Но ответ в том, что он не знает; он просто выполняет инструкции; адреса, на которые действуют эти инструкции, определяются компоновщиком. Минимальным требованием среды выполнения C является установка указателя стека, который также определяется компоновщиком и устанавливается либо в стартовом коде (инструкциями), либо в случае Cortex -M, например, загружается из таблицы векторов, что позволяет Cortex-M запускать код C непосредственно из сброса. - person Clifford; 08.09.2017

Элементы в пунктах с 1 по 3 не включаются в необработанный двоичный файл, поскольку они не используются в приложении; скорее, они используются компоновщиком и отладчиком на хосте разработки и не нужны для выполнения программы, где все, что вам нужно, это значения байтов и адрес для их записи, который более или менее содержит весь шестнадцатеричный файл (может также содержат запись начального адреса).

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

Что касается пункта 5, то микроконтроллеру знать не обязательно; компоновщик использует эту информацию при разрешении абсолютных и относительных адресов в объектном коде. После полного разрешения (связывания) адреса напрямую встраиваются в код. Опять же, когда используется динамическая загрузка/связывание, требуются метаданные объектного файла, и такие системы обычно не загружают необработанный шестнадцатеричный файл или двоичный файл.

person Clifford    schedule 06.09.2017