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

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版を使用します。
* 各ファイルはカレントディレクトリ上にあるものとします。

[^1]: 後述しますがRaspberry Piそのものではありません。

# 手順

## 必要ファイルをダウンロードする

### 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
```

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

### 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"
```

[^3]: もちろんエディタはvi以外でも構いません。
	
### イメージのアンマウント

設定ファイルの編集が終わったら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がサポートしているハードウェアの一覧](https://wiki.qemu.org/Documentation/Platforms/ARM)を見ると“ARM Versatile/PB (ARM926EJ-S)”となっています。
[“ARM Versatile Platform Baseboard for ARM926EJ-S”](https://goo.gl/images/XGZNjo)と云う開発用ボードのようなのですが、残念ながらこれ以上は分からず‥‥‥

さて、QEMUがサポートしているハードウェアの一覧には“raspi2”と云うのもあり、これはズバリRaspberry Pi 2のエミュレータですが、残念ながら当方の環境では動作しませんでした。

## 仮想マシンのメモリサイズ

Raspberry Pi 1/Zero実機のメモリは512MBありますが[^4]、QEMU上では最大256MBまでです。
仮想マシンのメモリサイズはQEMUの `-m` オプションで指定しますが、256より大きい値を指定するとエラーになります。
（この上限はQEMU versatilepbエミュレータのソースにハードコードされています）

[^4]: Model A/A+/初期ロットBは256MBです。

## パーティションの拡張

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を動作させる](http://qiita.com/u6k/items/af43ab9a4326586b9071)
[Raspberry pi（Raspbian Jessie）を OS X の QEMU で動かす](http://qiita.com/knyrc/items/1e652c349fa8939235f9)
[QEMUでRaspbianのsandbox環境を構築する](http://qiita.com/metalels/items/695fc9635b5ce4a452fc)
[How to emulate a Raspberry Pi on your PC](https://blogs.msdn.microsoft.com/iliast/2016/11/10/how-to-emulate-raspberry-pi/)
[メモ：SDカードイメージをマウントするならkpartxが楽](http://qiita.com/spicemanjp/items/1998a3f68cb369651584)