Я использую модульную систему сборки для программного обеспечения, чем работает на встроенной цели ARM, а также на обычной машине X86 (linux). Я компилирую с помощью инструментальной цепочки GNU, таким образом, используя ld
.Как предотвратить неявный скрипт компоновщика, изменяющий LMA раздела
Один из модулей использует трюк linkerscript для сборки массива «зарегистрированных» объектов. Объекты создаются с помощью макроса, как это:
#define RegObject(name, arg1, arg2, etc) \
static TRegObject name \
__attribute__((section ("regobj_table"), used)) = \
{ arg1, arg2, etc }
Модуль также добавляет implicit linker script к шагу линии связи, которая выглядит следующим образом:
SECTIONS
{
.data : ALIGN(4)
{
regobj_table_start = .;
KEEP(*(regobj_table))
regobj_table_end = .;
}
}
regobj_table_start
и regobj_table_end
символы используются в коде для поиска зарегистрированных объектов. Это решение отлично подходит для собственных (Linux) скомпилированных целей.
Однако это не работает для цели ARM. Причина в том, что у меня есть специальный скрипт компоновщика по умолчанию для целевой (это крошечный микроконтроллер, работающий без ОС), который определяет адрес загрузочной памяти для раздела .data
. Это связано с тем, что раздел хранится во флэш-памяти, но как только микроконтроллер загружается, он копируется в ОЗУ. Соответствующая часть сценария линкера выглядит следующим образом:
MEMORY
{
ROM (rx) : ORIGIN = 0x00000000, LENGTH = 512k
RAM (rwx) : ORIGIN = 0x40000000, LENGTH = 32k
}
SECTIONS
{
/* ... other stuff ... */
.data :
{
_data = .;
*(.data)
*(.data.*)
} >RAM AT>ROM
/* ... even more stuff ... */
}
Это устанавливает VMA секции .data
куда-то в 0x4000000 диапазоне, и LMA в диапазоне 0x00000000.
Проблема заключается в том, что, когда неявный сценарий линкер добавляется к командной строке ld
, он просто забывает о LMA и снова становится равным VMA. Я отчаянно ищу метод, чтобы сообщить ld
, чтобы не касаться LMA при загрузке неявного сценария компоновщика.
Просто дикое предположение: добавит еще один неявный скрипт (после того, как он уже используется) для сборки ARM сделает трюк: 'SECTIONS {.data {} AT> ROM}'. В качестве альтернативы, если ARM-сборка может использовать другой неявный скрипт в первую очередь, просто добавьте 'AT> ROM' в соответствующее место в этом скрипте. –
Это не работает, потому что область памяти ПЗУ недоступна вне сценария, где она определена. Я уже пробовал это. – Bart
Вы считали, что вы встраиваете свой неявный скрипт в явный скрипт для ARM (таким образом, у вас есть, к сожалению, два сценария - один для ARM и неявный короткий для x86) - это действительно самое простое решение ... Или, может быть, использовать пользовательский раздел для объектов? –