FuchsiaをビルドしてQEMUのGDB-stubでデバッグします。2016年8月現在、arm32はspin_lockでデッドロックしてるようで、途中で止まります。
Table of Contents
1 QEMUで動かす
magenta/docs/getting_started.mdに記載されています。
1.1 ダウンロード
Fuchsiaをダウンロードします。
$ git clone https://fuchsia.googlesource.com/magenta
1.2 ビルドに必要なパッケージ
Fuchsiaのビルドに必要なパッケージをインストールします。
$ sudo apt install -y texinfo libglib2.0-dev autoconf libtool \ libsdl-dev build-essential
1.3 クロスツールチェイン
クロスツールチェインをダウンロードします。
$ ./scripts/download-toolchain
prebuilt/downloadsに配置されます。
$ ls prebuilt/downloads/ aarch64-elf-5.3.0-Linux-x86_64 arm-eabi-Linux-x86_64.tar.bz2 aarch64-elf-Linux-x86_64.stamp x86_64-elf-5.3.0-Linux-x86_64 aarch64-elf-Linux-x86_64.tar.bz2 x86_64-elf-Linux-x86_64.stamp arm-eabi-5.3.0-Linux-x86_64 x86_64-elf-Linux-x86_64.tar.bz2
このツールチェインに含まれるGDBはlayoutコマンドが無効となっているので、GDB用にツールチェインをビルドします。2時間ほどかかります。
$ sudo apt build-dep -y gcc gdb $ git clone https://fuchsia.googlesource.com/third_party/gcc_none_toolchains $ cd gcc_none_toolchains $ ./doit -a 'arm aarch64 x86_64' -f $ cd ..
1.4 ビルド
ターゲットとなるボードをmakeで指定します。数分で完了します。
$ make <target>
build-<target>に作成されます。
build-<target>
この記事ではmagenta-pc-x86-64を指定します。
$ make magenta-pc-x86-64
<target>の一覧は以下のとおりです。<target>を省略した場合はmagenta-pc-x86-64となります。
$ make list List of all buildable projects: (look in project/ directory) qemu-virt-a53-test rpi3-test magenta-pc-x86-64 pc-x86-64-test magenta-qemu-arm32 pc-x86-test qemu-virt-a15-test magenta-qemu-arm64
1.5 QEMU
aptでインストールしても良いのですが、Fuchsiaのリポジトリで用意しているQEMUは若干パッチを当てているようなのでビルドしてインストールします。
$ sudo apt build-dep -y qemu $ git clone https://fuchsia.googlesource.com/third_party/qemu $ mkdir qemu.build $ cd qemu.build $ ../qemu/configure --target-list=arm-softmmu,aarch64-softmmu,x86_64-softmmu $ make && sudo make install
QEMUを起動します。
$ ./scripts/run-magenta-x86-64
使用できる引数は以下のとおりです。
$ ./scripts/run-magenta-x86-64 -h help: -a <arch> : arm32, arm64, or x86-64 -b : build first -c : add item to kernel commandline -d : run with emulated disk -g : use graphical console -k : use KVM -m <memory in MB> : default 512MB -n : run with emulated nic -N : run with emulated nic via tun/tap -o <dir> : build directory -r : run release build -u : use uniprocessor -v : use vnc based display -x <bootfs> : add eXtra bootfs -h for help all arguments after -- are passed to qemu directly
2 GDB-stubでデバッグする
GDBでカーネルとuappのコードを追跡できるようにします。
2.1 QEMU
qemu-system-xxxコマンドを直接実行しても良いのですが、以下の様にスクリプトを変更します。
diff --git a/scripts/run-magenta b/scripts/run-magenta index 555c64d..e1102ae 100755 --- a/scripts/run-magenta +++ b/scripts/run-magenta @@ -22,6 +22,7 @@ function HELP { echo "-u : use uniprocessor" echo "-v : use vnc based display" echo "-x <bootfs> : add eXtra bootfs" + echo "-G <port> : gdb port" echo "-h for help" echo "all arguments after -- are passed to qemu directly" exit 1 @@ -43,8 +44,9 @@ RELEASE=0 VNC=0 INITRD= CMDLINE="" +GDBPORT="" -while getopts a:Abc:dgkm:nNo:ruvx:h FLAG; do +while getopts a:Abc:dgkm:nNo:ruvx:G:h FLAG; do case $FLAG in a) ARCH=$OPTARG;; A) AUDIO=1;; @@ -61,6 +63,7 @@ while getopts a:Abc:dgkm:nNo:ruvx:h FLAG; do u) UP=1;; v) VNC=1;; x) INITRD=$OPTARG;; + G) GDBPORT=$OPTARG;; h) HELP;; \?) echo unrecognized option @@ -189,6 +192,11 @@ if [ "$INITRD" != "" ]; then ARGS+=" -initrd $INITRD" fi +# gdb port +if [ "$GDBPORT" != "" ]; then + ARGS+=" -gdb $GDBPORT -S" +fi + # run qemu echo $QEMU $ARGS -append "$CMDLINE" $@ $QEMU $ARGS -append "$CMDLINE" $@
QEMUを起動します。
$ ./scripts/run-magenta-x86-64 -G tcp::10000
2.2 GDB
x86_64-elf-5.3.0-Linux-x86_64/bin/x86_64-elf-gdbだと以下のエラーが出てしまいます。
Remote 'g' packet reply is too long: 000000000...
Ubuntu 16.04のgdb64ならば出ないのでそちらを使います。
$ sudo apt install -y gdb64
以下のスクリプトを用います。
$ cat gdb.x symbol-file build-magenta-pc-x86-64/magenta.elf set architecture i386:x86-64 target remote localhost:10000 b lk_main la src c
GDBを起動します。
$ gdb64 -x gdb.x
scripts/run-magenta-arm64の場合は、先ほどビルドしたgcc_none_toolchains/aarch64-elf-5.3.0-Linux-x86_64/bin/aarch64-elf-gdbを使います。scripts/run-magenta-arm32も同様です。
2.3 実行結果
アーキテクチャ固有のアセンブラが実行された後、共通部分のlk_main関数が実行されます。
kernel/arch/xxx/xxx/start.S -> lk_main at kernel/top/main.c
以下のようにlk_mainでbreakしています。
2.4 GDB-stubでuserbootをデバッグする
userbootはカーネルからユーザアプリケーションへ制御を切り替えるプログラムです。Linuxのinitに近いものです。
bootstrap2 (kernel) -> userboot_init (kernel) -> userboot (uapp) -> ... -> bin/mxsh (uapp)
userboot (uapp)がロードされるアドレスはログ出力されます。
[00001.069] K userboot: userboot-code 0x2000 @ [0x1002000,0x1004000)
add-symbol-fileでuserboot (uapp)をロードします。
$ cat gdb.x symbol-file build-magenta-pc-x86-64/magenta.elf set architecture i386:x86-64 target remote localhost:10000 add-symbol-file build-magenta-pc-x86-64/uapp/userboot/libuserboot.so 0x1002000 b _start la src c
先ほどと同様にQEMUとGDBを起動すると、以下のようにuserboot (uapp)の_start関数でbreakされました。
bin/devmgr (uapp)もロードアドレスが割り出せれば追跡可能だと思います(割り出せてないので未確認)。