у вас есть свой ответ прямо там -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, а не значения в.данных, поэтому он всегда будет работать в командной строке или не просто скрипт компоновщика или сложный и т. д.
Вы можете сделать это с помощью файла-линкера (определите данные раздела с использованием [данных раздела вывода] (https://sourceware.org/binutils/ docs/ld/Output-Section-Data.html) с 'BYTE',' SHORT', 'LONG' и' QUAD'. Вы также можете прочитать ваш файл из stdin, чтобы вы могли использовать 'echo' или другие методы для укажите все в командной строке. Эти инструкции ('BYTE, SHORT, LONG, QUAD') в основном полезны для предоставления информации заголовка для какого-либо другого загрузчика системы (возможно, кода SOC rom). Таким образом, это возможно **, это не самый лучший маршрут, и более разумно использовать ассемблер. Вы также можете импортировать необработанные двоичные файлы. –
@artlessnoise - Да, спасибо. Но в данном случае я стараюсь избегать файла компоновщика, по крайней мере напрямую. – InfinitelyManic
Я вижу, ваш «bootup.ld.cli» очень похож на ссылку er, но это не технически. Я думал, что вы не хотите компилировать/собирать любой код для создания загрузочного/исполняемого файла. Ваш титул вводит меня в заблуждение. –