利用 Android 虚拟化框架(AVF)运行自定义 Linux 虚拟机
本文于 2025 年 8 月 26 日在 GitHub 发布:https://github.com/lfdevs/run-linux-on-android-guide/blob/main/docs/zh-HanS/avf-linux.md
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. 下载镜像
下载 Google 官方最新的 Debian 镜像并解压。
1 2
wget https://dl.google.com/android/ferrochrome/latest/aarch64/images.tar.gz tar -zxvf images.tar.gz
将解压得到的
root_part4K 对齐。向上调整root_part的文件大小,字节数需要为 4096 的整倍数。可参考以下命令。1
truncate -s 6442450944 root_part # 调整为 6 GiB
2. (可选)修改镜像
可以利用 chroot 对 root_part 做一些简单的修改,如更改语言、安装升级软件包等。
挂载镜像和系统特殊目录。
1 2 3 4 5
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/
如果主系统不是
aarch64架构,需要使用qemu-aarch64-static来进行二进制翻译。若主系统是 Debian 系发行版,可参考以下命令。1 2 3
sudo apt update sudo apt install -y qemu-user-static binfmt-support sudo cp /usr/bin/qemu-aarch64-static /mnt/debian_vm/usr/bin/
进入
chroot环境并进行修改。1 2 3 4 5 6 7 8 9 10 11
# 进入 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
退出
chroot环境并卸载相关挂载点。1 2 3 4 5 6
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. 运行虚拟机
可以修改
vm_config.json文件来配置虚拟机。比如修改分配给虚拟机的运行内存大小:1
"memory_mib" : 8192
将
images.tar.gz解压后的文件发送到您的 Android 设备。1 2 3 4 5
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/
在
adb shell内执行以下命令来运行虚拟机。1
/apex/com.android.virt/bin/vm run /data/local/tmp/vm_config.json
在虚拟机的 Shell 内执行以下命令来关闭虚拟机。
1
shutdown 0
使用 u-boot 运行虚拟机
1. 下载 u-boot.bin
使用浏览器前往 aosp_u-boot-mainline Branch Grid 网站,在
u-boot_crosvm_aarch64列选择最新的项目。在打开的新标签页中选择
u-boot.bin文件,浏览器会自动下载该文件。
2. 下载 Linux 发行版的原始磁盘映像
使用的原始磁盘映像需要包含 Linux 系统完整的分区。本文选择的是 Debian 13 的 nocloud 云镜像,您也可以前往 Debian Official Cloud Images 自行下载。
1
2
3
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. (可选)修改镜像
扩容镜像中的分区。若主系统是 Debian 系发行版,可参考以下命令。
1 2 3 4 5 6
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
如果主系统不是
aarch64架构,可使用qemu-system-aarch64来启动虚拟机。若主系统是 Debian 系发行版,可参考以下命令。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
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
虚拟机启动后,可在 QEMU 的
serial0视图登录 root 账户并进行修改。1 2 3 4 5 6
# 升级软件包 apt update && apt upgrade -y # 根据您的需要安装新的软件包 apt install -y vim nano wget curl git sysbench locales # 重新配置语言环境 dpkg-reconfigure locales
4. 运行虚拟机
编写
u_boot_vm_config.json文件来启动虚拟机。可以使用或参照 u_boot_vm_config.json。将相关文件发送到您的 Android 设备。
1 2 3
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/
在
adb shell内执行以下命令来运行虚拟机。1
/apex/com.android.virt/bin/vm run /data/local/tmp/u_boot_vm_config.json
在虚拟机的 Shell 内执行以下命令来关闭虚拟机。
1
shutdown 0
FAQ
虚拟机怎么连接网络?
由于 Android 的限制,创建虚拟网卡需要 root 权限。如果您的 Android 设备能够使用 root 权限,则可以使用 setup_network.sh 来为虚拟机创建一个虚拟网卡 crosvm_tap。
在您的 Android 设备上执行
setup_network.sh。1 2 3 4 5 6
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在虚拟机内配置静态 IP 地址。如果您使用的是 Google 官方的 Debian 镜像或 Debian 官方的
nocloud云镜像,则可以新建一个配置文件/etc/systemd/network/20-virtio-net.network,并写入以下内容。1 2 3 4 5 6 7 8
[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
重新加载
systemd-networkd服务以应用新配置。1
systemctl restart systemd-networkd
虚拟机怎么使用桌面环境?
由于 Android 的限制,在 Android 和虚拟机之间进行端口转发或 vsock 通信均需要 root 权限。但我没有符合条件的设备进行测试,如果您有任何想法或方案,欢迎在 Issues 中一起讨论。
