Raspbian JessieをQEMUで動かす 2017/7/5版

  • 1
    いいね
  • 0
    コメント

2017/7/5版のRaspbian JessieをQEMUでエミュレート動作させた際の手順です。
もはや何番煎じだか分かりませんが、メモとして。

前提

  • エミュレートする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 には以下を記述します。

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”と云う開発用ボードのようなのですが、残念ながらこれ以上は分からず‥‥‥
RaspbianをQEMUで動作させる際に設定変更が必要になるのも、おそらくRaspberry PiとARM Versatile Platform Baseboardとの差異によるものと思われます。

さて、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が楽


  1. 後述しますがRaspberry Piそのものではありません。 

  2. 公式サイトからwgetでダウンロードする場合は $ wget -O 2017-07-05-raspbian-jessie-lite.zip https://downloads.raspberrypi.org/raspbian_lite_latest 

  3. もちろんエディタはvi以外でも構いません。 

  4. Model A/A+/初期ロットBは256MBです。