Skip to content

Latest commit

 

History

History
246 lines (178 loc) · 9.02 KB

File metadata and controls

246 lines (178 loc) · 9.02 KB

利用 Android 虛擬化框架(AVF)執行自訂 Linux 虛擬機

Android 虛擬化框架(AVF)可提供安全且私密的執行環境,用於執行程式碼。Android 提供實作參考資料,其中包含實作 AVF 所需的所有元件。儘管 AVF 主要用來提供比 Android 應用程式沙箱安全係數更高、甚至經過正式驗證的隔離保證,但我們也可以利用它來執行自訂 Linux 虛擬機。Android 15 QPR2 及以上版本的「Linux 開發環境」也驗證了這一點。

系統需求

  • 作業系統:Android 13 及以上
  • SoC:Google Tensor、聯發科天璣 9400、三星獵戶座 2500 及更新的 SoC

ℹ️注意:由於高通的限制,驍龍 8 Elite 目前僅支援受保護的虛擬機 ,如 Microdroid,不能執行未經 Google 或 OEM 簽署的自訂 Linux 虛擬機。但若有 root 權限,您也可以參考 polygraphene 的指南。您可以使用 adb shell 執行指令 /apex/com.android.virt/bin/vm run-microdroid 來確定您的 Android 裝置是否支援執行自訂 Linux 虛擬機,執行 Microdroid 時可能需要透過 adb -s localhost:8000 shell 連線虛擬機的 Shell。本文所有操作步驟適用於大部分的 Linux 發行版,其他作業系統使用對應的指令即可。

無頭虛擬機

由於從頭開始自行製作虛擬機映像檔的步驟較為繁瑣,所以本節僅討論使用 Google 官方專門為 AVF 製作的 Debian 映像檔的情況。

1. 下載映像檔

  1. 下載 Google 官方最新的 Debian 映像檔並解壓縮。
wget https://dl.google.com/android/ferrochrome/latest/aarch64/images.tar.gz
tar -zxvf images.tar.gz
  1. 將解壓縮得到的 root_part 4K 對齊。向上調整 root_part 的檔案大小,位元組數需要為 4096 的整倍數。可參考以下指令。
truncate -s 6442450944 root_part # 調整為 6 GiB

2. (可選)修改映像檔

可以利用 chrootroot_part 做一些簡單的修改,如變更語言、安裝升級軟體套件等。

  1. 掛載映像檔和系統特殊目錄。
sudo mkdir -p /mnt/debian_vm
sudo mount -o loop root_part /mnt/debian_vm
sudo mount --bind /dev /mnt/debian_vm/dev/
sudo mount --bind /proc /mnt/debian_vm/proc/
sudo mount --bind /sys /mnt/debian_vm/sys/
  1. 如果主機系統不是 aarch64 架構,需要使用 qemu-aarch64-static 來進行二進位翻譯。若主機系統是 Debian 系發行版,可參考以下指令。
sudo apt update
sudo apt install -y qemu-user-static binfmt-support
sudo cp /usr/bin/qemu-aarch64-static /mnt/debian_vm/usr/bin/
  1. 進入 chroot 環境並進行修改。
# 進入 chroot 環境
sudo chroot /mnt/debian_vm
# 設定 DNS
rm /etc/resolv.conf
echo "nameserver 8.8.8.8" | tee /etc/resolv.conf
# 升級軟體套件
apt update && apt upgrade -y
# 根據您的需要安裝新的軟體套件
apt install -y vim nano wget curl git sysbench locales
# 重新設定語系環境
dpkg-reconfigure locales
  1. 退出 chroot 環境並卸載相關掛載點。
exit
sudo umount /mnt/debian_vm/sys
sudo umount /mnt/debian_vm/proc
sudo umount /mnt/debian_vm/dev
sudo umount /mnt/debian_vm
sudo rmdir /mnt/debian_vm

3. 執行虛擬機

  1. 可以修改 vm_config.json 檔案來設定虛擬機。比如修改分配給虛擬機的記憶體大小:
"memory_mib" : 8192,
  1. images.tar.gz 解壓縮後的檔案傳送到您的 Android 裝置。
adb push vm_config.json /data/local/tmp/
adb push vmlinuz /data/local/tmp/
adb push initrd.img /data/local/tmp/
adb push kernel_extras_part /data/local/tmp/
adb push root_part /data/local/tmp/
  1. adb shell 內執行以下指令來執行虛擬機。
/apex/com.android.virt/bin/vm run /data/local/tmp/vm_config.json
  1. 在虛擬機的 Shell 內執行以下指令來關閉虛擬機。
shutdown 0

使用 u-boot 執行虛擬機

1. 下載 u-boot.bin

  1. 使用瀏覽器前往 aosp_u-boot-mainline | Branch Grid 網站,在 boot_crosvm_aarch64 欄選擇最新的專案。

  1. 在開啟的新分頁中選擇 u-boot.bin 檔案,瀏覽器會自動下載該檔案。

2. 下載 Linux 發行版的原始磁碟映像檔

使用的原始磁碟映像檔需要包含 Linux 系統完整的磁碟分割區。本文選擇的是 Debian 13 的 nocloud 雲端映像檔,您也可以前往 Debian Official Cloud Images 自行下載。

wget https://cloud.debian.org/images/cloud/trixie/latest/debian-13-nocloud-arm64.tar.xz
tar -xvf debian-13-nocloud-arm64.tar.xz
mv disk.raw debian-13-nocloud-arm64.raw

3. (可選)修改映像檔

  1. 擴充映像檔中的磁碟分割區。若主機系統是 Debian 系發行版,可參考以下指令。
sudo apt update
sudo apt install -y qemu-utils
qemu-img resize -f raw debian-13-nocloud-arm64.raw 8G
sudo losetup -fP debian-13-nocloud-arm64.raw
# 使用 KDE 分割區管理器或 GParted 等應用程式調整 /dev/loop0 的磁碟分割區(請根據實際情況確定迴圈裝置編號)
sudo losetup -d /dev/loop0
  1. 如果主機系統不是 aarch64 架構,可使用 qemu-system-aarch64 來啟動虛擬機。若主機系統是 Debian 系發行版,可參考以下指令。
sudo apt update
sudo apt install -y qemu-system
qemu-system-aarch64 \
  -machine virt \
  -cpu cortex-a72 \
  -smp 8 \
  -m 8192 \
  -drive if=none,file=debian-13-nocloud-arm64.raw,format=raw,id=hd0 \
  -device virtio-blk-pci,drive=hd0 \
  -netdev user,id=net0,hostfwd=tcp::2222-:22 \
  -device virtio-net-pci,netdev=net0 \
  -device virtio-gpu-pci \
  -device qemu-xhci \
  -device usb-kbd \
  -device usb-tablet \
  -display gtk,gl=on \
  -bios /usr/share/qemu-efi-aarch64/QEMU_EFI.fd
  1. 虛擬機啟動後,可在 QEMU 的 serial0 視圖登入 root 帳號並進行修改。
# 升級軟體套件
apt update && apt upgrade -y
# 根據您的需要安裝新的軟體套件
apt install -y vim nano wget curl git sysbench locales
# 重新設定語系環境
dpkg-reconfigure locales

4. 執行虛擬機

  1. 編寫 u_boot_vm_config.json 檔案來啟動虛擬機。可以使用或參照 u_boot_vm_config.json

  2. 將相關檔案傳送到您的 Android 裝置。

adb push debian-13-nocloud-arm64.raw /data/local/tmp/
adb push u-boot.bin /data/local/tmp/
adb push u_boot_vm_config.json /data/local/tmp/
  1. adb shell 內執行以下指令來執行虛擬機。
/apex/com.android.virt/bin/vm run /data/local/tmp/u_boot_vm_config.json
  1. 在虛擬機的 Shell 內執行以下指令來關閉虛擬機。
shutdown 0

FAQ

虛擬機如何連線到網路?

由於 Android 的限制,建立虛擬網路卡需要 root 權限。如果您的 Android 裝置能夠使用 root 權限,則可以使用 setup_network.sh 來為虛擬機建立一個虛擬網路卡 crosvm_tap

  1. 在您的 Android 裝置上執行 setup_network.sh
wget https://github.com/lfdevs/run-linux-on-android-guide/raw/refs/heads/main/scripts/avf/setup_network.sh
adb push setup_network.sh /data/local/tmp/
adb root
adb shell chmod +x /data/local/tmp/setup_network.sh
adb shell /data/local/tmp/setup_network.sh
adb unroot
  1. 在虛擬機內設定靜態 IP 位址。如果您使用的是 Google 官方的 Debian 映像檔或 Debian 官方的 nocloud 雲端映像檔,則可以新增一個設定檔 /etc/systemd/network/20-virtio-net.network,並寫入以下內容。
[Match]
Name=eth0

[Network]
Address=192.168.1.2/24
Gateway=192.168.1.1
DNS=8.8.8.8
DNS=1.1.1.1
  1. 重新載入 systemd-networkd 服務以套用新設定。
systemctl restart systemd-networkd

ℹ️注意:該方法參考了這篇 AVF 文件,如果您遇到了任何問題或有其他方案,歡迎在 Issues 中一起討論。

虛擬機如何使用桌面環境?

由於 Android 的限制,在 Android 和虛擬機之間進行通訊埠轉發或 vsock 通訊均需要 root 權限。但我沒有符合條件的裝置進行測試,如果您有任何想法或方案,歡迎在 Issues 中一起討論。

參考資料