#硬件环境:x86 PC
#软件环境:ubuntu20. 04 ;qemu
#目标:使用qemu创建x86虚拟机和arm64虚拟机
1. qemu
sudo apt install qemu qemu-system
2. rootfs
rootfs有多种方法制作,如busybox,buildroot,Ubuntu等,busybox/buildroot尺寸最小但很难安装图形栈,Ubuntu rootfs尺寸较大但安装图形栈方便。
下面将介绍这两种玩法
2.1 Busybox rootfs
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
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
make defconfig
make menuconfig
Settings --->
.. .
--- Build Options
[ *] Build static binary ( no shared libs)
.. .
make -j 8
make install
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一样
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
#安装图形用8 G
dd if = / dev/ zero of= ubuntu20. 04 _rootfs_arm64. img bs= 1 M count= 1024
mkfs. ext4 ubuntu20. 04 _rootfs_arm64. img
mkdir rootfs
sudo mount ubuntu20. 04 _rootfs_arm64. img rootfs/
# arm 64 的ubuntu rootfs
sudo debootstrap -- arch arm64 focal rootfs/ http:
或debian:sudo debootstrap -- arch arm64 -- foreign buster rootfs/ http:
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
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
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
wget -c http://cdimage.ubuntu.com/ubuntu-base/releases/20.04/release/ubuntu-base-20.04.3-base-arm64.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/
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/
passwd
echo "nameserver 127.0.0.53" >> /etc/resolv.conf
apt update
exit
umount ./test
/* 直接往文件系统拷贝 */
$ 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
$ 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
$ export ARCH = x86
$ make x86_64_defconfig
make menuconfig
make -j 8
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
./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
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 256 M - 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 256 M - 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