Raspberry Pi Type B 512MBを買ったのが8月のこと。Raspbianをインストールして無線LAN接続のためのUSBドングル(BUFFALO 無線LAN子機 WLI-UC-GNM)を挿してカメラモジュールをつないで、ちょっと遊んではみたもののそのまま放置していました。もったいない。

原因を考えてみたところ、

  • apt-getなどでインストールして遊びたいありもののソフトウェアはとくにない
  • 自分でRaspberry Pi用のプログラムを書きたい
  • 統合開発環境フリークの自分にとってはパフォーマンスが低すぎて開発機にはならない(Eclipseなどがまともに動かない)
  • それどころか、ちょっと複雑なライブラリをビルドしようとするとそれだけで数時間以上かかってしまう
  • しかも途中でエラーが起きたりして飽きる、だるい

ということのようです。

そこで、Windows上でRaspbianをエミュレーションし、ビルドなど面倒なことはそこでやって、実機にはバイナリのみデプロイすることにしました。基本的には QEMU – Emulating Raspberry Pi the easy way (Linux or Windows!) に書いてある方法の二番煎じです。この記事に従って作業すると、次のようなことができるようになります。

  • Windows版QEMUの上でRaspbian OSが動き、実機のRaspberry Piで動くバイナリをコンパイルできるようになる
  • 200MB程度しか空き容量がないRaspbianのディスクイメージを拡張し、2GB以上の容量を確保、さまざまなパッケージをインストールできるようになる
  • 256MBしかメモリを割り当てられないQEMUの制限に対し、スワップ領域を用意することで対処し、わりと多めのメモリを必要とする処理が可能になる
  • ExpanDriveを使うことで、QEMU上のRaspbian OSとホストマシンであるWindows間で簡単にファイルのやり取りができるようになる
raspbian-on-qemu-windows

WindowsでRaspbianが動いてる!

2015年1月4日追記; あけましておめでとうございます!

そういうのもあるのか!しかし、WindowsでARM Linux用のクロスビルド環境を簡単に作れる方法ってあるんでしょうか?とりあえずLinuxの方はこちらをどうぞ。Windows + Visual Studioでそれっぽいことをしてる人も海外にはいるようですね。

QEMUのインストール

QEMU(キューエミュ)は、Fabrice Bellardが中心となって開発しているオープンソースのプロセッサエミュレータである。

QEMU for Windowsからインストーラをダウンロードして実行します。記事執筆時点での64bit版Windows用の最新バイナリはqemu-w64-setup-20141210.exeでした。

このあと、QEMUバイナリがあるディレクトリ、例えば C:\Program Files\qemu などへパスを通します。

Raspbian ディスクイメージなどのダウンロード

Downloads | Raspberry Pi のOperating System ImagesからRaspbianの最新版をダウンロードして、ZIPを展開します。記事執筆時点での最新版は2014/12/24リリースのDecember 2014で、ファイル名は 2014-12-24-wheezy-raspbian.img でした。

あとは、Raspberry Piのプロセッサと互換性があるカーネルイメージが必要です。作り方が Compiling an ARM1176 kernel for QEMU に書いてありますが、幸い、ページ執筆者がダウンロード可能なバイナリを用意してくれています。リンク先の2行目にコンパイル済みカーネルへのリンク(kernel-qemu)があります。

一つのフォルダの中に以下の二つのファイルが入っているようにしてください。

  • YYYY-MM-DD-wheezy-raspbian.img (YYYY-MM-DDは2014-12-24など。以降、実際のファイル名に読みかえてください)
  • kernel-qemu

QEMUの起動

二つのファイルが揃ったフォルダの中で、コマンドプロンプトかPowerShellで以下のコマンドを実行します。うまくいけば、QEMU上でbashが起動します。

qemu-system-armw -kernel kernel-qemu -cpu arm1176 -m 256 -M versatilepb -no-reboot -serial stdio -append "root=/dev/sda2 panic=1 rootfstype=ext4 rw init=/bin/bash" -hda YYYY-MM-DD-wheezy-raspbian.img

ここで、 nano などを使って /etc/ld.so.preload の内容をコメントアウトします。

nano /etc/ld.so.preload
# このあとカーソルが一文字目に合っているはずなので "#" を入力します。
# "#" が挿入されたのを確認したら Ctrl+x を押します。
# ファイルを保存するか聞かれるので y とENTERキーを順に押します。

同様の手順で /etc/udev/rules.d/90-qemu.rules を作成します。起動時に、Raspberry Piが通常アクセスするマウントポイント(例えば /dev/root)からカーネルが見ているマウントポイント(例えば /dev/sda2)へシンボリックリンクを張る内容です。

KERNEL=="sda", SYMLINK+="mmcblk0"
KERNEL=="sda?", SYMLINK+="mmcblk0p%n"
KERNEL=="sda2", SYMLINK+="root"

最後にシステムをシャットダウンします。

halt

ディスク容量の拡張とRaspbianの起動

Raspbian ディスクイメージは200MB程度しか空き容量がなく、いろいろなパッケージをインストールするには不足です。そこで、ディスクイメージの容量を拡張します。Linuxなどではddコマンドで容量を拡張する方法が一般的のようですが、Windowsではcopyコマンドを使って二つのディスクイメージを連結すれば同じ結果を得られます。 Is it possible to resize a QEMU disk image? を参考にしました。

# 2GB拡張する場合
qemu-img create -f raw temp.img 2G
copy /b YYYY-MM-DD-wheezy-raspbian.img+temp.img raspbian.img

以降、QEMUでは生成された raspbian.img を使います。 YYYY-MM-DD-wheezy-raspbian.img はごみ箱に捨てて構いません。 temp.img はあとでスワップ領域用に再利用します。

先ほどの起動コマンドから init=/bin/bash を消し、 -hda オプションが YYYY-MM-DD-wheezy-raspbian.img でなく raspbian.img を指すようにします。

qemu-system-armw -kernel kernel-qemu -cpu arm1176 -m 256 -M versatilepb -no-reboot -serial stdio -append "root=/dev/sda2 panic=1 rootfstype=ext4 rw" -hda raspbian.img

Raspbianにユーザ名 pi パスワード raspberry でログインしたら、fdiskでパーティションテーブルを書き換え、Raspbianが使えるディスク容量を増やします。

sudo fdisk /dev/sda

ここまで書いて気づいたんですが、ほぼ同じことをしている日本の方がいますね。 Raspberry Pi のイメージファイルを拡張する という記事です。

現在のパーティションテーブルを確認します.

というところから読み進めてください。

なお、僕の環境ではRaspbian上で日本語がうまく表示できなかったのですが、 jfbterm をインストールし、その上で作業するようにしたら解決しました。

sudo apt-get install jfbterm

スワップ領域の拡張

さて、ディスク容量も2GB増えて、いろいろインストールできるようになったのはいいのですが、実際にさまざまなコードをビルドしようと思うと、QEMUの256MBのメモリ制限がきつくなってきます。僕の場合、OpenCVのビルド中にメモリが足りなくなって、 make がエラー終了してしまいました。

qemu-system-armw にはRAM容量を指定できる -m オプションがあるのですが、256を超えた値ではRaspbianが起動しないそうです。

そこで、Raspberry Piフォーラムの書き込みを参考に、先ほど作成した temp.img をQEMUに二つ目のディスクとして読み込ませ、全体をスワップ領域として使えるようにします。起動コマンドは次の通りです。

qemu-system-armw -kernel kernel-qemu -cpu arm1176 -m 256 -M versatilepb -no-reboot -serial stdio -append "root=/dev/sda2 panic=1 rootfstype=ext4 rw" -hda raspbian.img -hdb temp.img

Raspbianが起動したら、次のコマンドを実行するだけです。

mkswap /dev/sdb
swapon /dev/sdb

もしRAMディスクを作成できるようなソフトウェアを持っていたら、 temp.img をRAMディスク上に置いてやれば、アクセスが段違いに高速化すると思います。

RaspbianとWindows間のファイル交換

QEMU上のRaspbianとホストとなっているWindowsの間でファイル交換する方法については、Raspbian上でSambaを動かすとかやり方はいろいろあると思うのですが、僕は、SFTPサーバをネットワークドライブとしてマウントできるExpanDriveを使っています。

RaspbianはデフォルトでSSHサーバが起動するようになっているので、QEMUの起動コマンドに-redir "tcp:10022::22"と書き足して、次のようにすれば、WindowsからSSHログインできるようになります。

qemu-system-armw -kernel kernel-qemu -cpu arm1176 -m 256 -M versatilepb -no-reboot -serial stdio -append
"root=/dev/sda2 panic=1 rootfstype=ext4 rw" -redir "tcp:10022::22" -hda raspbian.img -hdb temp.img

あとはExpanDriveでSFTPサーバ 127.0.0.1 のポート 10022 に接続すれば、Raspbianのホームディレクトリの中身が普通のフォルダのようにアクセスできるようになります。いつも使っているGUIベースのテキストエディタで設定ファイルを編集することもできます。


One Response to “Windows+QEMUでRaspberry Piをエミュレートする”

Trackbacks and Pingbacks:

  1. Raspberry PiでJavaCV(Java + OpenCV) | junkato.jp

    […] にして、先の記事でセットアップしたQEMU上で #大晦日ハッカソン を続けておりました。 […]

Leave a Reply

  • (will not be published)