動機
クロスプラットフォーム(今回はaarch64)用のlinuxカーネルをPC上でお手軽に動かし、gdbで動きを見たい
環境
- OS: Ubuntu 16.04
- CPU: Intel(R) Core(TM) i7-3517U CPU @ 1.90GHz x4
使ったツール
-
Buildroot
- さまざまな組込linux環境を簡単に構築できるようにしてくれている便利ツール
- クロスコンパイラなどのビルドツールチェーンも自動でビルドしてくれる
- busyboxなどを使った最低限のrootfsも作ってくれる
- さまざまな用途に使われることを想定しており、プラットフォームの構成管理という観点でもすごく勉強になる
-
QEMU
- 言わずと知れたプロセッサエミュレータ
- 例えばホストマシン(x86)上でaarch64用の実行ファイルをエミュレートしてくれたりする。
- 純粋なプロセッサエミュレーション(ベアメタル)だけでなく、OS上の環境をエミュレーションすることも可能
手順
1. BuildrootによるLinux imageのビルド
- バージョン2017.02.9
- 確認時点(2018/1/21)でのLatest long term support
$ curl -O https://buildroot.org/downloads/buildroot-2017.02.9.tar.bz2
$ tar xf buildroot-2017.02.9.tar.bz2
$ cd buildroot-2017.02.9
$ make qemu_aarch64_virt_defconfig
$ unset LD_LIBRARY_PATH
$ make BR2_JLEVEL=`getconf _NPROCESSORS_ONLN`
$ cd ..
2. QEMUのビルド
- バージョン2.11.0
- 確認時点(2018/1/21)でのLatest releases
- Ubuntu16.04の場合、aptからでも2.5がインストールできるが、その場合buildrootが作成するイメージを起動できない(詳細未調査)
-
board/qemu/aarch64-virt/readme.txt
を確認すると、Tested with QEMU 2.6.0
と書かれているため、それ以降のバージョンをインストール
- aarch64用のQEMUをビルドする。
$ sudo apt install zlib1g-dev libglib2.0-dev libpixman-1-dev
$ curl -O https://download.qemu.org/qemu-2.11.0.tar.xz
$ tar xf qemu-2.11.0.tar.xz
$ cd qemu-2.11.0
$ ./configure --target-list=aarch64-softmmu
$ make -j`getconf _NPROCESSORS_ONLN`
$ cd ..
3. QEMUの実行
- 少し長いが、パス以外は
board/qemu/aarch64-virt/readme.txt
と同じ - 成功していれば、ログインプロンプトが表示される
- ユーザ名"root"で、パスワードはなし
$ qemu-2.11.0/aarch64-softmmu/qemu-system-aarch64 -M virt -cpu cortex-a57 -nographic -smp 1 -kernel buildroot-2017.02.9/output/images/Image -append "console=ttyAMA0" -netdev user,id=eth0 -device virtio-net-device,netdev=eth0
4. aarch64用gdbのビルド&インストール
- バージョン8.0.1
- 確認時点(2018/1/21)でのLatest releases
Ubuntu 16.04では、aarch64用gdbがパッケージとして提供されていない模様(なんでだろう。。。)- (追記)aarch64用としても使える、gdb-multiarchがパッケージとして提供されていました。下記のようにわざわざビルドしなくても、
sudo apt install gdb-multiarch
で十分です。
$ sudo apt install texinfo
$ curl -O http://ftp.gnu.org/gnu/gdb/gdb-8.0.1.tar.xz
$ tar xf gdb-8.0.1.tar.xz
$ cd gdb-8.0.1
$ ./configure --target=aarch64-linux-gnu
$ make -j`getconf _NPROCESSORS_ONLN`
$ sudo make install
$ cd ..
5. Linuxカーネルをデバッグ情報付きでビルド
- busyboxが
configs/qemu_aarch64_virt_defconfig
で使用している、board/qemu/aarch64-virt/linux-4.9.config
では、デバッグ情報がついていない - 下記では、手順として書きやすいよう
linux-4.9.config
を直接編集しているが、デフォルトを変更したくない場合はlinux-menuconfig
でも変更可能
$ cd buildroot-2017.02.9
$ echo "CONFIG_DEBUG_KERNEL=y" >> board/qemu/aarch64-virt/linux-4.9.config
$ echo "CONFIG_DEBUG_INFO=y" >> board/qemu/aarch64-virt/linux-4.9.config
$ make BR2_JLEVEL=`getconf _NPROCESSORS_ONLN`
$ cd ..
6. LinuxカーネルをGDBでデバッグ
- さらに長くなるが、3.に以下の2つのオプションを追加しただけ
-
-gdb
: gdbクライアントからの接続を待つデバイスを指定-
tcp::4321
でTCPポート4321でlistenする
-
-
-S
: 起動時にCPUを停止する- このオプションにより、startupからgdbデバッグできるようになる
-
6-1. gdbオプション付きでQEMU起動
$ qemu-2.11.0/aarch64-softmmu/qemu-system-aarch64 -M virt -cpu cortex-a57 -nographic -smp 1 -kernel buildroot-2017.02.9/output/images/Image -append "console=ttyAMA0" -netdev user,id=eth0 -device virtio-net-device,netdev=eth0 -gdb tcp::4321 -S
6-2. gdbを起動
$ aarch64-linux-gnu-gdb -i=mi buildroot-2017.02.9/output/build/linux-4.9.6/vmlinux
(gdb) target remote :4321
Remote debugging using :4321
warning: Can not parse XML target description; XML support was disabled at compile time
0x0000000040000000 in ?? ()
(gdb) b start_kernel
Breakpoint 1 at 0xffffff80085907e0
(gdb) c
Continuing.
Breakpoint 1, start_kernel () at init/main.c:480
480 {
(gdb) p jiffies
$3 = 4294892296