2014年4月22日

Raspberry PiをQEMUエミュレータ上で走らせる(1) QEMUのインストールとカーネルの起動

Raspberry Piを使ったCaller ID+天気予報付きディジタル時計プロジェクトを加速することにした。

今回は小生の通常の「字ばっかり」のプロジェクトと違ってXウィンドウを使ったUI(表示のみ)なので、表示具合を確認しながら進めなければならないが、実機がないと開発できないというのはやりにくい。そこで、QEMUを使って実機なしでエミュレートすることを計画した。

RPi用のQEMUについては、こちらこちらの記事を参考にしたが、(当然のことながら)記事のとおりに進めてもその通り動作しない。以下にカットアンドトライで試した結果を報告する。

QEMUのインストール

まずはQEMUのインストールから。ホストは我が家の何でも屋のFC13(x86 32bit 8GB)。他のディストロでは少々違いがあるかもしれないが、そこは工夫してください。
 
上記記事によると、ほとんどのディストロの標準パッケージのQEMUはRPiのCPU(arm1176)をサポートしておらず、また実際にサポートしていないことが確認できたので、パッケージのインストールは諦め、ソースから作ることにする。

まず、適当な作業用ディレクトリを作り、そこにQEMUのGITをクローンする。

h@spice:~/projects$ mkdir rpi
h@spice:~/projects$ cd rpi
h@spice:~/projects/rpi$ git git://git.qemu-project.org/qemu.git

あとは普通にconfigureとmakeを走らせる。上記記事ではPREFIXを「/usr」にしているが、標準パッケージとのガチンコを避けるためにデフォルトの「/usr/local」にしておく。「git submodule update --init dtc」は、configureがDTC(libfdt)が見つからないと文句をいい、「libfdt-devel」パッケージが見つからなかったので。

h@spice:~/projects/rpi$ cd qemu
h@spice:~/projects/rpi/qemu$ git submodule update --init dtc
h@spice:~/projects/rpi/qemu$ ./configure --target-list="arm-softmmu arm-linux-user"    \
            --enable-sdl    \
            --prefix=/usr/local
 
・・・

h@spice:~/projects/rpi/qemu$ make
・・・

h@spice:~/projects/rpi/qemu$ sudo make install

上記記事では、ここで「qemu-system-arm -cpu help」でRPiのCPU(arm1176)がサポートされているかどうか確認することになっているが、これが上手くいかない。代わりに「qemu-arm -cpu ?」は動いたので、これでよいことにする。

h@spice:~/projects/rpi/qemu$ qemu-system-arm -cpu help
No machine specified, and there is no default.
Use -machine help to list supported machines!

h@spice:~/projects/rpi/qemu$ qemu-arm -cpu ?  
Available CPUs:
  arm1026
  arm1136
  arm1136-r2
  arm1176
・・・

RPiのイメージファイル

次は、また適当な作業ディレクトリを作って、カーネルイメージとディスク(SDカード)イメージファイルを作る。
カーネルイメージファイル: 自前のカーネルはダメ。以下のように専用カーネルをダウンロードする。
ディスクイメージファイル: 動作するディスクイメージ(ファイルシステムイメージではない)なら何でもよい。ここでは実機「rpi」からコピーしてみた(このコピーは時間がかかるので先行してバックグラウンドで実行するとよい)。

言い忘れたが、この作業ディレクトリはディスクイメージファイル(小生の実機は8GB)を 作るので、ホストに十分なディスク空き容量があることを確認しておく。

h@spice:~/projects/rpi$ mkdir rpi-emu
h@spice:~/projects/rpi$ cd rpi-emu
h@spice:~/projects/rpi/rpi-emu$ wget http://xecdesign.com/downloads/linux-qemu/kernel-qemu
h@spice:~/projects/rpi/rpi-emu$ ssh rpi if=/dev/mmcblk0 bs=16M >rpi.img

イメージファイルができたらQEMUを起動する。

h@spice:~/projects/rpi/rpi-emu$ qemu-system-arm -kernel kernel-qemu -cpu arm1176 -m 256 -M versatilepb -serial stdio -append "root=/dev/sda2 panic=1 rootfstype=ext4 rw init=/bin/bash" -hda rpi.img
audio: Could not init `oss' audio driver
Uncompressing Linux... done, booting the kernel.

お馴染みの「Uncompressing Linux...」が表示され、デスクトップにRPiのコンソールウィンドウが現れるので嬉しくなる。

ここでのキモは、カーネルコマンドラインの「init=/bin/bash」で、ユーザレベルの初期化を何もせずにいきなりbashを起動する

もし何らかのエラーがありカーネルがパニックになると、上記のコマンドラインでは自動的にリブートを繰り返す。「-no-reboot」オプションを追加すると、リブートせずにQEMUが終了する。いずれにせよデバックがやり辛いので、パニックのメッセージがコンソールに表示されたらコンソールウィンドウの MENU>PAUSE でウィンドウを止める。残念ながらこのウィンドウはスクロールできないようなので(もしかしたらできるかもしれないがよく分からない)、PAUSEは上手くタイミングを計らねばならない。

下はわざとエラーを起こして見たところ(ディスクイメージファイルが完成しないうちにマウントさせようとした)。


順調に行けば、bashのプロンプトが出てきて「やった~!」となるが、世の中そう甘くはない。起動しただけの状態では、言わば丸裸で、/procさえマウントされていないから、色々なシステムユーティリティが動かない。取りあえずちょっとだけやってみる。


ダミーのネットワークインタフェースが見えるが、MACアドレスはわざとらしい「~00:12:34:56」。カーネルのバージョンは、実機の3.10.24+ #614より新しそう。

取りあえずカーネルは動き、シェルが動くようになった。次はここでネットワークとXウインドウを動かすが、それは次回に。

おっと、一言。QEMUのコンソールウィンドウは、クリックすると以降のマウスクリックやキーボードの入力をすべてトラップするので、意図せずにトラップされた時は、パニックらずに「Ctrl+Alt+G」で逃げ出す。

0 件のコメント:

コメントを投稿