QEMU on M1 Mac

# 更新履歴
- QEMU on M1 Macの話を独立（2021/01/09）
- Windows10 ARMでvirtio-gpuを利用するように（2021/01/14更新）
- Homebrewでのインストールを追記（2021/05/24更新）
- 最新のQEMUのソースツリーに対応（hvf対応が組み込まれました）（2021/09/23更新）

# 動いたOS（とその一部感想）

- Windows 10 ARM (aarch64 + hvf)
    - 速い（特に起動と終了）。普段の動作もIntel Mac上のエミュで動かしてたWindowsとは桁違いに速い。
    - x86_64エミュレーションも動くのでかなりのソフトが動く（Office とか Git とか Pythonとか）
- Ubuntu Desktop 20.04LTS (aarch64 + hvf)
- CentOS 7 (aarch64 + hvf)
    - どちらも下手な Intel マシンに入れてるより速い。
- Raspberry Pi OS 64bit (aarch64 + tcg)
    - 実機（Raspberry Pi 3B）より速い…
- Raspberry Pi OS 32bit (arm + tcg)
    - 画面の描画が遅い。起動時にはフリーズしたかと思うぐらい黒い画面で待たされる。
- Ubuntu Server 20.04LTS (x86_64)
    - 少し遅いけどまあ使える速度。
- Lubuntu 20.04LTS (x86_64)
    - 画面の描画が遅いが，そこが我慢できればx86_64 のエミュレーションも十分使える感じ。
- Windows 10 x86_64 (x86_64)
    - めっちゃ遅い・・・
- Windows 98SE (i386)
    - 昔使ってたi386マシンで動かしてた時より速い。
- MacOS X 10.5 Leopard (PPC)
    - 遅い・・・

# ビルド＋インストールの話

全般的に niw さんの Gist が参考になる。ARM 版 Windows 10 を試すだけならこれで十分。Raspberry Pi OSを動かしたり，x86_64やi386のエミュレーションを動かしたい場合は，UTM.app がおすすめ。

- [ARM 版 Windows 10 を Hypervisor.framework のパッチをあてた QEMU を使って Apple Silicon な Mac で動かす（niwさんのGist）](https://gist.github.com/niw/e4313b9c14e968764a52375da41b4278)
- [utm.app（GitHub）](https://github.com/utmapp)

## 自分で構築する

- 自分でQEMUのソースにパッチを当てて動くのを作りたい場合はこちら。
- 最新のQEMUではhvfによるアクセラレーションに最初から対応しているのでパッチを当てる必要なし！（2021/09/23更新）

1. QEMUのソースを本家からとってくる。

    ```:shell
      $ git clone https://git.qemu.org/git/qemu.git
    ```

    すでに取ってきたソースを最新のものに追随する場合は以下を実行。

    ```:shell
      $ cd qemu
      $ git pull
      $ git submodules sync
      $ git submodules update --recursive
    ```

1. ビルドしてインストール（下の例では /opt/QEMU に入れるようにしている。このディレクトリを作成し，書き込み許可を与えておくこと）

    ```:shell
     $ cd qemu
     $ mkdir build
     $ cd build
     $ ../configure --prefix=/opt/QEMU --target-list=aarch64-softmmu,arm-softmmu,x86_64-softmmu,i386-softmmu,ppc-softmmu --enable-cocoa
     $ make -j
     （途中の出力略）
     $ make install
    ```

一応，これで作成したバージョンで以下の動作を確認：

- qemu-system-aarch64 ： Windows 10 ARM，CentOS 7，Ubuntu 20.04 LTS，Raspberry OS
- qemu-system-x86_64 ： Windows 10 (x86_64)

## Homebrewでインストール

- 最新のQEMUに[Akihiko Odaki](https://github.com/akihikodaki)さんがパッチを当ててOpenGL(!)まで動くようになってるQEMUがHomebrew経由で簡単にインストールできる。
- 色々大変ならこちらがおすすめ。
    - [3D accelerated qemu on MacOS](https://github.com/knazarov/homebrew-qemu-virgl)

1. HomebrewでリポジトリをTapする。

    ```:shell
      $ brew tap knazarov/qemu-virgl
    ```
1. インストールする。終わり。

    ```:shell
      $ brew install qemu-virgl
    ```

# いろんなOSを動かしてみる

## Ubuntu 20.04.1 LTS on QEMU
- QEMU用のEDK II OVMF EFIイメージを以下のサイトからダウンロードしておく。
    - [ARM 版 Windows 10 を Hypervisor.framework のパッチをあてた QEMU を使って Apple Silicon な Mac で動かす](https://gist.github.com/niw/e4313b9c14e968764a52375da41b4278)
- 以下の場所にあった 20201217版の focal-desktop-arm64.iso がインストールできてた。今の daily build がうまく動くか分からない。ISOイメージのバージョンが異なるとインストールの最後の段階でクラッシュする場合がある。
    - [Ubuntu 20.04.1 LTS (Focal Fossa) Daily Build](https://cdimage.ubuntu.com/focal/daily-live/)
- Desktop版ではなくServer版をインストールすれば問題なく動く模様。Ubuntu Serverのインストールについては以下の記事に詳しい。
    - [UTMを使ってM1 MacにUbuntu20.04をインストールして、その中でDockerを動かして、その中でUbuntu20.10を動かしてみる](https://qiita.com/akase244/items/726edbdd10085198f61f#_reference-a56a9288e3afe8ace047)

1. EFIイメージからpflashイメージを作成する。

    ```:shell
     $ dd if=/dev/zero of=pflash0.img bs=1m count=64
     $ dd if=/dev/zero of=pflash1.img bs=1m count=64
     $ dd if=QEMU_EFI.fd of=pflash0.img conv=notrunc
     $ dd if=QEMU_VARS.fd of=pflash1.img conv=notrunc
    ```
1. Ubuntuをインストールするイメージを作成する（サイズは10GB）。

    ```:shell
     $ qemu-img create -f qcow2 Ubuntu.qcow2 10G
    ```
1. 以下の手順でISOイメージから起動してインストール。
    - イメージへのパスなどは適宜変更する。
    - ブート時に TianoCore のロゴが出ているところで ESC を押して Device Manager →  OVMF Platform Configuration でブート時の解像度を変更できる（手元では 1440x900 と 1680x1050 は確認している）。
    - インストール後は Ubuntu の設定で変更するのでここで変更しなくても良い。

    ```:shell
     $ qemu-system-aarch64 \
         -monitor stdio \
         -M virt,highmem=off \
         -accel hvf \
         -display default,show-cursor=on \
         -cpu host \
         -smp 4 \
         -m 4096 \
         -drive file=./Ubuntu/pflash0.img,format=raw,if=pflash,readonly=on \
         -drive file=./Ubuntu/pflash1.img,format=raw,if=pflash \
         -device virtio-gpu-pci \
         -device nec-usb-xhci \
         -device usb-kbd \
         -device usb-tablet \
         -device intel-hda -device hda-duplex \
         -nic user,model=virtio \
         -hda ./Ubuntu/Ubuntu.qcow2 \
         -cdrom ./images/focal-desktop-arm64.iso \
         -boot order=d
    ```
1. インストール後に設定で Ubuntu の解像度を変更できる。

## Raspberry Pi OS（ARM64）

1. Raspberry Pi OSのダウンロード。以下のリンク先から `2020-08-20-raspios-buster-arm64.zip` をダウンロードする。
    - [Raspberry Pi OS ARM64](http://downloads.raspberrypi.org/raspios_arm64/images/)

1. カーネルイメージとdtbファイルを抽出。
    - OSイメージを展開すると `2020-08-20-raspios-buster-arm64.img` というイメージファイルが得られる。
    - Mac上で上記イメージファイルをダブルクリックするとマウントされるので，その中から `kernel8.img` と `bcm2710-rpi-3-b.dtb` を取り出す。
    - 取り出したあとはディスクイメージを取り出してアンマウントしておく。

1. OSのイメージファイルを以下のコマンドで qcow2 形式に変換する。

    ```:shell
      $ qemu-img convert -f raw -O qcow2 2020-08-20-raspios-buster-arm64.img 2020-08-20-raspios-buster-arm64.qcow2
    ```

1. イメージファイルのサイズを16GB（SDカードのサイズ）にリサイズする。

    ```:shell
      $ qemu-img resize 2020-08-20-raspios-buster-arm64.qcow2 16G
    ```

1. カーネルイメージ，DTBファイル，OSのイメージファイルを1箇所にコピーして，以下のようなスクリプトでQEMUを起動。

    ```:run_raspi3b.sh
      qemu-system-aarch64 \
        -monitor stdio \
        -M raspi3b \
        -accel tcg,split-wx=on \
        -display default,show-cursor=on \
        -m 1G \
        -smp 4 \
        -dtb ./RasPi3/bcm2710-rpi-3-b.dtb \
        -kernel ./RasPi3/kernel8.img \
        -no-reboot \
        -device usb-kbd \
        -device usb-tablet \
        -device usb-net,netdev=net0 \
        -netdev user,id=net0 \
        -drive file=./RasPi3/2020-08-20-raspios-buster-arm64.qcow2,format=qcow2,if=sd \
        -append "console=ttyAMA0 root=/dev/mmcblk0p2 rootfstype=ext4 fsck.repair=yes rootwait"
    ```
1. Raspberry Pi OSが起動したら，ターミナルで以下を実行し，ディスクの容量分だけ利用できるようにファイルシステムを拡張する。

    ```:shell
      $ sudo raspi-config  --expand-rootfs
    ```

## Windows 10 ARM on QEMU

QEMUのビルド以降は，基本的に @niw さんの Gist（以下）のまま。

- [ARM 版 Windows 10 を Hypervisor.framework のパッチをあてた QEMU を使って Apple Silicon な Mac で動かす](https://gist.github.com/niw/e4313b9c14e968764a52375da41b4278)

### ドライバ

1. Windows10を起動後，「管理者モード」（Administrator）でコマンドラインプロンプトを起動して以下を実行。その後，Windows10を再起動

    ```:shell
      bcdedit -set TESSIGNING ON
    ```
1. ドライバをインストール
    - ネットワークドライバ（virtio-net）
        - [https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/archive-virtio/virtio-win-0.1.190-1/virtio-win-0.1.190.iso](https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/archive-virtio/virtio-win-0.1.190-1/virtio-win-0.1.190.iso)
    - ビデオドライバ（virtio-gpu）
        - 以下をダウンロードして「InstallCerts and Driver.bat」を実行
        - [https://github.com/ubenmackin/ACVM/releases/download/v1.5/viogpudo.zip](https://github.com/ubenmackin/ACVM/releases/download/v1.5/viogpudo.zip)

1. 以下のスクリプトでWindows10を起動（ビデオを virtio-gpu に変更）

    ```:run_win10.sh
      qemu-system-aarch64 \
        -monitor stdio \
        -M virt,highmem=off \
        -accel hvf \
        -display default,show-cursor=on \
        -cpu host \
        -smp 4 \
        -m 4096 \
        -drive file=./Windows10/pflash0.img,format=raw,if=pflash,readonly=on \
        -drive file=./Windows10/pflash1.img,format=raw,if=pflash \
        -device virtio-gpu \
        -device nec-usb-xhci \
        -device usb-kbd \
        -device usb-tablet \
        -device intel-hda \
        -device hda-duplex \
        -device virtio-net,netdev=net0 \
        -netdev user,id=net0 \
        -drive file=./Windows10/Windows10_ARM64_21286.qcow2,format=qcow2,if=none,id=boot,cache=writethrough \
        -device nvme,drive=boot,serial=Windows10
    ```