硬件环境:X86 PC
软件环境:crosvm
目标:PC上搭建运行crosvm (x86和arm64版本)的环境,然后使用crosvm启动虚拟机
1. crosvm环境
- 本章节介绍了X86版本和ARM64版本crosVM的模拟环境.ARM64的稍复杂一点,需要先模拟一个ARM64 Host
Server,再在其上运行crosVM.
1.1 X86 crosvm
- 启动X86 crosvm依赖三个部分:crosvm二进制,rootfs,Image.
1.1.1 crosvm编译
#下载代码
git clone https://chromium.googlesource.com/chromiumos/platform/crosvm
#安装编译依赖
sudo apt-get install build-essential libcap-dev libfdt-dev wayland-scanner++ pkg-config libwayland-dev wayland-protocols
#初始化crosVM第三方依赖
git submodule update --init
#安装rust环境
curl https://sh.rustup.rs -sSf | sh
source $HOME/.cargo/env
#编译crosVM二进制
cargo build
#或者cargo build --features=gdb
/* 二进制位于./target/debug/crosvm */
1.1.2 linux编译
- 编译chrome kernel
#下载代码(其实是linux 5.10.80)
git clone --depth 1 -b chromeos-5.10 https://chromium.googlesource.com/chromiumos/third_party/kernel
#编译bzImage/vmlinux
make chromiumos-container-vm-x86_64_defconfig
make -j4 bzImage
/* bzImage和./vmlinux均可用于crosvm启动 */
- 标准linux
#也可以编译标准linux(linux为5.13)
git clone https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
#编译bzImage/vmlinux
mv cros-defconfig .config
make olddefconfig
make -j8 bzImage
- 编译rootfs
参考:rootfs制作
- 创建VM
#基础启动
./crosvm run --disable-sandbox --rwroot ./rootfs.img ./Image
#带控制sock启动
/* 一个shell启动VM */
./crosvm run -s /run/crosvm.sock --disable-sandbox --rwroot ../../image/simple-rootfs.img vmliux
/* 另一shell可关闭crosvm进程 */
./crosvm stop /run/crosvm.sock
- 问题解决
#Rootfs.img启动后报错”can't open /dev/tty2”,执行:
ln -sf /dev/null /dev/tty2;
ln -sf /dev/null /dev/tty3;
ln -sf /dev/null /dev/tty4
1.2 ARM版环境
- 启动ARM crosvm依赖3个部分:ARM64 Compile Server, ARM64 Host Linux + rootfs,crosvm + rootfs + Image
1.2.1 crosVM交叉编译(失败)
- 我需要编译一个arm64版本的crosVM,首先想到rust交叉编译
/* 1. 首先查看rust支持哪些OS和CPU架构 */
rustc --print target-list | pr -tw100 --columns 3
/* 2. 查看编译出来的程序是否依赖动态库 */
ldd ./target/debug/crosvm
/* 3. 查看rust安装了哪些工具链 */
rustup show
rustup target add aarch64-unknown-linux-gnu
vi .cargo/config #将target修改为,增加linker
[target.aarch64-unknown-linux-gnu]
linker = "aarch64-linux-gnu-gcc"
/* 4. 编译为指定架构 */
cargo build --target=aarch64-unknown-linux-gnu
结果:crosVM编译失败,minijail缺失pkg-config arm包.我只能交叉编译crosVM源码,无法编译它的依赖包.
1.2.2 ARM64编译Server
- 使用交叉编译crosvm行不通,那我只有搭建一个arm64 Server,在Server上编译crosVM.
1.2.2.1 ARM Server创建
- 创建Arm64 Ubuntu20.04 Server
/* 0. 上ubuntu官网下载ubuntu-20.04-server-arm64.iso镜像 */
https://cdimage.ubuntu.com/ubuntu-legacy-server/releases/20.04/release/
/* 1. 制作空的disk image,用于镜像安装和后续启动 */
qemu-img create ubuntu20.04-arm64.img 100G
/* 2. 下载QEMU-UEFI. 经测试该UEFI无法支持Ubuntu21/22等更高版本 */
wget https://releases.linaro.org/components/kernel/uefi-linaro/latest/release/qemu64/QEMU_EFI.fd
或者wget http://releases.linaro.org/components/kernel/uefi-linaro/16.02/release/qemu64/QEMU_EFI.fd
/* 3. qemu安装arm64虚拟机 */
qemu-system-aarch64 -m 4096 -cpu cortex-a57 -smp 4 -M virt -bios QEMU_EFI.fd -nographic -drive if=none,file=ubuntu-20.04-server-arm64.iso,id=cdrom,media=cdrom -device virtio-scsi-device -device scsi-cd,drive=cdrom -drive if=none,file=ubuntu20.04-arm64.img,id=hd0 -device virtio-blk-device,drive=hd0
/* 4. ctrl + A,之后X可退出qemu */
/* 4. ubuntu已经安装到img了,使用img重新系统 */
qemu-system-aarch64 -m 4096 -cpu cortex-a57 -smp 4 -M virt -bios QEMU_EFI.fd -nographic -drive if=none,file=ubuntu20.04-arm64.img,id=hd0 -device virtio-blk-device,drive=hd0
文件共享
vmvare
- 虚拟机中打开设置,在选项中点击共享文件夹,启用该功能并配置文件夹路径
- 安装VMvare tools,否则可能会出现找不到hgfs文件夹/hgfs下无共享文件夹
tar -zxvf '/media/hadoop/VMware Tools/VMwareTools-10.3.10-12406962.tar.gz'
#若出现read only问题,将压缩包拷贝到Download
tar VMwareTools-10.3.10-12406962.tar.gz
vmware-install.pl
Arm server
- Arm Server中的文件想拷贝出去,或外面文件想拷贝进来,有以下方法:
scp拷贝
scp user@ip:/home/user/disk2/arm64-server-ubuntu16.04/libs/wayland-scanner++_0.2.5-2build1_arm64.deb ./
1.2.3 CrosVM编译
- ARM Server中编译crosVM和x86一样,参考上面章节.
- 问题说明:
Arm ubuntu18.04上官方没有arm64 wayland-scanner++软件包.只有ubuntu20.04才有,所以Arm版crosVM只能在Ubuntu20.04以上编译.
1.2.4 ARM Host Linux
- 目标:首先我们需要搭建一个最新版本ARM linux系统(包含pKVM),做为调试crosVM和pKVM的Host环境.
- 编译最新版Linux Kernel
/* 1. 下载最新linux稳定版代码,目前最新5.16-rc2,2021.11.22 */
/* pKVM太新,无法直接使用Ubuntu21.1(linux5.11)搭建环境,需要全部自己手动制作最新的系统 */
git clone http://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git
/* 2. 指定交叉编译工具链和defconfig,arm64不像arm有很多config,arm64只有一个defconfig */
export $PATH=PATH:/home/tools/arm-linux/gcc-linaro-5.5.0-2017.10-x86_64_aarch64-linux-gnu/bin
make ARCH=arm64 defconfig
make -j6 ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
/* Image和./vmlinux均可用于crosvm启动 */
1.2.5 rootfs
1.2.5.1 Busybox简易rootfs
- 参考上文
1.2.5.2 Ubuntu rootfs
/* 安装一个ubuntu20.04的ARM rootfs */
dd if=/dev/zero of=ubuntu20.04_rootfs_arm64.img bs=1M count=1024
mkfs.ext4 ubuntu20.04_rootfs_arm64.img
mkdir rootfs
mount ubuntu20.04_rootfs_arm64.img rootfs/
#若制作x86
debootstrap --arch amd64 focal rootfs/ http://archive.ubuntu.com/ubuntu
#若制作Arm64
debootstrap --arch=arm64 --variant=minbase focal rootfs/ http://mirrors.ustc.edu.cn/ubuntu-ports/
chroot rootfs
echo "tmpfs /tmp tmpfs defaults 0 0" >> /etc/fstab
echo "tmpfs /var/log tmpfs defaults 0 0" >> /etc/fstab
echo "tmpfs /root tmpfs defaults 0 0" >> /etc/fstab
echo "sysfs /sys sysfs defaults 0 0" >> /etc/fstab
echo "proc /proc proc defaults 0 0" >> /etc/fstab
/* 我们此时还可以安装你想要的软件包 */
apt install gdb
exit
umount rootfs
/* crosvm启动ubuntu rootfs */
./crosvm run --disable-sandbox --rwroot ../ubuntu/ubuntu20.04_rootfs.img --rwdisk ../ubuntu/disk-4g.img -p 'init=/bin/bash' ./vmlinux
/* 挂载disk,/dev/vdb就是disk.img */
mount -t ext4 /dev/vdb disk/
- Ubuntu rootfs可以用于crosvm启动,还未能成功用于qemu-system-aarch64.
1.2.6 嵌套虚拟化启动crosvm
/* 1. 启动最新版arm host linux, */
/* 1.1 rootfs-all.img为打包了crosvm+rootfs+Image的镜像 */
/* 1.2 命令行kvm-arm.mode=protected用于使能pKVM */
/* 1.3 Ctrl+A后按X可退出qemu */
qemu-system-aarch64 -cpu cortex-a72 -machine virt,virtualization=true,gic-version=3 -nographic -smp 2 -m 1024M -kernel Image -append "root=/dev/ram rdinit=/linuxrc console=ttyAMA0 kvm-arm.mode=protected " -initrd ./rootfs-all.img -device virtio-scsi-device
/* 2. 在arm host linux中使用crosvm创建一个vm */
/* 2.1 说明: 先后台启动syslogd(解决crosvm运行依赖);crosvm-nopci规避了pci-bridge设备注册问题;rootfs-ext4-5m.img需要做成ext4格式,参考2.1.2.3 */
syslogd &
./crosvm-nopci run --protected-vm --disable-sandbox --rwroot ./rootfs-ext4-5m.img ./Image
1.2.7 问题解决
- crosvm无法配置pci桥设备
register_pci_device linux.rs:2715 //看来系统不支持pci bridge设备,该行注释
1.3 DEBUG
1.3.1 GDB调试VM Kernel
/* 在一个root shell启动VM,其中100为port号,可以自行修改 */
./crosvm run --gdb 100 --disable-sandbox --rwroot rootfs-5m.img vmlinux
/* 在另一个shell */
gdb vmlinux
(gdb) target remote:100
(gdb) hbreak start_kernel
(gdb) c
1.3.2 GDB调试CROSVM
/* gdb运行带--features=gdb的crosvm,可对crosvm二进制进行单步调试 */
rust-gdb ./crosvm-netr-gdb
(gdb)set args run --disable-sandbox --rwroot rootfs-5m.img vmlinux
(gdb)b run_vm
(gdb)r
(gdb)n
/* imx8板子 */
./gdb ./crosvm-nopci
(gdb)set args run --disable-sandbox --rwroot ./rootfs-ext4-5m.img ./Image
--protected-vm