WinAVR. Использование инструментов GNU #03. Управление компоновщиком avr-ld
Некоторые опции компоновщика
Хотя это не платформозависимые опции для avr-ld, перечисленные стандартные опции могут быть интересны пользователям AVR.
- -lимя
- Указывает расположение статической библиотеки, названной libимя.a, и использует её для определения из неё неопределенных символов. Библиотека ищется по пути, который задан в списке стандартных каталогов, которые заданы во время компиляции (например, для Unix-систем это /usr/local/avr/lib), и который можно расширить списком каталогов, заданным опциями -L (которые должны предшествовать опциям -l в командной строке).
- -Lпуть
- Дополнительное место для поиска статических библиотек, запрашиваемых опциями -l.
- --defsym symbol=expr
- Определяет использование значения выражения expr вместо глобального символа symbol.
- -M
- Печать карты компоновки в стандартный выходной поток stdout.
- -Map mapfile
- Печать карты компоновки в файл распределения mapfile.
- --cref
- Вывод таблицы перекрёстных ссылок в файл распределения mapfile (в случае передачи опции -Map) или в stdout.
- --section-start sectionname=org
- Начинает секцию sectionname с абсолютного адреса org.
- -Tbss org
-Tdata org
-Ttext org - Начинает секцию bss, data или org с адреса org.
- -T scriptfile
- Использует scriptfile как скрипт компоновщика, заменяя стандартный скрипт компоновщика. Стандартные скрипты компоновщика записаны в каталоге, зависящем от системы (например, /usr/local/avr/lib/ldscripts для Unix-систем), и состоят из имени архитектуры AVR (с avr2 по avr5) с добавленным суффиксом .x. Они описывают, как различные секции памяти должны быть связаны между собой.
Передача опций компоновщику из C-компилятора.
По умолчанию все неизвестные аргументы “не опции” в командной строке avr-gcc (то есть все аргументы “имена файлов”, у которых нет суффиксов, обрабатываемых компилятором avr-gcc) передаются напрямую компоновщику. Таким образом, все файлы, заканчивающиеся на .o (библиотеки объектных модулей), предоставляются компоновщику.
Системные библиотеки обычно не передаются их явными именами, лучше использовать опцию -l, которая использует сокращенную форму имени архива (смотрите на странице 1 данного раздела). avr-libc добавляет две системные библиотеки, libc.a и libm.a. Хотя стандартная библиотека libc.a всегда будет искаться для неопределенных ссылок, когда запускается компоновщик, используя препроцессор компилятора Си (то есть всегда есть по крайней мере одна неявная опция -lc), математическая библиотека libm.a нуждается в явном запросе, используя -lm. Смотрите также объясняющий это раздел FAQ.
Условно makefile’ы используют макрос сборки LDLIBS
, чтобы следить за опциями -l (и возможно -L), которые должны быть добавлены в командную строку Си компилятора только при компоновке конечного двоичного кода. А макрос LDFLAGS
используется, чтобы записать другие опции командной строки Си компилятора, которые должны быть переданы как опции во время этапа компоновки. Отличие этих опций, размещенных ранее в командной строке, в том, что библиотеки включаются в её конце, так как они должны быть использованы, чтобы определить глобальные символы до сих пор еще неопределенные на данный момент.
Специальные флаги компоновщика могут быть переданы из командной строки Си компилятора, используя опцию компилятора -Wl (смотрите страницу 1 раздела). Эта опция требует отсутствия пробелов в добавленных опциях компоновщика, хотя некоторые из приведённых выше опций компоновщика (подобных -Map или --defsym) нуждаются в пробелах. В этих ситуациях, пробел может быть заменен эквивалентным символом. Например, следующая командная строка может быть использована, чтобы скомпилировать foo.c в исполняемый файл и вывести карту компоновки, которая содержит список перекрестных ссылок, в файл foo.map:
$ avr-gcc -O -o foo.out -Wl,-Map=foo.map -Wl,--cref foo.c
В качестве альтернативы, запятая, как заполнитель, будет заменена пробелом перед передачей опции компоновщику. Так для устройств с внешней SRAM следующая командная строка заставит компоновщик разместить сегмент данных по адресу 0x2000 в SRAM:
$ avr-gcc -mmcu=atmega128 -o foo.out -Wl,-Tdata,0x802000
Смотрите описание секции данных для разъяснения, почему необходимо добавить 0x800000 к реальному значению. Заметьте, что стек всё еще остается во внутренней RAM, начиная с символа __stack
, который обеспечивается исполняемым кодом инициализации. Это вероятно является хорошей идеей (так как доступ к внутренней RAM быстрее), и даже обязательно для некоторых ранних контроллеров, у которых были аппаратные ошибки, не допускающие использование ими стека во внешней RAM. Заметьте, что динамически распределяемая область памяти для malloc()
всё ещё может быть выделена после всех переменных в секции данных, при этом конфликтов между стеком и динамически распределяемой памятью не произойдет.
Как правило, чтобы переместить стек из его стандартного расположения вверху внутренней RAM, значение символа __stack
может быть изменено в командной строке компоновщика. Так как компоновщик обычно вызывается из препроцессора компилятора, этого можно достигнуть, используя опцию компилятора, подобную следующей:
-Wl,--defsym=__stack=0x8003ff
Пример выше генерирует код, использующий под стек пространство от RAM адреса 0x3ff и ниже. Размер доступного стекового пространства зависит от нижней границы внутренней RAM конкретного контроллера. Приложение должно гарантировать, что стек не выйдет за границы, а также так организовывать стек, чтобы не конфликтовать с размещением переменных, созданным компилятором (секции .data и .bss).