QEMU でエミュレートされた MIPS Malta ボードのブート コードを書き込もうとしています。
私が理解しているように、Malta ボードは 4MB のコードをフラッシュから物理 RAM の特定の位置 (0x1fc00000、MIPS プログラム アドレス空間の 0xbfc00000: MIPS32 リセット割り込み位置) にロードします。この場所に読み込まれて実行されるコードを作成しようとしています。
私は永遠にループする単純なアセンブリプログラムを持っています:
.text
_start:
b _start
これを GNU アセンブラでアセンブルすると、このコードを含む .text セクションを含む ELF ファイルが得られます。objdump を使用して逆アセンブルします。
Disassembly of section .text:
00000000 <_start>:
0: 1000ffff b 0 <_start>
4: 00000000 nop
...
リンカー スクリプトを使用して、.text セクションを 0x8fc00000 に再配置できます。
Disassembly of section .text:
8fc00000 <_start>:
8fc00000: 1000ffff b 8fc00000 <_start>
8fc00004: 00000000 nop
...
ELF ファイルには実行不可能な他のセクション、ELF ヘッダーなどが含まれているため、objcopy を使用してテキスト セクションのみをダンプします。
mips-freebsd-objcopy -O binary --only-section .text boot.o.ld boot.bin
ただし、分岐オペランドは依然として相対であるため、結果のコードは絶対アドレス指定を使用せず、0x8fc00000 ではなく 0x0 に分岐します。
% mips-freebsd-objdump -D -m mips -b binary boot.bin
boot.bin: file format binary
Disassembly of section .data:
00000000 <.data>:
0: ffff0010 b 0x0
4: 00000000 nop
...
出力で相対アドレスを絶対アドレスに解決する objcopy または ld へのフラグを無駄に検索しました。セクションの開始アドレスを操作するための objcopy フラグがありますが、これらは出力形式のオフセット テーブルを変更するだけであり、バイナリ出力には影響しないと思います (明らかにそのようなテーブルはありません)。
これまでに見つけた唯一の回避策は、アセンブリ ソースに .org ディレクティブを追加することです。
.org 0x8fc00000
これにより、当然のことながら、前にゼロが埋め込まれた約 2 GB のファイルが生成されますが、切り捨てることができる絶対アドレス指定のコードが生成されます。
これを行う正しい方法はありますか?