Raspbian Stretch を Windows 上の QEMU で動かす

###きっかけ
[Pearl の EM-1](https://pearldrum.com/products/kits/electronics/malletstation/) という MIDI コントローラーが欲しいのですが、音源が内蔵されていないのに MIDI で音源をつなごうとすると1万円くらいする専用の「MIDI Expander」(という USB OTG -> MIDI 変換器) がないと接続できないことが判明。

ドイツ MidiTech 社の Pianobox mini というUSB MIDIコントローラー直接続OK!なGM音源もあるけど、よくよく調べると中国 MidiPlus 社のOEMくさい。。。でも世の中にUSBホストになれるUSB-MIDIインターフェースは他になさそう。。。
で、よく周りを見回したら大掃除の時に出てきた**初代** Raspberry Pi があったので、USBコントローラー->MIDI自作変換器に仕立てていこうと思います。

というわけで開発用のエミュレータの整備。
ネットの情報そのままではうまくいかなかったので、自分用にメモを残します。

#### 必要なもの
- Windows 10 の PC
- 公式の Raspbian イメージ (https://www.raspberrypi.org/downloads/raspbian/)
- QEMU on Windows (https://www.qemu.org/download/#windows)
- QEMU 向けにカスタマイズされた Linux カーネル (https://github.com/dhruvvyas90/qemu-rpi-kernel)
- QEMU で使うデバイスツリーファイル (https://github.com/dhruvvyas90/qemu-rpi-kernel)


###1. QEMU のインストール
[QEMU公式のリンク](https://www.qemu.org/download/#windows) からダウンロードしてきた qemu-w64-setup-20181211.exe を実行。特別なことはなく、Next ボタンを押していけばOK。
VMware Player とか VirtualBox と違い、QEMUの起動自体がコマンドラインなので PATH 環境変数の追加も推奨。

###2. Raspbian イメージの準備
[Raspberry Pi公式のページ](https://www.raspberrypi.org/downloads/raspbian/)からZIPファイルをダウンロード。
その後、ZIPの中の *.img ファイルを取り出す。この *.img ファイルは使う時に QEMU 用にコンバートする。(後述)

###3. QEMU 用のファイルの準備
まずはカーネルとデバイスツリーファイル(*.dtb)をGitHubの [dhruvvyas90/qemu-rpi-kernel](https://github.com/dhruvvyas90/qemu-rpi-kernel) から入手する。
カスタムカーネルのバージョンは、Raspbian の「Kernel version:」と合わせないと動かなかったので注意。

```Console:
C:\qemu-vms\raspbian> dir /B
2018-11-13-raspbian-stretch-lite.img
kernel-qemu-4.14.50-stretch
versatile-pb.dtb
```

次にRaspbianのイメージをQEMU用の形式に変換する。

```Console:
C:\qemu-vms\raspbian\> qemu-img convert -f raw -O qcow2 2018-11-13-raspbian-stretch-lite.img 2018-11-13-raspbian-stretch-lite.qcow
```

ディスクイメージの拡張はこれ。(この例では、QCOWファイルに4GB追加)

```Console:
C:\qemu-vms\raspbian\> qemu-img resize 2018-11-13-raspbian-stretch-lite.qcow +4G
Image resized.
```


###4. 起動
まだNIC(=有線LAN)が使えない状態ですが、とりあえず起動するコマンドはこれ。
QEMUの画面が出て、左上に Raspberry Pi のアイコンのある起動画面が表示されたら起動成功。

```Console:
C:\qemu-vms\raspbian> qemu-system-armw -cpu arm1176 -m 256 -M versatilepb -dtb versatile-pb.dtb -kernel kernel-qemu-4.14.50-stretch -append "root=/dev/sda2 panic=1 rootfstype=ext4 rw" -hda 2018-11-13-raspbian-stretch-lite.qcow -no-reboot -serial tcp:localhost:23,server,nowait -net nic -net user,hostfwd=tcp::22-:22 -usb -device usb-host,hostbus=0,hostport=5,hostport=1
```
<details><summary>オプションの説明</summary><div>
`-cpu`, `-m`, `-M`:
arm1176を搭載したARM社のリファレンスキット「Versatile Platform Baseboard」としてQEMUを起動。メモリを512MBにしたかったが、エラーでQEMU自体が起動しないので256MBのままにする。
machine type を表す `-M` で Raspberry Pi を指定しない理由は後述。
`-dtb`, `-kernel`:
デバイスツリーファイルとカーネルの指定。QEMU起動時にイメージ内の各ファイルをコマンドラインで指定したものに置き換えるらしい。(詳細不明)
`-serial`:
RS-232Cと思われるシリアル通信ポートの有効化。`tcp:localhost:23,server,nowait`を追加すると Windows 10 側から`telnet`コマンドでログインできる。
`-net`:
有線LANの有効化。`-net user`で仮想スイッチ接続(≒VMwareのVMNatとか、Hyper-Vの仮想スイッチ)経由の接続になる。
QEMUの標準仮想スイッチでホスト側からの接続が遮断されているので、開けるポートだけ`hostfwd`オプションで指定する。
`-usb`, '-device':
USBの有効化。(まだ接続確認ができていない...)
</div></details>

###5. 初期設定
VM起動後は、QEMUの画面から初回ログインを行う。(ユーザー名:pi, パスワード:raspberry)
初期状態だと RS-232C も SSH も有効になっていないので、`sudo raspi-config`コマンドで有効化する。
下のページが参考になります。
> Raspberry pi セットアップからシリアル通信まで - Qiita
> (https://qiita.com/saitotak/items/e2006423a40bb89cb653)

再起動は Raspbian 内で`shutdown -h now`で停止し、再度 Windows から`qemu-system-armw`コマンドでVM起動。
多分、-no-reboot があるので`shutdown -r now`が効かない。(シャットダウンはするが、その後起動しない)

###6. 接続確認
Windows 10 Fall Creators Update あたりから`telnet`も`ssh`もOSの標準機能として使える。「コマンドプロンプト」から`telnet`または`ssh`でOK。
注意点として、QEMUの機能でホスト側のポートにマッピングしているので、IPアドレスはホストOS側になることに注意。後、Windows標準の`telnet`コマンドはUTF-8非対応だったり、キーボードの入力が二重になったり(`unset localecho`で切ってもダメ)、挙動が変なので素直にTeraTermの導入をお勧めします。(XMODEMでバイナリも送信できるし)

```Console:(ssh接続)
C:\> ssh pi@localhost
pi@localhost's password:
Linux raspberrypi 4.14.50+ #1 Fri Sep 21 11:29:13 CDT 2018 armv6l
~~~ 長いので省略 ~~~

pi@raspberrypi:~ $
```
```Console:(シリアル接続)
C:\> telnet -t vt100 localhost 10001

Raspbian GNU/Linux 9 raspberrypi ttyAMA0
raspberrypi login: pi

Password: raspberry

~~~ 長いので省略 ~~~

pi@raspberrypi:~$
pi@raspberrypi:~$ <-なんでか Enter キーも2回入力されてしまう

```


###7. その後の展開
停止は Raspbian 内で`shutdown -h now`でシャットダウンできる。
これに開発環境側からビルドとQEMUの起動、各種デバッグメッセージの取得、ホスト側USBデバイスの接続ができたら大体やりたいことができるかなという印象。
物理的なMIDI端子の増設とテストは、そもそも電子工作の世界なのでVM上ではさすがにテストできない。


###補足:
この記事の説明は **初代** Raspberry Pi 用です。(構成が似ている Pi Zero, Pi Zero も、今回のでいけるはず)
64bit化された Raspberry Pi 2/3 はQEMUのコマンドが異なる上、QEMUの`-M`オプションに raspi2 が用意されている模様。

> **Supported in qemu-system-arm**
> raspi2      Raspberry Pi 2
> **Supported in qemu-system-aarch64**
> raspi2      Raspberry Pi 2
> ...
> (https://wiki.qemu.org/Documentation/Platforms/ARM)

```Console:
# 32bitモードの場合
C:\qemu-vms\raspbian\> qemu-system-armw -m 1024 -M raspi2 ...(省略)

# 64bitモードの場合
C:\qemu-vms\raspbian\> qemu-system-aarch64w -m 1024 -M raspi2 ...(省略)
```

但し、`-M raspi2`をつけるとQEMUも仮想CPU 4個で動作し始める為、PC側が物理6コア以上ないと激重になる。(というか、なった。)


###ToDo
- NIC の有効化
- シリアルポートの有効化
- SSH の有効化

####履歴
- シリアルポートとNICの有効化を追加 (2019/1/7)
- 初版作成 (2019/1/6)