qemu-arm を使う
qemu で ARM や MicroBlaze のエミュレーションが出来るそうなので、インストールして使ってみた。
インストールは configure, make するだけ。
$ wget http://download.savannah.gnu.org/releases/qemu/qemu-0.14.1.tar.gz $ tar xvfz qemu-0.14.1.tar.gz $ mkdir build $ cd build $ ../qemu-0.14.1/configure Error: zlib check failed Make sure to have the zlib libs and headers installed.
zlib.h が無いとコンパイルが通らないことがわかったので、
$ sudo apt-get install zlib1g-dev
で zlib をインストール。
そのまま、
$ make $ make install
で、/usr/local/bin/qemu-* がインストールされる。
インストールされたら、arm 用 gcc でコンパイル・リンクした hello world を動かしてみる。ダイナミックリンクにするかスタティックリンクにするかで、qemu 上での動かし方が変わる。まずはスタティックリンクの場合:
$ arm-none-linux-gnueabi-gcc -o arm_static -static hello.c $ file ./arm_static ./arm_static: ELF 32-bit LSB executable, ARM, version 1 (SYSV), for GNU/Linux 2. 6.16, statically linked, not stripped $ qemu-arm arm_static hello, world
ちゃんと動いた。
ダイナミックリンクしたプログラムを動かすには、-L でライブラリの場所を指定しなければならない。
引数に -L を入れない場合は以下のようにエラーになる:
$ arm-none-linux-gnueabi-gcc -o arm_dynamic hello.c $ file ./arm_dynamic ./arm_dynamic: ELF 32-bit LSB executable, ARM, version 1 (SYSV), for GNU/Linux 2 .6.16, dynamically linked (uses shared libs), not stripped $ qemu-arm arm_dynamic /lib/ld-linux.so.3: No such file or directory
引数に -L を入れると、
$ qemu-arm -L /usr/local/arm-2010q1/arm-none-linux-gnueabi/libc/ arm_dynamic hello, world
ちゃんと動いた。
MicroBlaze の場合は以下のようになる:
$ mb-linux-gcc -o mb hello.c $ qemu-microblaze -L /opt/xilinx/microblaze-unknown-linux-gnu/microblaze-unknow n-linux-gnu/ mb hello, world
引数 -L のオプションは一つしか指定出来ないようだ。自分でクロスコンパイルしたライブラリをロードさせるには、仕方がないので gnutools のライブラリと、自分でコンパイルしたライブラリを一つのディレクトリにコピーするなりして動作確認を行った。
qemu のコンパイル時の追記で、
最新版の qemu をコンパイルする場合、カーネルのバージョンが古いと普通に configure しただけではコンパイルが通らないことがある。
qemu は configure で、eventfd の有無をチェックしているが、カーネルの eventfd のバージョンが qemu 0.14 の期待しているバージョンより古く、かつ configure では eventfd のバージョンのチェックなどしないので、configure が通ってもコンパイルエラーが発生する問題があった。
エラー内容は、EFD_NONBLOCK が無い、というコンパイルエラーである。
カーネルが新しいと、linux/eventfd.h に EFD_NONBLOCK が定義されてる。
configure のオプションで eventfd を使わなくするような回避方法があれば良いのだが、調べたところ、そのような機能を configure は提供していないことがわかった。
無理やり configure を編集して make した:
$ diff -U 14 configure.org configure --- configure.org 2011-06-15 09:11:39.000000000 +0900 +++ configure 2011-06-15 09:11:29.000000000 +0900 @@ -2062,28 +2062,29 @@ # check if eventfd is supported eventfd=no cat > $TMPC << EOF #include <sys/eventfd.h> int main(void) { int efd = eventfd(0, 0); return 0; } EOF if compile_prog "" "" ; then eventfd=yes fi +eventfd=no