はじめに
QEMU user-mode emulationの使い方を説明します。
仮想CPUはARMを使います。
install
QEMU / gcc-arm を installします。
console
$ sudo apt-get install -y qemu gcc-arm-linux-gnueabi gdb-arm-none-eabi
gdb-arm-none-eabiのinstallで以下エラーが出る場合があります。
.../gdb-arm-none-eabi_7.6.50.20131218-0ubuntu1+1_amd64.deb を展開する準備をしています ...
gdb-arm-none-eabi (7.6.50.20131218-0ubuntu1+1) を展開しています...
dpkg: アーカイブ /var/cache/apt/archives/gdb-arm-none-eabi_7.6.50.20131218-0ubuntu1+1_amd64.deb の処理中にエラーが発生しました (--unpack):
'/usr/share/man/man1/gdb.1.gz' を上書きしようとしています。これはパッケージ gdb 7.7.1-0ubuntu5~14.04.3 にも存在します
dpkg-deb: エラー: サブプロセス ペースト がシグナル (Broken pipe) によって強制終了されました
man-db (2.6.7.1-1ubuntu1) のトリガを処理しています ...
処理中にエラーが発生しました:
/var/cache/apt/archives/gdb-arm-none-eabi_7.6.50.20131218-0ubuntu1+1_amd64.deb
E: Sub-process /usr/bin/dpkg returned an error code (1)
バグのようですが
https://bugs.launchpad.net/ubuntu/+source/gdb-arm-none-eabi/+bug/1320305
以下コマンドで強制的にinstallしてください。
$ sudo apt-get -o Dpkg::Options::="--force-overwrite" install gdb-arm-none-eabi
sample code
sample codeをgcc-armでコンパイルして、QEMUで実行します。
ライブラリパスをQEMU_LD_PREFIX or -Lで指定できます。
console
$ cat test.c
#include <stdio.h>
int main(int argc, char* argv[])
{
printf("Hello!\n");
return 0;
}
$ arm-linux-gnueabi-gcc -g test.c
$ QEMU_LD_PREFIX=/usr/arm-linux-gnueabi qemu-arm a.out
Hello!
$ qemu-arm -L /usr/arm-linux-gnueabi a.out
Hello!
gdb
gdbを使ってデバッグします。
qemu-armの-gオプションでgdb接続待ちにします。1234はprot numberです。
console_A
$ qemu-arm -g 1234 -L /usr/arm-linux-gnueabi a.out
.gdbinitを設定します。catを参照ください。
arm用のgdbを起動します。
console_B
$ cat $HOME/.gdbinit
set auto-load safe-path ~
set pagination 0
$ cat .gdbinit
set architecture armv5t
set sysroot /usr/arm-linux-gnueabi
b main
target remote :1234
c
$ arm-none-eabi-gdb ./a.out
GNU gdb (7.6.50.20131218-0ubuntu1+1) 7.6.50.20131218-cvs
(...)
Reading symbols from ./a.out...done.
The target architecture is assumed to be armv5t
Breakpoint 1 at 0x8454: file test.c, line 5.
warning: A handler for the OS ABI "GNU/Linux" is not built into this configuration
of GDB. Attempting to continue with the default armv5t settings.
Cannot access memory at address 0x0
0xf67d6d10 in ?? ()
Breakpoint 1, main (argc=1, argv=0xf6fff204) at test.c:5
5 printf("Hello!\n");
(gdb)