2017/7/5版のRaspbian JessieをQEMUでエミュレート動作させた際の手順です。
もはや何番煎じだか分かりませんが、メモとして。
2018/4/12追記
Stretch 2018/3/13版での手順を投稿しました。
https://qiita.com/Nebutan/items/1cffada81e61a9f2ed58
前提
- エミュレートするRaspberry Piは1/Zero相当です。1
- 実行環境はUbuntu 17.04です。
- QEMUとkpartxを事前にインストールしておきます。
$ sudo apt-get install qemu kpartx
- RaspbianはLite版を使用します。
- 各ファイルはカレントディレクトリ上にあるものとします。
手順
必要ファイルをダウンロードする
Raspbianイメージファイル
まずはRaspbianのイメージファイルをダウンロードします。
公式は https://www.raspberrypi.org/downloads/raspbian/ ですが、日本では北陸先端大にあるミラーサーバ http://ftp.jaist.ac.jp/pub/raspberrypi/raspbian_lite/images/ を利用する方が早くダウンロードできます。2
$ wget http://ftp.jaist.ac.jp/pub/raspberrypi/raspbian_lite/images/raspbian_lite-2017-07-05/2017-07-05-raspbian-jessie-lite.zip
ダウンロードしたら展開をお忘れなく。
$ unzip 2017-07-05-raspbian-jessie-lite.zip
QEMU用カーネル
https://github.com/dhruvvyas90/qemu-rpi-kernel よりQEMU用カーネルをダウンロードします。
Raspbian Jessie 2017/7/5版のカーネルは4.9ですが、上記リポジトリのQEMU用カーネルは最新でも4.4.34なので、そちらをダウンロードします。
(4.4.34でも動作します)
$ wget https://github.com/dhruvvyas90/qemu-rpi-kernel/raw/master/kernel-qemu-4.4.34-jessie
イメージを編集する
後述の理由によりこのままではQEMU上で動作しませんので、Raspbianイメージ内の一部設定ファイルを変更する必要があります。
イメージのマウント
Raspbianイメージのルートパーティションをホストの /mnt にマウントします。
$ sudo kpartx -a 2017-07-05-raspbian-jessie-lite.img
$ sudo mount /dev/mapper/loop0p2 /mnt -o loop,rw
Raspbian設定ファイルの編集
Raspbianイメージの /etc/ld.so.preload を編集し、/usr/lib/arm-linux-gnueabihf/libarmmem.so
の行を削除または # でコメントアウトします。3
$ sudo vi /mnt/etc/ld.so.preload
次いで /etc/udev/rules.d/90-qemu.rules を新規作成します。
$ sudo vi /mnt/etc/udev/rules.d/90-qemu.rules
90-qemu.rules には以下を記述します。
KERNEL=="sda", SYMLINK+="mmcblk0"
KERNEL=="sda?", SYMLINK+="mmcblk0p%n"
KERNEL=="sda2", SYMLINK+="root"
イメージのアンマウント
設定ファイルの編集が終わったらRaspbianイメージをアンマウントします。
$ sudo umount /mnt
$ sudo kpartx -d 2017-07-05-raspbian-jessie-lite.img
起動する
以下のコマンドを入力し、QEMU上でRaspbianが起動することを確認します。
もちろん初期ID・パスワードはRaspberry Pi実機にインストールする場合と同様です。
下記コマンドでは -redir
オプションでホストの10022番ポートからRaspbianのSSHに接続できるようにしています。
$ qemu-system-arm \
-kernel kernel-qemu-4.4.34-jessie \
-cpu arm1176 \
-M versatilepb \
-m 256 \
-no-reboot \
-serial stdio \
-append "root=/dev/sda2 panic=1" \
-hda 2017-07-05-raspbian-jessie-lite.img \
-redir tcp:10022::22
Raspbianイメージのパーティションサイズを拡張する
必須ではありませんが、このままではパーティションの空き容量が約500MBしかありません。
以下はRaspbianイメージのパーティション拡張手順です。
イメージのサイズを拡張する
以下のコマンドでイメージのサイズ変更を行います。
ここでは4GB分拡張して元と合わせ5.6GBにしていますが、拡張するサイズを変更するは +4G
の箇所を適宜変更してください。
またRaspbianが動作中の場合は終了させてください。
$ qemu-img resize 2017-07-05-raspbian-jessie-lite.img +4G
イメージサイズ拡張を反映させる
前述のコマンドでRaspbianを起動します。
ここからはRaspbian上での操作になります。
fdiskの操作
fdisk
を実行します。
$ sudo fdisk /dev/sda
p
コマンドでパーティションの一覧を表示します。
Command (m for help): p
Disk /dev/sda: 5.6 GiB, 6020597248 bytes, 11758979 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xa8790229
Device Boot Start End Sectors Size Id Type
/dev/sda1 8192 93596 85405 41.7M c W95 FAT32 (LBA)
/dev/sda2 94208 3370369 3276162 1.6G 83 Linux
Command (m for help):
デバイス一覧の /dev/sda2 の先頭セクタを記録しておきます。
(この例では 94208
)
d
コマンドでパーティション 2 を削除します。
Command (m for help): d
Partition number (1,2, default 2): 2
Partition 2 has been deleted.
Command (m for help):
n
コマンドでパーティションを作成します。
Command (m for help): n
パーティションタイプは p
、パーティション番号は 2
を入力します。
Partition type
p primary (1 primary, 0 extended, 3 free)
e extended (container for logical partitions)
Select (default p): p
Partition number (2-4, default 2): 2
先頭セクタ番号は先ほど記録した値を入力します。
(この例では 94208
)
First sector (2048-11758978, default 2048): 94208
最終セクタ番号はそのまま改行を入力します。
Last sector, +sectors or +size{K,M,G,T,P} (94208-11758978, default 11758978):
Created a new partition 2 of type 'Linux' and of size 5.6 GiB.
Command (m for help):
w
コマンドでパーティション情報を書き込みます。
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Re-reading the partition table failed.: Device or resource busy
The kernel still uses the old table. The new table will be used at the next reboot or after you run partprobe(8) or kpartx(8).
fdisk
が終了するので、Raspbianを再起動して新しいパーティション情報を反映させます。
$ sudo shutdown -r now
ファイルシステムのサイズ変更
再起動後、以下のコマンドでファイルシステムのサイズ変更を行います。
$ sudo resize2fs /dev/sda2
df -h
コマンドでパーティションサイズが拡張できていることを確認できれば完了です。
$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/root 5.5G 929M 4.3G 18% /
(以下省略)
備考とか今後の課題とか(余談)
エミュレートするハードウェア
ここでQEMUがエミュレートしているハードウェアは、実はRaspberry Piそのものではありません。
QEMUの -M
オプションで指定しているそれは versatilepb
となっています。
では“versatilepb”とは何か、とQEMUがサポートしているハードウェアの一覧を見ると“ARM Versatile/PB (ARM926EJ-S)”となっています。
“ARM Versatile Platform Baseboard for ARM926EJ-S”と云う開発用ボードのようなのですが、残念ながらこれ以上は分からず‥‥‥
さて、QEMUがサポートしているハードウェアの一覧には“raspi2”と云うのもあり、これはズバリRaspberry Pi 2のエミュレータですが、残念ながら当方の環境では動作しませんでした。
仮想マシンのメモリサイズ
Raspberry Pi 1/Zero実機のメモリは512MBありますが4、QEMU上では最大256MBまでです。
仮想マシンのメモリサイズはQEMUの -m
オプションで指定しますが、256より大きい値を指定するとエラーになります。
(この上限はQEMU versatilepbエミュレータのソースにハードコードされています)
パーティションの拡張
Raspberry Pi実機では raspi-config
で簡単に実行できますが、本記事では fdisk
などで回りくどいことをしています。なぜでしょう?
やってみると分かりますが、QEMU上で raspi-config
からパーティションの拡張を実行しようとすると“sda2 is not an SD card. Don't know how to expand”と怒られてしまいます。残念でした。
QEMUのオプション
QEMUの -redir
オプションは今後のバージョンで廃止予定とのことですが、代替表記とされる -net user,hostfwd=tcp::10022-:22
に変更すると接続できず。
今後の課題とさせてください‥‥‥
Raspbian Stretch
さて、本家Debianではすでに新たな安定版としてStretchがリリースされています。
Raspbianも追従するのは時間の問題と思われるので、本記事も早晩変更が必要になることでしょう。
参考にした記事
QEMU for windowsでRaspbian Jessieを動作させる
Raspberry pi(Raspbian Jessie)を OS X の QEMU で動かす
QEMUでRaspbianのsandbox環境を構築する
How to emulate a Raspberry Pi on your PC
メモ:SDカードイメージをマウントするならkpartxが楽