qemu-kvm Hypervisor

#硬件环境:x86 PC
#软件环境:ubuntu20.04;qemu
#目标:使用qemu创建x86虚拟机和arm64虚拟机

1. qemu

#使用开源包
sudo apt install qemu qemu-system
#也可以自己进行编译,能gdb调试

2. rootfs

    rootfs有多种方法制作,如busybox,buildroot,Ubuntu等,busybox/buildroot尺寸最小但很难安装图形栈,Ubuntu rootfs尺寸较大但安装图形栈方便。
下面将介绍这两种玩法

2.1 Busybox rootfs

#下载地址:https://busybox.net/downloads/ 
wget https://busybox.net/downloads/busybox-1.35.0.tar.bz2
tar -jxvf busybox-1.35.0.tar.bz2
cd busybox-1.33.0
2.1.1 ARM rootfs
#ARM版本设施
    #设置CPU架构
    export ARCH=arm64
    #设置交叉编译工具链前缀
    export CROSS_COMPILE=~/share/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
2.1.2 X86 rootfs
#x86版本
#生成默认.config
make  defconfig
#设置busybox选项
make menuconfig
#修改选项
    Settings  ---> 
        ...
        # 静态编译busybox
        --- Build Options  
        [*] Build static binary (no shared libs) 
        ...

#编译
make -j 8
make install

#make rootfs
dd if=/dev/zero of=rootfs-1m.img bs=1M count=10
mkfs.ext4 rootfs-1m.img

mkdir fs
sudo mount -t ext4 -o loop rootfs-1m.img ./fs
sudo make install CONFIG_PREFIX=./fs
cd fs/
sudo mkdir proc dev etc home mnt
sudo cp -r ../examples/bootfloppy/etc/* etc/
cd ../
sudo chmod -R 777 fs/
sudo umount fs

2.2 Ubuntu rootfs

    前文rootfs用Busybox或者BuildRoot等工具,在做GPU虚拟化过程中,由于图形软件栈依赖太多,很难把全部的包都包含到小文件系统中。
这篇文章介绍如何基于Ubuntu官方提供的base文件系统加入最小图形软件栈。
  方法1:直接从http://cdimage.ubuntu.com/ubuntu-base/releases/里面下载
  方法2:或者通过qemu-debootstrap下载,如果host和guest是同一种arch,效果和debootstrap一样
  • debootstrap–已验证可用
/* 安装依赖 */
sudo apt-get install debian-archive-keyring bison flex bc build-essential libncurses* libssl-dev gcc-aarch64-linux-gnu
sudo apt-get install  qemu-user-static binfmt-support debootstrap

/* 制作一个ubuntu20.04 rootfs */
#安装图形用8G
dd if=/dev/zero of=ubuntu20.04_rootfs_arm64.img bs=1M count=1024
mkfs.ext4 ubuntu20.04_rootfs_arm64.img
mkdir rootfs
sudo mount ubuntu20.04_rootfs_arm64.img rootfs/
#arm64的ubuntu rootfs
    sudo debootstrap --arch arm64 focal rootfs/ http://mirrors.ustc.edu.cn/ubuntu-ports/
    或debian:sudo debootstrap --arch arm64 --foreign buster  rootfs/ http://mirrors.ustc.edu.cn/debian/
    /* 用于x86模拟arm64 */
    sudo cp /usr/bin/qemu-aarch64-static ./rootfs/usr/bin/
    #debian才有的 sudo chroot rootfs/ debootstrap/debootstrap --second-stage
sudo chroot rootfs
#配置密码
passwd root
useradd -G sudo -m -s /bin/bash xx
passwd xx
    #debian才有的 echo "auto lo" > /etc/network/interfaces
    #debian才有的 echo "iface lo inet loopback" >> /etc/network/interfaces
    #debian才有的 echo "allow-hotplug enp0s1" > /etc/network/interfaces
    #debian才有的 echo "iface enp0s1 inet dhcp" >> /etc/network/interfaces
/* 此外可以安装想要的软件包 */
apt update
apt install net-tools gdb
#安装ubuntu桌面,耗时很久
apt install ubuntu-desktop -y
exit
sudo umount rootfs 
    /* x86环境使用qemu启动arm64 linux OK*/
    qemu-system-aarch64 -m 512 -cpu cortex-a57 -M virt -nographic -smp 2 -kernel Image-5.11.10 -append "noinintrd sched_debug     root=/dev/vda rootfstype=ext4 rw crashkernel=256M loglevel=8" -drive if=none,file=ubuntu20.04_rootfs_arm64.img,id=hd0 -device virtio-blk-device,drive=hd0
  • qemu-debootstrap
sudo apt-get install debootstrap qemu-user-static schroot
dd if=/dev/zero of=./rootfs.img bs=1M count=4000
mke2fs -t ext4 ./rootfs.img
mkdir ./test
sudo mount -o loop ./rootfs.img ./test

#option 1
wget -c http://cdimage.ubuntu.com/ubuntu-base/releases/20.04/release/ubuntu-base-20.04.3-base-arm64.tar.gz
#or x86
#wget -c http://cdimage.ubuntu.com/ubuntu-base/releases/20.04/release/ubuntu-base-20.04.3-base-amd64.tar.gz
sudo tar -xzvf ubuntu-base-20.04.3-base-arm64.tar.gz -C test/
sudo cp -a /usr/bin/qemu-aarch64-static test/usr/bin/

#option 2
cd test
sudo qemu-debootstrap --arch=arm64 --variant=minbase focal ./ http://mirrors.ustc.edu.cn/ubuntu-ports/
sudo cp /etc/apt/sources.list ./etc/apt/sources.list
cd ..

sudo chroot test/
#change root passwd
passwd

echo "nameserver 127.0.0.53" >> /etc/resolv.conf 
apt update

exit
umount ./test
  • copy-to-rootfs
/* 直接往文件系统拷贝 */
$ sudo mount -t ext4 ubuntu20.04_rootfs_arm64.img tmpfs/ -o loop
$ sudo cp -af a.bin tmpfs/
$ sudo umount tmpfs
$ sudo chmod 777 ubuntu20.04_rootfs_arm64.img

3. kernel

sudo apt install libelf-dev
wget https://mirror.bjtu.edu.cn/kernel/linux/kernel/v5.x/linux-5.4.50.tar.xz
xz -d linux-5.4.50.tar.xz
tar xvf linux-5.4.50.tar.xz

#arm64 版本
    # 设置CPU架构
    $ export ARCH=arm64
    # 设置交叉编译工具链前缀
    $ export CROSS_COMPILE=~/dir/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
    $ make defconfig
#x86 版本
    $ export ARCH=x86
    $ make x86_64_defconfig

#关闭kaslr,也可在启动入参加入nokaslr
make menuconfig
#Processor type and features ---->
#    [] Randomize the address of the kernel image (KASLR)

make -j 8
#cp arch/x86/boot/bzImage ../

3 启动虚拟机

3.1 x86

qemu-system-x86_64 -kernel ./bzImage -hda ./rootfs-1m.img -append root=/dev/sda console=ttyS0 -nographic

3.2 Arm64

3.2.1 Arm64 Ubuntu20.04

/* 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启动arm虚拟机 */
qemu-system-aarch64 -m 4096 -cpu cortex-a57 -smp 8 -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 */
/* 5.安装好后启动虚拟机  */
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

3.2.2 Arm64 linux

使用qemu启动linux内核+busybox rootfs,可用于调试qemu和内核。下述操作都在Arm64环境中。
3.2.2.1 正常启动linux
./qemu-system-aarch64-4.2.1 -cpu cortex-a72 -machine virt -nographic -smp 1 -m 256M -kernel Image-5.11.10 -append "noaslr rdinit=/linuxrc console=ttyAMA0" -initrd ./rootfs.cpio.gz -hdc qemu-disk-128.img     #dev/vdc                                           

./qemu-system-aarch64-4.2.1 -cpu cortex-a72 -machine virt -nographic -smp 1 -m 256M -kernel Image-5.11.10 -append "noaslr rdinit=/linuxrc console=ttyAMA0" -initrd ./rootfs.cpio.gz -drive file=qemu-disk-128.img,cache=none,if=virtio    #/dev/vda
3.2.2.2 vm与host交互
由于没有网络,可以通过共享一个镜像在VM与Host间相互拷贝文件
#1 in vm side mount disk
mkdir -p /home/share
mount -t ext4 /dev/vda /home/share

#2 in host side
mkdir share
sudo mount -t ext4 qemu-disk-128.img share/
sudo umount share
3.2.2.3 GDB调试内核
编译内核时已带CONFIG_DEBUG_INFO,设置cpu个数为1,关闭kaslr。
#1 run kernel with gdb 1234
./qemu-system-aarch64-4.2.1 -cpu cortex-a72 -machine virt -nographic -smp 1 -m 256M -kernel Image-5.11.10 -append "noaslr rdinit=/linuxrc console=ttyAMA0" -initrd ./rootfs.cpio.gz -hdc qemu-disk-128.img  -s -S
#2 gdb debug
gdb ./vmlinux-5.11.10
target remote:1234
b virtblk_probe
c
3.2.2.3 GDB调试qemu
Qemu需要重新编译,apt install的qemu没有符号
gdb ./qemu-system-aarch64-4.2.1
set args -cpu cortex-a72 -machine virt -nographic -smp 1 -m 256M -kernel Image-5.11.10 -append "noaslr rdinit=/linuxrc console=ttyAMA0" -initrd ./rootfs.cpio.gz -hdc qemu-disk-128.img
b virtio_mmio_class_init
r
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏