2018年01月05日

Raspberry PiベアメタルをQEMUでデバッグするメモ

Raspberry Piベアメタルプログラミングは、microSDをいちいち抜き差ししないといけないのが面倒です。
SDカードを使わない方法としては、ネットワークブートやUSB接続でホストをマスストレージに見せかけるなどの方法もあるようですが、GPIOなどを操作しない場合にはエミュレータが有効です。

今回Raspberry PiのベアメタルにMicroPythonのREPLを追加するにあたって、Linux上でQEMUを使ってみました。

ARMのバイナリを動作させられるQEMUは、Ubuntuのパッケージで用意されていますのでインストールは簡単です。
Raspberry Piのバイナリを動かす場合は、
qemu-system-arm \
-kernel firmware.elf \
-cpu arm1176 \
-M versatilepb \
-m 256 \
-no-reboot \
-nographic \
-monitor null \
-serial stdio \
-redir tcp:10022::22

というようにすれば動作します。これはMakefileの中にもrunというターゲットで入れてあります。

ただ、QEMUを使う場合にはMini-UARTはうまく動作させるのは難しいようです。
ですので、QEMUの場合はMiniでないほうのUARTを使う必要があります。
今のところ、uart-qemu.cに通常のUARTとMini-UARTの両方を入れて、
#if 1 // 0ならMini-UART
通常のUARTのコード
#else
Mini-UARTのコード
#endif
というやり方で選択できるようにしてあります。

QEMU上で動作しているARM用バイナリは、クロス開発環境用のGDBでデバッグすることができます。

まず、QEMU上でのバイナリは"-s -S"オプションをつけて起動します。
$ qemu-system-arm -kernel build/firmware.elf -cpu arm1176 -M versatilepb -m 256 -no-reboot -nographic -monitor null -serial stdio -s -S


次に、同じマシンの別のターミナルからGDBを起動します。
そして、targetコマンドで「remote localhost:1234」を指定します。
$ arm-none-eabi-gdb -q build/firmware.elf
Reading symbols from build/firmware.elf...done.
(gdb) target remote localhost:1234
Remote debugging using localhost:1234
0x00008000 in start ()
(gdb)


あとは普通にGDBのコマンドが使えます。
よく使うのは

・l 現在位置のソースを表示
・n 次の行(関数の中には入らない)
・s ステップ(関数の中に入る)
・c continue
・b file:num fileのnum行をブレークポイントに
・b function functionの先頭をブレークポイントに
・p/x var 変数varを16進数表示(&varや*varという表現も可能)
・awatch var 変数varが読み書きされたらブレーク

あたりです。

以下に今回参考にしたサイトを挙げておきます。

piでベアメタルプログラミング - bobuhiro11's diary
RaspberryPi/kernel/src-qemu at master ・ richcole/RaspberryPi
QEMU ARM で遊ぼう
gdb の使い方・デバッグ方法まとめ

ちなみにQEMUでRaspbianを起動することもできますが、それにはQEMU用にビルドしたカーネルが必要です。
ビルド済みカーネルや起動方法は下記のGitHubにあります。

Home ・ dhruvvyas90/qemu-rpi-kernel Wiki

raspbian-on-qemu.png
posted by boochow at 01:45| Comment(0) | Raspberry Pi | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
※ブログオーナーが承認したコメントのみ表示されます。
人気記事