aarch64 のベアメタルプログラムの挙動がわからん過ぎたのでデバッグ環境を構築し、使い方を勉強した。
前提
aarch64 のビルド環境とエミュレーター、gdb は導入済み。
この記事内で言及はないが、 mikoto2000/qemu-aarch64:3.1.0 を使用した。
デバッグ対象のビルド
デバッグオプション(-g3
)をつけて、プログラムをビルドする。
# make
aarch64-linux-gnu-as -g3 -o boot.o boot.S
aarch64-linux-gnu-gcc -g3 -O0 -I ../util/include -c -o main.o main.c
aarch64-linux-gnu-gcc -g3 -O0 -I ../util/include -c -o uart.o ../util/src/uart.c
aarch64-linux-gnu-gcc -g3 -O0 -I ../util/include -c -o string.o ../util/src/string.c
aarch64-linux-gnu-gcc -g3 -O0 -I ../util/include -c -o system_register.o ../util/src/system_register.S
aarch64-linux-gnu-ld -o kernel8.elf boot.o main.o uart.o string.o system_register.o -T linker.ld
aarch64-linux-gnu-objcopy -O binary kernel8.elf kernel8.img
QEMU でデバッグ実行
デバッグ対象バイナリを指定して、 QEMU を起動する。
# qemu-system-aarch64 -kernel ./kernel8.img -nographic -machine raspi3 -s -S
-s
:localhost:1234
で gdb を待ち受ける-S
: 開始と同時にプログラムを一時停止する
gdb で QEMU に接続する
別のターミナルを開いて、 gdb で QEMU に接続する。
# gdb-multiarch -q ./kernel8.elf
Reading symbols from ./kernel8.elf...done.
(gdb) target remote localhost:1234
Remote debugging using localhost:1234
0x0000000000000000 in ?? ()
(gdb) b start
Breakpoint 1 at 0x80000: file boot.S, line 7.
(gdb) b go_to_main
Breakpoint 2 at 0x8002c: file boot.S, line 22.
(gdb) c
Continuing.
Thread 1 hit Breakpoint 1, start () at boot.S:7
7 mov sp, #0x80000
...(略)
みたいな感じで作ったプログラムをデバッグできる。
以上。