あなたはすぐそこに答え-Ttext =数-Tdata =番号を持っているように、彼らはGNUです何GNUリンカスクリプト項目はありませんコマンドライン項目。コマンドラインのat記号に注意してください。
gnuリンカースクリプトはこれに似ています(ただし、ほとんどの場合、必要がなくてもかなり複雑です)。あなたは-Ttext =アドレスアプローチを使用する場合、GNUリンカは少し面白いこと
MEMORY
{
rom : ORIGIN = 0x08000000, LENGTH = 0x1000
ram : ORIGIN = 0x20000000, LENGTH = 0x1000
}
SECTIONS
{
.text : { *(.text*) } > rom
.rodata : { *(.rodata*) } > rom
.bss : { *(.bss*) } > ram
}
注意、時にはそれはあなただけで直線的にし、代わりにそのプログラムの数キロバイトを持っているように、アドレスでそれを置くかもしれないギャップを挿入しますそれはいくつかのデッドスペースを埋める必要がありますし、さらにいくつかを置く必要がありますが、非常に限られたターゲットのためにリンカスクリプト(コマンドライン対)他のすべての要因が一定に保たれ、出力にギャップを入れません。
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オブジェクトを使用します。リンカーがas-built/configured toolchains(またはCライブラリと言う)ブートストラップコードを使用できないようにすることで、特定のオブジェクトファイルが呼び出された時点でリンカスクリプトを複雑にしないと、コードを提供する必要がありますあなたがフラッシュを交換する場合、コマンドライン上のオブジェクトの重要性。oとblinker02.oをmakefileのldコマンドラインで実行すると、バイナリは動作しません。あなたはエントリーポイントを自由に設定することができますが、これはローダー用です。エントリーポイントが無意味であるように見えるベアメタルであれば、ハードウェアは起動方法をブートします。この場合は、cortex-mアドレスゼロスタックポインタにロードする値です。アドレス4はリセットベクトルのアドレスです(lsbitは親指のマシンなので、ツールはgnuアセンブラ固有のthumb_funcを使って次のラベルを指示します)分岐先アドレス)。
私はこのコードを元のarmv4tとarmv5tから、またはより新しいarm docs "all thumb variants"で呼び出されたので、私はこのコードを約1つ撒いたので、最も移植性の高いアーム命令です腕の芯。あなたのcortex-m4を使って、それを取り除くか、おそらく-m3または-m4にしてarmv7-m thumb2拡張を引っ張ることができます。
ので、短い答えは
arm-none-eabi-ld -o so.elf -Ttext=0x08000000 -Tbss=0x20000000 so.o
では、あなたが.DATAを必要といけないと仮定すると、作業バイナリを作るための十分以上です。
。データには、より多くのもの、リンカスクリプト、より複雑なブートストラップなどが必要です。それはコピージャンプのことですが、REALプログラムをsramのみで実行するようにコンパイルします(別のエントリポイントのフルサイズのアームスタイルしかし、RAMベースのアドレスで)、そのバイナリを取って、それを言葉に変換するアドホックツールを書いて、フラッシュからコピーしてREALプログラム全体をブランクにコピーするプログラムのエントリを0xabcdefにします。 .dataも.bssもなく、コマンドラインを使うことができるので、REAL ramのみのプログラムが可能です。そしておそらく私はあなたをすでに失ってしまったでしょう。
同様に、コマンドラインを使用すると、.bssがゼロに設定されていると仮定することはできません。また、ブートストラップもそれを行う必要があります。もしあなたが.bssと.dataを持っていないなら、少なくとも1つの古いコンパイラが不要なゴミを追加したので、あなたはCプログラムのエントリーポイントに分岐する前に、盲目的にすべてのRAMを0にすることができます。 main()関数を見て、main()という名前の関数について何も魔法がないということを強調するなら、バイナリです。
リンカスクリプトはツールチェーン固有のものなので、gnuリンカスクリプトがKielに移植してARMに移植する必要はありません(そうです、私はARMがKielを所有していることを知っています。最初の.data/.bssの問題。理想的には、あなたのツールで作業をしたいので、.dataと.bssのビットがどのようになっているかを知ることができます。リンカスクリプトを正しく作っていることを伝える方法は(少なくともldでは)難しいしかし、それはあなたが.bssの開始アドレス、.bssの終了アドレス、それらを減算して長さを得るいくつかの数え方のようなものを定義することができるなら変数を作成します。同様に.dataのために、その後ブートストラップアセンブリ言語でゼロ開始アドレスと長さ、および/または開始アドレスと終了アドレスを使用した.bssメモリ。 .dataには2つのアドレスが必要です。そこにはフラッシュ(より多くのリンカースクリプトfoo)と、RAMに入れたい場所と、ブートストラップのコピーの長さが入ります。
あなたはこのコード
unsigned int x=5;
unsigned int y;
を書いて、あなたは、コマンドラインリンカスクリプトを使用している場合ので、基本的には、最初のC関数が入力されたときに0にxが5またはyであることを期待する一切理由はありませんこれらの変数を使用します。 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'と組み合わせて使用することもできます。これらのステートメント( 'BYTE、SHORT、LONG、QUAD')は、他のシステムローダー(おそらくSOC ROMコード)のヘッダー情報を提供するために主に役立ちます。 –
@artlessnoise - ありがとうございます。しかし、現時点では、私はリンカファイルを避けようとしています;少なくとも直接。 – InfinitelyManic
あなたの 'bootup.ld.cli'はリンクのようなものですそれは技術的なものではありません。あなたがブート可能/実行可能ファイルを作るためにコードをコンパイル/アセンブルしたくないと思った。あなたのタイトルは私を誤解します。 –