Raspberry Pi 3をQEMUで動かしてみた on Debian 12

# はじめに
みんな大好きRaspberry Pi 3をQEMUで動かして (エミュレートして) みた時のメモです。

# 参考にしたサイト
- https://qiita.com/yaju/items/edf548efd18f0eaab94a
- https://farabimahmud.github.io/emulate-raspberry-pi3-in-qemu/

# 構成図
```
+-----------------------------+
| +-------------------------+ |
| | +---------------------+ | |
| | | +-----------------+ | | |
| | | | Raspberry Pi OS | | | |
| | | +-----------------+ | | |
| | | Rapsberry Pi 3      | | |
| | +---------------------+ | |
| | QEMU                    | |
| +-------------------------+ |
| Debian                      |
+-----------------------------+
```

# 各ソフトウェアのバージョン
## Debian
```
$ cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
NAME="Debian GNU/Linux"
VERSION_ID="12"
VERSION="12 (bookworm)"
VERSION_CODENAME=bookworm
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
```
## QEMU
```
$ qemu-system-aarch64 --version
QEMU emulator version 7.2.5 (Debian 1:7.2+dfsg-7+deb12u2)
Copyright (c) 2003-2022 Fabrice Bellard and the QEMU Project developers
```
```
$ qemu-system-aarch64 -M help | grep raspi
raspi0               Raspberry Pi Zero (revision 1.2)
raspi1ap             Raspberry Pi A+ (revision 1.1)
raspi2b              Raspberry Pi 2B (revision 1.1)
raspi3ap             Raspberry Pi 3A+ (revision 1.0)
raspi3b              Raspberry Pi 3B (revision 1.2)
```
- ちなみに、別マシンにて8.1.2をビルドしましたが、QEMUでは3B+や4Bのサポートはまだのようです。
  ```
  $ qemu-system-aarch64 --version 
  QEMU emulator version 8.1.2 (v8.1.2)
  Copyright (c) 2003-2023 Fabrice Bellard and the QEMU Project developers
  $ qemu-system-aarch64 -M help | grep raspi
  raspi0               Raspberry Pi Zero (revision 1.2)
  raspi1ap             Raspberry Pi A+ (revision 1.1)
  raspi2b              Raspberry Pi 2B (revision 1.1)
  raspi3ap             Raspberry Pi 3A+ (revision 1.0)
  raspi3b              Raspberry Pi 3B (revision 1.2)
  ```
## Rapsberry Pi OS
- 2020-08-20-raspios-buster-arm64
  - https://downloads.raspberrypi.org/raspios_arm64/images/raspios_arm64-2020-08-24/
  - 本当はもっと新しいバージョンを使いたかったのですが、新しいバージョンを使うと、CLIの画面が表示されませんでした。そのため、以下の記事にある2020-08-20-raspios-buster-arm64を使いました。
    - https://qiita.com/yaju/items/edf548efd18f0eaab94a

# 手順
1. Raspberry Pi用のファイルを保存するディレクトリ (e.g., /home/user/raspi3) を作成します。
   ```sh
   mkdir -p /home/user/raspi3
   ```
1. Raspberry Pi OSのイメージをダウンロードします。
   ```sh
   cd /home/user/raspi3
   ```
   ```sh
   wget https://downloads.raspberrypi.org/raspios_arm64/images/raspios_arm64-2020-08-24/2020-08-20-raspios-buster-arm64.zip
   ```
1. ダウンロードしたファイルを解凍します。
   ```sh
   unzip 2020-08-20-raspios-buster-arm64.zip
   ```
1. イメージファイル2020-08-20-raspios-buster-arm64.imgをループバックマウントします。
   ```sh
   sudo losetup --show -fP 2020-08-20-raspios-buster-arm64.img
   ```
   - ループバックマウントが成功すると、以下のようにデバイス名が表示されます。デバイス名は環境によって異なります。
     ```
     /dev/loop6
     ```
1. 上記デバイス上のパーティション/dev/loop6p1を任意のディレクトリ (e.g., /mnt/tmp) にマウントします。
   ```sh
   sudo mkdir /mnt/tmp
   ```
   ```sh
   sudo mount /dev/loop6p1 /mnt/tmp/
   ```
1. 以下の2つのファイルを/hoem/user/raspi3にコピーします。
   ```sh
   cp /mnt/tmp/bcm2710-rpi-3-b.dtb /home/user/raspi3
   ```
   ```sh
   cp /mnt/tmp/kernel8.img /home/user/raspi3
   ```
1. 該当のデバイスをアンマウントします。
   ```sh
   sudo umount /mnt/tmp
   ```
   ```sh
   sudo losetup -d /dev/loop6
   ```
1. 仮想マシンを起動するためのシェルスクリプトrun.shを作成します。
   ```sh
   cd /home/user/raspi3
   ```
   ```sh
   touch run.sh
   ```
   ```sh
   chmod +x run.sh
   ```
   ```sh
   vim run.sh
   ```
   ```
   qemu-system-aarch64 \
   -m 1024 \
   -M raspi3b \
   -kernel kernel8.img \
   -dtb bcm2710-rpi-3-b.dtb \
   -drive format=raw,file=2020-08-20-raspios-buster-arm64.img \
   -append "console=ttyAMA0 root=/dev/mmcblk0p2 rw rootwait rootfstype=ext4 dwc_otg.fiq_fsm_enable=0 bcm2708_fb.fbwidth=1280 bcm2708_fb.fbheight=720" \
   -no-reboot \
   -device usb-kbd \
   -device usb-mouse \
   -device usb-net,netdev=net0 \
   -netdev user,id=net0,hostfwd=tcp::2222-:22 \
   -nographic
   ```
1. run.shを実行してください。
   ```sh
   ./run.sh
   ```
1. Enjoy!
   ```
   $ ./run.sh 
   [    0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd034]
   [    0.000000] Linux version 5.4.51-v8+ (dom@buildbot) (gcc version 5.4.0 20160609 (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.9)) #1333 SMP PREEMPT Mon Aug 10 16:58:35 BST 2020
   [    0.000000] Machine model: Raspberry Pi 3 Model B
   
   (snip)
   
   [  OK  ] Started OpenBSD Secure Shell server.
   
   Debian GNU/Linux 10 raspberrypi ttyAMA0
   
   raspberrypi login
   ```

# さいごに
少し古いバージョンではありますが、Raspberry Pi OSをQEMUで動かすことに成功しました。Raspberry Piの入手が難しい場合には、QEMUを使ってみるのはいかがでしょうか？