Raspberry Pi用バイナリをQEMUエミュレータで動かす方法(ユーザーモードエミュレーション)

Mathematicaが無料になって以来、Raspberry Piを触る機会が増えました。Raspberry Piの良さは、各種センサーを比較的容易に使えることにあり、そういうことをしないなら、Raspberry Piはあまりいいハードウェアではありません。メモリはたった512MBしかなく、CPUは32ビットのARM、そのクロックは700MHzと低速です。

実験のために、Raspberry Pi用のバイナリを動かしたいことがあるのですが、この性能の低さに憂鬱になります。インテル入ってるのPCは、Raspberry Piよりはるかに高性能なので、Raspberry Pi用のバイナリをRaspberry Pi上ではなくPC上で動かせればいいのですが、CPUが違うので、Raspberry Pi、つまりARM用のバイナリを、インテルのCPUでそのまま動かすことはできません。

そこで、QEMUでエミュレートすることを考えます。QEMUのエミュレーションには、システム全体をエミュレートする方法と、ユーザーモードだけをエミュレートする方法があります。

以前紹介した方法(Windowsの場合Ubuntuの場合)は、システム全体をエミュレートする方法です。比較的高性能なPCなら、システム全体をエミュレートしても、実機と同程度の性能を発揮できます(メモリが256MBという問題がありましたが)。

ここではユーザーモードをエミュレートする方法を紹介します。この方法には、システム全体をエミュレートするよりも軽く、使えるメモリも多い(ホストに十分なメモリがあれば)というメリットがあります。

Ubuntuで試します。

まず、Raspbianのイメージをダウンロードします。2013-12-24以降がいいでしょう。

wget http://downloads.raspberrypi.org/raspbian/images/raspbian-2014-01-09/2014-01-07-wheezy-raspbian.zip

fdisk -l 2014-01-07-wheezy-raspbian.img」などとして、2番目のパーティションの始点を調べます(2014-01-07-wheezy-raspbian.imgの場合は122880です)。これに512をかけた結果(62914560)を後で使います。

qemu-user-staticをインストールし、作業用ディレクトリを作ります(この作業は1回だけやればいいです)。

sudo apt-get install qemu-user-static
mkdir rootfs

イメージをマウントします。

sudo mount -o offset=62914560 2014-01-07-wheezy-raspbian.img rootfs

エミュレーション環境を整えます(この作業は1回だけやればいいです)。

sudo cp /usr/bin/qemu-arm-static rootfs/usr/bin/
sudo sed -i 's/^/#/' rootfs/etc/ld.so.preload

エミュレーションを開始します。

sudo QEMU_CPU=arm1176 chroot rootfs

qemu-arm-staticがデフォルトでエミュレートするアーキテクチャはARMV7lですが、Raspberry PiはARMV6l(CPUはARM1176)なので、環境変数をそのように設定しています(arm1176の代わりにarm11mpcoreとすればマルチコアになります)。事前に「xhost local:localhost」とすればXの画面も持ってこられます。

後はご自由に。

Ubuntu上のエミュレータ(QEMU)で動作するRaspbian

システム全体をエミュレートする必要がない場合は、ユーザーモードエミュレーションのほうがいいでしょう。

Raspberry PiのためのディストリビューションであるRaspbianを、Windows上のQEMUで動かす方法を以前紹介しました。

Raspberry PiのためのディストリビューションであるRaspbianを、Ubuntu上のQEMUで動かす方法が、HOWTO: Virtual Raspbian on Qemu in Ubuntu Linux 12.10で紹介されています。

記事では2013-02-09-wheezy-raspbian.imgを使っていますが、2013-09-25-wheezy-raspbian.imgや2014-01-07-wheezy-raspbian.imgでも動作しました(ディスクの拡張のためにWindowsの場合にもやったような面倒な作業も)。「file ~/qemu_vms/2013-02-09-wheezy-raspbian.img」は「file -k ~/qemu_vms/2013-02-09-wheezy-raspbian.img」でしょうか。

起動はこんな感じ。(localhost:10022でSSHに、localhost:15901でVNCに接続できるようにしています。)

qemu-system-arm -kernel kernel-qemu -cpu arm1176 -m 256 -M versatilepb -no-reboot -serial stdio -append "root=/dev/sda2 panic=1" -hda 2013-09-25-wheezy-raspbian.img -redir tcp:10022::22 -redir tcp:15901::5901

GUIはRaspberry Pi側でVNC Serverを起動し、ホスト側で「vncviewer localhost::15901」とすれば(startxよりこっちが好き)。

SSHでのログインは「ssh -p 10022 pi@localhost」で行えます。下の画像のように、Raspbianを起動したシェルでそのままログインできるのですが、SSHを使えるようにしておけば、scpも使えるので便利かもしれません。

4822234800背景の理解などには日経Linux『誰でもできる! Raspberry Piで楽しもう』(日経BP社, 2013)が役立ちました。

Windows上のエミュレータ(QEMU)で動作するRaspbian

システム全体をエミュレートする必要がない場合は、ユーザーモードエミュレーションのほうがいいでしょう。

B00CBWMXVERaspberry Piのためのディストリビューション、Raspbianは、QEMU上でも動作します。この記事では、Windows上のQEMU上でRaspbianを動かす方法を紹介します。

いろいろ面倒なので、最終的に動かすのはWindows上のQEMUだとしても、ディスクイメージを作り直す作業(下の手順2)はUbuntuでやったほうがよさそうです。

(1)
Windows上で試すにはちょっと工夫が必要なのですが、Raspberry Pi emulation for Windowsなら、展開してrun.batをダブルクリックするだけで動くようになっているので、今回はこれを使います。(参考:Raspberry Pi:QEmuで仮想環境

(2)
これはとばしてもかまいませんが、その場合は(3)のraspbian.img2012-07-15-wheezy-raspbian.imgのままにしてください。

ディスクイメージ2012-07-15-wheezy-raspbian.imgの空き容量が不十分なので、VirtualBoxで作った4GBの仮想ディスクに、Ubuntuで「sudo dd if=2012-07-15-wheezy-raspbian.img of=/dev/sdb」として書き込み、gpartedでパーティションを拡大、「sudo dd if=/dev/sdb of=raspbian.img」として作り直します(空き領域に新パーティションを作ってそれを削除してから拡張するとうまくいくとか)。もっとよい方法があるのでしょうが、「qemu-img.exe resize 2012-07-15-wheezy-raspbian.img +2G」とraspi-configのexpand=rootfsではうまくいきませんでした。

(3)
qemu/run.batの内容を以下のように修正します。「-m 256」はメモリを256MBにするオプション(これより大きくしても無効)、「-redir tcp:10022::22」と「-redir tcp:15901::5901」はSSHサーバとVNCサーバにアクセスしやすくするためのオプションです(参考:Raspberry Pi:QEMUとの通信)。

qemu-system-arm.exe -M versatilepb -cpu arm1176 -hda raspbian.img -kernel kernel-qemu -m 256 -append "root=/dev/sda2" -redir tcp:10022::22 -redir tcp:15901::5901

(4)
run.batをダブルクリックして、Raspbianを起動させます。Raspbianの設定ツールであるraspi-configが起動するので、「ssh」でSSHサーバを有効にし、「change_pass」でパスワードを簡単なものに変えて、タブ→Finishで終わらせます。(初期設定ではユーザpi、パスワードはraspberry)。

(5)
メモリが少ないのですが(256MB)、増やす方法がわからないので、とりあえず、スワップ領域を512MBに増やします(参考:Raspberry Pi のswap領域変更)。

(6)
パッケージリストを更新し、VNCサーバをインストールします。(startxよりこっちが好きです。)

sudo apt-get update && sudo apt-get install tightvncserver

(7)
vncserver -geometry 1200x800」としてVNCサーバを起動させます(解像度の指定はオプショナルです)。

(8)
WindowsにTightVNC(クライアントのみ)をインストール・起動し、「localhost:15901」にアクセスして、GUIを利用できるようにします。

(9)
GUIがいらないときは、localhost:10022にSSHでログインするといいでしょう。