2017-02-02 22 views
0

Возможно ли создать базовую программу загрузки/запуска сборок с помощью простого кода, используя только параметры командной строки GNU LD в вместо обычного файла -T-скрипта для цели Cortex-M4?Возможно ли создать базовую программу загрузки/запуска сборочной сборки с использованием только опций командной строки GNU LD.

Я рассмотрел документацию GNU LD и просмотрел различные местоположения, включая этот сайт; однако я не нашел никакой информации, предполагающей, что эксклюзивное использование параметров командной строки для компоновщика GNU возможно или невозможно.

Моя попытка управления макетами объектного файла без обычного поставщика при условии, что * .ld scriptfile является чисто академическим. Это не домашнее задание. Я не требую никакой помощи для написания кода сборки запуска. Я просто ищу окончательный ответ или дальнейшее направление ресурсов.

$ arm-none-eabi-ld bootup.o -o bootup @bootup.ld.cli.file 

Содержание Примера bootup.ld.cli.file

--entry 0x0 
--Ttext=0x0 
--section-start .isr_vector=0x0 
--section-start _start=0x4 
--section-start .MyCode=0x8c 
--Tdata=0x20000000 
--Tbss=0x20000000 
-M=bootup.map 
--print-gc-sections 
+0

Вы можете сделать это с помощью файла-линкера (определите данные раздела с использованием [данных раздела вывода] (https://sourceware.org/binutils/ docs/ld/Output-Section-Data.html) с 'BYTE',' SHORT', 'LONG' и' QUAD'. Вы также можете прочитать ваш файл из stdin, чтобы вы могли использовать 'echo' или другие методы для укажите все в командной строке. Эти инструкции ('BYTE, SHORT, LONG, QUAD') в основном полезны для предоставления информации заголовка для какого-либо другого загрузчика системы (возможно, кода SOC rom). Таким образом, это возможно **, это не самый лучший маршрут, и более разумно использовать ассемблер. Вы также можете импортировать необработанные двоичные файлы. –

+0

@artlessnoise - Да, спасибо. Но в данном случае я стараюсь избегать файла компоновщика, по крайней мере напрямую. – InfinitelyManic

+0

Я вижу, ваш «bootup.ld.cli» очень похож на ссылку er, но это не технически. Я думал, что вы не хотите компилировать/собирать любой код для создания загрузочного/исполняемого файла. Ваш титул вводит меня в заблуждение. –

ответ

2

у вас есть свой ответ прямо там -Ttext = число -Tdata = число и так далее нет гну элементов компоновщика сценария они являются гну командной строки. обратите внимание на знак на вашей командной строке.

Сценарий компоновщика gnu больше похож на этот (хотя большинство из них значительно сложнее, даже если им это не нужно).

MEMORY 
{ 
    rom : ORIGIN = 0x08000000, LENGTH = 0x1000 
    ram : ORIGIN = 0x20000000, LENGTH = 0x1000 
} 

SECTIONS 
{ 
    .text : { *(.text*) } > rom 
    .rodata : { *(.rodata*) } > rom 
    .bss : { *(.bss*) } > ram 
} 

Обратите внимание, что гну линкер немного смешно, когда вы используете = адрес подход -Ttext, иногда он будет вставлять пробелы вы можете иметь несколько кбайт программы и вместо него просто линейно размещая его по адресу, как он должен положить некоторые из них, затем проложить какое-то мертвое пространство, затем добавить еще немного, никогда не выяснять, почему, но для крайне ограниченных целей скрипт компоновщика (vs command line) все остальные факторы, поддерживаемые постоянными, не помещают пробел в результат.

EDIT:

so.s

.cpu cortex-m0 
.thumb 

.thumb_func 
.global _start 
_start: 
stacktop: .word 0x20001000 
.word reset 
.word hang 
.word hang 
.word hang 
.word hang 

.thumb_func 
reset: 
    b hang 
.thumb_func 
hang: b . 

flash.s

.cpu cortex-m0 
.thumb 

.thumb_func 
.global _start 
_start: 
stacktop: .word 0x20001000 
.word reset 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 

.thumb_func 
reset: 
    bl notmain 
    b hang 

.thumb_func 
hang: b . 

.thumb_func 
.globl dummy 
dummy: 
    bx lr 

flash.ld

MEMORY 
{ 
    rom : ORIGIN = 0x08000000, LENGTH = 0x1000 
    ram : ORIGIN = 0x20000000, LENGTH = 0x1000 
} 

SECTIONS 
{ 
    .text : { *(.text*) } > rom 
    .rodata : { *(.rodata*) } > rom 
    .bss : { *(.bss*) } > ram 
} 

blinker02.c

void dummy (unsigned int); 

int notmain (void) 
{ 
    unsigned int ra; 
    for(ra=0;ra<100;ra++) dummy(ra); 
    return(0); 
} 

Makefile

ARMGNU = arm-none-eabi 

AOPS = --warn -mcpu=cortex-m0 
COPS = -Wall -O2 -nostdlib -nostartfiles -ffreestanding -mcpu=cortex-m0 

all : blinker02.bin sols.bin socl.bin 

clean: 
    rm -f *.bin 
    rm -f *.o 
    rm -f *.elf 
    rm -f *.list 

so.o : so.s 
    $(ARMGNU)-as $(AOPS) so.s -o so.o 

flash.o : flash.s 
    $(ARMGNU)-as $(AOPS) flash.s -o flash.o 

blinker02.o : blinker02.c 
    $(ARMGNU)-gcc $(COPS) -mthumb -c blinker02.c -o blinker02.o 

blinker02.bin : flash.ld flash.o blinker02.o 
    $(ARMGNU)-ld -o blinker02.elf -T flash.ld flash.o blinker02.o 
    $(ARMGNU)-objdump -D blinker02.elf > blinker02.list 
    $(ARMGNU)-objcopy blinker02.elf blinker02.bin -O binary 

sols.bin : so.o 
    $(ARMGNU)-ld -o sols.elf -T flash.ld so.o 
    $(ARMGNU)-objdump -D sols.elf > sols.list 
    $(ARMGNU)-objcopy sols.elf sols.bin -O binary 

socl.bin : so.o 
    $(ARMGNU)-ld -o socl.elf -Ttext=0x08000000 -Tbss=0x20000000 so.o 
    $(ARMGNU)-objdump -D socl.elf > socl.list 
    $(ARMGNU)-objcopy socl.elf socl.bin -O binary 

Разница между командной строки и файлы компоновщик скрипт SOCl и золи список имена

diff sols.list socl.list 
2c2 
< sols.elf:  file format elf32-littlearm 
--- 
> socl.elf:  file format elf32-littlearm 

не собирается возиться с демонстрируя разницу вы можете увидеть вниз дорога.

Для сборки только вам не нужно беспокоиться о стартовых файлах и других параметрах командной строки (на gcc). С объектами C вы делаете. не позволяя компоновщику использовать встроенный/сконфигурированный программный набор (или скажем C-библиотеку) загрузочный код, вы должны предоставить его, если вы не усложняете сценарий компоновщика до такой степени, что вызываются определенные объектные файлы, а затем упорядочение объектов в командной строке, если вы меняете память.o и blinker02.o в командной строке ld в файле makefile, двоичный файл не работает. вы можете установить точки входа все, что хотите, но они предназначены исключительно для загрузчика, если это голый металл, который, по-видимому, является точкой входа, бесполезен, аппаратное обеспечение загружает, как оно загружается, в этом случае с адресом cortex-m zero это значение для загрузки в указателе стека, адрес четыре - это адрес вектора сброса (с набором lsbit, поскольку это машина с большим пальцем, позволяют инструментам делать это для вас, используя специальный ассемблер gnu thumb_func, чтобы указать следующую метку является адресом назначения филиала).

Я посыпал коркусом-m0 примерно одним, потому что это то, что я взял из этого кода, и двумя оригинальными armv4t и armv5t или как вызывается в новых документах рук «все варианты большого пальца», это самый переносимый набор команд рукоятки сердечники рук. с вашей корекс-m4 вы можете избавиться от этого или, возможно, сделать его -m3 или -m4, чтобы втянуть расширения armv7-m thumb2.

так короткий ответ

arm-none-eabi-ld -o so.elf -Ttext=0x08000000 -Tbss=0x20000000 so.o 

более чем достаточно для создания рабочих бинарных файлов Предполагая, что вам не нужно .data.

.data требует гораздо больше материала, скрипта компоновщика, более сложного бутстрапа и т. Д. Это или вы делаете операцию копирования, компилируете программу REAL, которая должна выполняться только в sram (различная начальная точка с полным размером руки но на базовом адресе ram), затем напишите adhoc-инструмент, чтобы взять этот двоичный код и превратить его в слова .word 0xabcdef в программе, которая копирует из флэш-памяти, чтобы развернуть всю программу REAL, а затем ветвится, теперь программа копирования и перехода только с отсутствием .data или .bss действительно необходимо и может использовать командную строку, поэтому можно использовать только программу REAL ram. И я, наверное, уже потерял тебя на этом.

Аналогичным образом, используя командную строку, вы не можете или не должны предполагать, что .bss обнуляется, ваш bootstrap тоже должен это сделать. Теперь, если у вас есть .bss и no .data, тогда вы можете слепо обнулить все баранки при загрузке до того, как вы перейдете в точку входа программ C (я использую notmain(), потому что хотя бы один старый компилятор добавил ненужный мусор к бинарный, если он увидел функцию main() и подчеркнуть ту точку, что обычно нет ничего волшебного в функции с именем main().).

Сценарии компоновщика являются специфичными для инструментальных средств, поэтому нет причин ожидать, что скрипты компоновщика gnu будут перенесены в Kiel для подключения к ARM (да, я знаю, что ARM принадлежит Килю, теперь ссылался на RVCT или что бы это ни было сейчас) и т. Д. Так что это первая проблема .data/.bss. В идеале вы хотите, чтобы ваши инструменты выполняли работу, поэтому они знают, как бит .data и .bss так просто позволяют им рассказать вам, как вы позволили им сказать, что вы правильно создаете скрипт компоновщика (по крайней мере, с ld), и это сложно. , но он создает переменные, если вы это сделаете, чтобы определить такие вещи, как начальный адрес для .bss, конечный адрес для .bss, возможно, даже некоторую математику, чтобы вычесть их и получить длину, аналогично для .data, а затем на языке ассемблера начальной загрузки вы можете обнулить .bss-память, используя начальный адрес и длину, и/или начальный адрес и конечный адрес. Для .data вам нужны два адреса, где вы помещаете их во flash (больше скрипта компоновщика foo) и где он хочет идти в ram, а длина - копия бутстрапа.

так в основном, если вы пишете этот код

unsigned int x=5; 
unsigned int y; 

и использование командной строки компоновщик сценария, то никакие оснований не ожидать й быть 5 или у равных 0, когда первая функция C вводятся который использует эти переменные. Если вы предположите, что x будет равен 5, ваша программа завершится неудачей.

, если вы сделаете это вместо

unsigned int x; 
unsigned int y; 
void myfun (void) 
{ 
    x=5; 
    y=0; 
} 

теперь эти задания инструкции в .text, а не значения в.данных, поэтому он всегда будет работать в командной строке или не просто скрипт компоновщика или сложный и т. д.

+0

Макет кажется прекрасным при просмотре через файл карты, objdump и readelf; однако я не могу пройти мимо ResetHandler. ПК не продвигается; поэтому я спрашиваю, достаточно ли для командной строки всего лишь полного и правильного макета. Я буду отмечать ваш ответ соответственно, так как считаю, что он должен работать. – InfinitelyManic

+1

Да, было абсолютно построено с и без сценариев компоновщика в течение многих лет, основное различие заключается в этом gnu ld weirdness ... –

+0

у вас есть один объект - это язык ассемблера или вы пытаетесь полагаться на ботстрап toolchains? (который не будет работать без соответствующего скрипта компоновщика, который идет с ним). –