註:如果你是想在Raspberry Pi跑QEMU/KVM虛擬機,請參考這篇: 樹莓派跑ARM架構的Linux虛擬機
Emulating Raspberry Pi OS (ARM) on Linux PC (x86).
這篇文章Ivon解說如何在x86架構的Linux電腦,以QEMU模擬執行ARM架構的Raspberry Pi OS。
雖說QEMU模擬異質ARM架構,執行速度約只有實體機器的五分之一,沒有KVM,也沒有圖形加速,但只要耐心夠,仍可以在虛擬機內測試一些樹莓派環境的軟體。
1. 環境#
- Host OS:Arch Linux
- Linux核心版本:6.4.3
- QEMU版本:8.0.2
- 要模擬的硬體:Raspberry Pi 3 Model B
- 要模擬的作業系統:Raspberry Pi OS Bullseye 64-bit
根據 官方文件,QEMU目前只支援模擬Raspberry Pi Zero、Raspberry Pi 1、Raspberry Pi 2、Raspberry Pi 3 Model A、Raspberry Pi 3 Model B。
我選擇最近代的Raspberry Pi 3 Model B,其RAM模擬上限1GB,請善用SWAP。
2. 安裝QEMU/KVM#
於電腦啟用虛擬化,並 安裝QEMU套件。Virt Manager可不裝。
接著安裝qemu-system-aarch64
模擬器
sudo pacman qemu-system-aarch64
最後準備一套VNC客戶端,我用 Remmina。
3. 準備Raspberry Pi OS核心與系統映像檔#
首先我們要準備Linux核心和dtb用於開機,這些可以從Raspberry Pi OS的映像檔抽取出來。
- 至
Raspberry Pi官網,下載最新版
Raspberry Pi OS (64-bit)
映像檔,選取Raspberry Pi OS with desktop
版本。
cd ~
mkdir raspberrypi && cd raspberrypi
wget https://downloads.raspberrypi.org/raspios_arm64/images/raspios_arm64-2023-05-03/2023-05-03-raspios-bullseye-arm64.img.xz
- 將其解壓縮
tar xvJf 2023-05-03-raspios-bullseye-arm64.img.xz
- 將映像檔掛載為loop device
mkdir mnt
sudo losetup -f --show -P 2023-05-03-raspios-bullseye-arm64
# 應會顯示dev/loop0
sudo mount /dev/loop0p1 /home/$USER/raspberrypi/mnt
- 抽出kernel和dtb
cp mnt/kernel* .
cp mnt/*.dtb .
- 取消掛載
sudo umount /home/$USER/raspberrypi/mnt
sudo losetup -d /dev/loop0
- QEMU要求虛擬SD卡容量需為2的次方,所以我們就先將Raspberry Pi OS映像檔放大吧,這樣的話等會系統可用空間就有16GB:
qemu-img resize 2023-05-03-raspios-bullseye-arm64.img 16G
4. 撰寫開機指令稿#
- 新增開機指令稿
vim launch.sh
- 填入以下內容:
#!/bin/bash
qemu-system-aarch64 \
-M raspi3b \ #模擬Raspberry Pi 3 Model B
-cpu cortex-a72 \ #模擬Coretx-A72 CPU
-smp cores=4,threads=1,sockets=1 \ #CPU核心分配
-append "rw earlyprintk loglevel=8 console=ttyAMA0,115200 dwc_otg.lpm_enable=0 root=/dev/mmcblk0p2 rootdelay=1" \
-dtb bcm2710-rpi-3-b-plus.dtb \
-sd 2023-05-03-raspios-bullseye-arm64.img \ #使用的映像檔
-kernel kernel8.img \
-m 1G \ #RAM固定
-serial stdio \
-usb -device usb-mouse -device usb-kbd -device usb-tablet \ #插入鍵盤滑鼠
-device usb-net,netdev=net0 \ #提供網路連線
-netdev user,id=net0,hostfwd=tcp::5555-:22 \ #轉發Host的5555通訊埠到虛擬機22通訊埠
- 開機
chmod +x launch.sh
./launch.sh
等大概2分鐘,終端機會輸出開機訊息,等出現
raspberrypi login:
提示的時候,先不要登入。我不知道為何預設帳密(pi
和raspberry
)一直顯示incorrect login
,所以我們得用圖形界面新增一個可以登入的帳號。開啟Remmina,協定選VNC,連線位址輸入
localhost:5900
連線,就會看到圖形界面。按照螢幕指示設定語言,新增使用者帳號。安裝完成後,將虛擬機關機,圖形界面沒反應的話請在終端機按CTRL+C關機。
日後要開機的話就是執行launch.sh
指令稿。圖形界面沒有必要每次都開,直接在終端機登入新增的使用者帳號即可。
5. 調整虛擬硬碟大小#
新增使用者後,Raspberry Pi OS可能不會吃滿所有可用空間。預設映像檔是4GB,就算放大到16GB,硬碟後方的空間仍沒有利用到。
為此我們要手動調整分區大小,這裡我使用圖形化的Gparted調整。
- 使用Linux核心的nbd功能,將映像檔掛載為網路區塊裝置
sudo modprobe nbd max_part=10
sudo qemu-nbd -c /dev/nbd0 2023-05-03-raspios-bullseye-arm64.img 16G
- 安裝gpated,並用gparted編輯硬碟分區
sudo pacman -S gparted
sudo gparted /dev/nbd0
對
/dev/nbd0p2
分區點選右鍵,拉動滑桿,填滿後端空間,再按下綠色打勾套用。關閉gpated,取消掛載網路區塊裝置
sudo qemu-nbd -d /dev/nbd0
- 開機後使用
df -h
指令檢查系統可用空間是否已變大。
6. 加大dphys-swapfile#
QEMU模擬的RAM太小了,系統很容易當機,此時利用SWAP增加可用RAM吧。
Raspberry Pi OS預設用dphys-swapfile管理SWAP檔案,不可自行新增swapfile。
- 編輯SWAP大小設定檔
sudo vi /etc/dphys-swapfile
- 找到這一行,將預設的100 (MB) SWAP改為4096。
CONF_SWAPSIZE=4096
- 重啟服務,或者重開機。
sudo service dphys-swapfile restart
- 用
sudo swapon -s
指令查看SWAP大小是否變化。
7. 設定SSH伺服器#
- 於虛擬機內部安裝OpenSSH,並啟動服務
sudo apt update
sudo apt install openssh-server
sudo systemctl enable --now ssh
- 這樣就可以從Linux Host以5555通訊埠連線至虛擬機。
ssh <使用者名稱>@localhost -p 5555
參考資料#
- farabimahmud/emulate-raspberry-pi3-in-qemu - Github
- Native emulation of Rpi2/3 using Qemu’s Raspi2/3 machine - Github
- QEMU仿真树莓派1和3B-保姆级教程 - 知乎
- native-emulation variant does not start, SD card size error #3 - Github
- How to resize a qcow2 disk image on Linux - LinuxConfig.org
- 樹莓派 Raspberry Pi 記憶體不足當機?調整 Swap 交換空間大小解決 - G. T. Wang