arm64(aarch64)のLinuxカーネルをQEMU上でgdbデバッグする

# 動機
クロスプラットフォーム(今回はaarch64)用のlinuxカーネルをPC上でお手軽に動かし、gdbで動きを見たい

# 環境
- OS: Ubuntu 16.04
- CPU: Intel(R) Core(TM) i7-3517U CPU @ 1.90GHz x4

# 使ったツール
- [Buildroot](https://buildroot.org/)
  - さまざまな組込linux環境を簡単に構築できるようにしてくれている便利ツール
  - クロスコンパイラなどのビルドツールチェーンも自動でビルドしてくれる
  - busyboxなどを使った最低限のrootfsも作ってくれる
  - さまざまな用途に使われることを想定しており、プラットフォームの構成管理という観点でもすごく勉強になる
- [QEMU](https://www.qemu.org/)
  - 言わずと知れたプロセッサエミュレータ
  - 例えばホストマシン(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
```

# 参考ページ
- [QEMU上のLinuxカーネルをGDBでデバッグする](https://www.hiroom2.com/2014/01/15/qemu%E4%B8%8A%E3%81%AElinux%E3%82%AB%E3%83%BC%E3%83%8D%E3%83%AB%E3%82%92gdb%E3%81%A7%E3%83%87%E3%83%90%E3%83%83%E3%82%B0%E3%81%99%E3%82%8B/)
- [Buildroot and QEMU – the quickest receipe for your own Linux](http://pressreset.net/2013/09/buildroot-and-qemu-the-quickest-receipe-for-your-own-linux/)
- [RaspberryPi3用rootfs作成 by Buildroot](https://qiita.com/takeoverjp/items/395fa419c4aa44b610d3)