1. 目标

核心目标是为了验证aarch64架构下虚拟化支持问题。由于qemu是一个比较庞大的项目,提供了复杂的功能,编译起来非常费时费力,而我们仅仅是需要创建虚拟机,验证硬件虚拟化技术,故选择轻量级的kvmtool。
虚拟机系统也直接基于busybox制作。

环境基于aarch64架构的kylin server v10,详情如下:

[root@cp1 ~]# uname -a
Linux cp1 4.19.90-23.8.v2101.ky10.aarch64 #1 SMP Mon May 17 17:07:38 CST 2021 aarch64 aarch64 aarch64 GNU/Linux
[root@cp1 ~]# cat /etc/lsb-release
DISTRIB_ID=Kylin
DISTRIB_RELEASE=V10
DISTRIB_CODENAME=juniper
DISTRIB_DESCRIPTION="Kylin V10"
DISTRIB_KYLIN_RELEASE=V10
DISTRIB_VERSION_TYPE=enterprise
DISTRIB_VERSION_MODE=normal
[root@cp1 ~]# lscpu
架构:                           aarch64
CPU 运行模式:                   64-bit
字节序:                         Little Endian
CPU:                             64
在线 CPU 列表:                  0-63
每个核的线程数:                 1
每个座的核数:                   64
座:                             1
NUMA 节点:                      8
厂商 ID:                        Phytium
型号:                           2
型号名称:                       FT-2000+/64
步进:                           0x1
BogoMIPS:                       100.00
L1d 缓存:                       2 MiB
L1i 缓存:                       2 MiB
L2 缓存:                        256 MiB
NUMA 节点0 CPU:                 0-7
NUMA 节点1 CPU:                 8-15
NUMA 节点2 CPU:                 16-23
NUMA 节点3 CPU:                 24-31
NUMA 节点4 CPU:                 32-39
NUMA 节点5 CPU:                 40-47
NUMA 节点6 CPU:                 48-55
NUMA 节点7 CPU:                 56-63

2. kvmtool

2.1 下载kvmtools

通过git log查看,发现git.kernel.org的更新一些,不过最后编译出来执行lkvm version输出的版本是一样的

git clone git://git.kernel.org/pub/scm/linux/kernel/git/will/kvmtool.git
git clone --depth 1 https://github.com/kvmtool/kvmtool.git

2.2 依赖包安装

yum install ncurses-devel

2.3 编译安装

cd kvmtool
make
sudo cp lkvm /usr/local/bin

3. 系统制作

3.1 内核制作

3.1.1 下载内核

下载地址如下:

https://mirrors.tuna.tsinghua.edu.cn/kernel/
https://cdn.kernel.org/pub/linux/kernel/
https://mirrors.edge.kernel.org/pub/linux/kernel/

根据需要选择版本,我这与host os保持一致,选择了4.19.90内核版本

wget https://mirrors.tuna.tsinghua.edu.cn/kernel/v4.x/linux-4.19.90.tar.gz

3.1.2 解压

tar -xvf linux-4.19.90.tar.gz
cd linux-4.19.90/

3.1.3 设置CPU架构

export ARCH=arm64

3.1.4 设置选项

make menuconfig

在 menuconfig 中需要将一些模块编译进内核,如下所示:

  • For the default console output:
    CONFIG_SERIAL_8250=y
    CONFIG_SERIAL_8250_CONSOLE=y
-> Device Drivers                                                   
  -> Character devices                                              
    -> Serial drivers                                               
     -> 8250/16550 and compatible serial support (SERIAL_8250 [=y])
  • For running 32bit images on 64bit hosts:
    CONFIG_IA32_EMULATION=y
  • Proper FS options according to image FS (e.g. CONFIG_EXT3_FS, CONFIG_EXT4_FS).
  • For all virtio devices listed below:
    CONFIG_VIRTIO=y
    CONFIG_VIRTIO_PCI=y
-> Device Drivers                     
  -> Virtio drivers (VIRTIO_MENU [=y])
  • For virtio-blk devices (–disk, -d):
    CONFIG_VIRTIO_BLK=y
-> Device Drivers                
  -> Block devices (BLK_DEV [=y])
  • For virtio-net devices ([–network, -n] virtio):
    CONFIG_VIRTIO_NET=y
-> Device Drivers                                 
  -> Network device support (NETDEVICES [=y])     
    -> Network core driver support (NET_CORE [=y])
    -> Virtio network driver
  • For virtio-9p devices (–virtio-9p), 9p virtio, 支持 host 和 guest 中共享目录:
    CONFIG_NET_9P=y
    CONFIG_NET_9P_VIRTIO=y
    CONFIG_9P_FS=y
-> Networking support (NET [=y])                            
  -> Plan 9 Resource Sharing Support (9P2000) (NET_9P [=y]) 
     -> File systems                                      
         -> Network File Systems (NETWORK_FILESYSTEMS [=y]) 
  • For virtio-balloon device (–balloon):
    CONFIG_VIRTIO_BALLOON=y
-> Device Drivers                      
  -> Virtio drivers (VIRTIO_MENU [=y]) 
  • For virtio-console device (–console virtio):
    CONFIG_VIRTIO_CONSOLE=y
-> Device Drivers     
  -> Character devices
  • For virtio-rng device (–rng):
    CONFIG_HW_RANDOM_VIRTIO=y
-> Device Drivers                                                    
  -> Character devices                                               
    -> Hardware Random Number Generator Core support (HW_RANDOM [=y])
  • For vesa device (–sdl or --vnc):
    CONFIG_FB_VESA=y
-> Device Drivers                                  
  -> Graphics support                              
    -> Frame buffer Devices                        
      -> Support for frame buffer devices (FB [=y])
  • Support for uevent helper
    UEVENT_HELPER
-> Device Drivers                                    
  -> Generic Driver Options                          
    -> Support for uevent helper (UEVENT_HELPER [=y])

3.1.5 编译

根据CPU核数对编译参数进行配置

[root@cp1 linux-4.19.90]# make -j64
scripts/kconfig/conf  --syncconfig Kconfig
  CALL    scripts/checksyscalls.sh
  CHK     include/generated/compile.h
  CC      drivers/net/virtio_net.o
  CC      drivers/net/net_failover.o
  CC      net/core/failover.o
  GZIP    kernel/config_data.gz
  UPD     kernel/config_data.h
  CC      kernel/configs.o
  AR      kernel/built-in.a
  AR      net/core/built-in.a
  AR      net/built-in.a
  AR      drivers/net/built-in.a
  AR      drivers/built-in.a
  GEN     .version
  CHK     include/generated/compile.h
  UPD     include/generated/compile.h
  CC      init/version.o
  AR      init/built-in.a
  AR      built-in.a
  LD      vmlinux.o
  MODPOST vmlinux.o
  KSYM    .tmp_kallsyms1.o


  KSYM    .tmp_kallsyms2.o
  LD      vmlinux
  SORTEX  vmlinux
  SYSMAP  System.map
  OBJCOPY arch/arm64/boot/Image
  Building modules, stage 2.
  GZIP    arch/arm64/boot/Image.gz
  MODPOST 1585 modules

最后编译完成的内核位于arch/arm64/boot/Image,kernel编译完成,该Image一会启动时将用到。

3.2 根文件系统制作

3.2.1 下载buysbox源码

选择1.35的版本

wget https://busybox.net/downloads/busybox-1.35.0.tar.bz2

3.2.2 配置buysbox源码

tar -xvf busybox-1.35.0.tar.bz2
cd busybox-1.35.0/
make menuconfig

把busybox配置为静态编译,这样busybox在运行的时候就不需要额外的动态链接库

-> Settings
  -> Build Options
    -> Build BusyBox as a static binary (no shared libs)

3.2.3 编译安装buysbox

make -j64 && make install

3.2.4 rootfs

3.2.4.1 创建根目录所需的目录
cd _install
mkdir -p dev etc home lib mnt proc root sys tmp var

根文件系统目录说明

/bin: 系统管理员和用户均可使用的命令
/sbin: 系统管理员使用的系统命令
/dev: 存储特殊文件或设备文件;设备两种类型:字符设备、块设备
/etc: 系统配置文件
/home: 普通用户目录
/root:root用户目录
/lib: 为系统启动或根文件上的应用程序(/bin,/sbin等)提供共享库,以及为内核提供内核模块
/mnt:临时挂载点
/tmp: 临时文件存储目录
/usr:usr hierarchy,全局共享的只读数据路径
/var:存储常发生变化的数据目录:cache、log等
/proc: 基于内存的虚拟文件系统,用于为内核及进程存储其相关信息
/sys:sysfs虚拟文件系统提供了一种比proc更为理想的访问内核数据的途径:其主要作用在于为管理linux设备提供一种统一模型的接口;

3.2.4.2 创建根目录所需的必要文件
  • fstab
cat> etc/fstab << EOF
proc  /proc proc  defaults 0 0
tmpfs  /tmp  tmpfs  defaults 0 0
none  /tmp  ramfs defaults 0 0
sysfs /sys  sysfs defaults 0 0
mdev  /dev  ramfs defaults 0 0
EOF
  • profile
cat > etc/profile << EOF
PATH=/bin:/sbin:/usr/bin:/usr/sbin
export LD_LIBRARY_PATH=/lib:/usr/lib
/bin/hostname minilinux
USER="`id -un`"
LOGNAME=$USER
HOSTNAME='/bin/hostname'
PS1='[\u@\h \W]# '
EOF
  • rcS
mkdir -p etc/init.d/
cat > etc/init.d/rcS << EOF
/bin/mount -a
mkdir -p /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
echo "************Welcome to mini Linux************"
EOF
chmod 755 etc/init.d/rcS
  • initab
cat > etc/inittab << EOF
::sysinit:/etc/init.d/rcS
::respawn:-/bin/sh
::askfirst:-/bin/sh
::ctrlaltdel:/bin/umount -a -r
EOF
chmod 755 etc/inittab
  • 添加设备文件
cd dev
mknod console c 5 1
mknod null c 1 3
mknod tty1 c 4 1
cd -
3.2.4.3 制作根文件系统镜像文件rootfs.cpio.gz
find . | cpio -o -H newc > ../rootfs.cpio 
cd ..
gzip -c rootfs.cpio > rootfs.cpio.gz
3.2.4.4 制作根文件系统镜像文件rootfs.ext4
dd if=/dev/zero of=rootfs.ext4 bs=1M count=32
mkfs.ext4 rootfs.ext4
mkdir -p rootfs
mount -o loop rootfs.ext4 rootfs
cp -rf _install/* rootfs
umount rootfs

4 启动mini linux

4.1 基于initrd 启动方式

lkvm run --kernel linux-4.19.90/arch/arm64/boot/Image --initrd busybox-1.35.0/rootfs.cpio.gz --param "root=/dev/ram rdinit=/linuxrc" --console serial  --name vm1

4.2 基于disk启动方式

lkvm run --kernel linux-4.19.90/arch/arm64/boot/Image --disk busybox-1.35.0/rootfs.ext4 --console serial  --name vm1

4.3 启动效果

启动效果如下:
在这里插入图片描述


5. 问题记录

  • 编译lkvm报“hw/i8042.c:153:19: error: ‘value’ may be used uninitialized in this function [-Werror=maybe-uninitialized]”错误,具体如下:
hw/i8042.c: In function 'kbd_io':
hw/i8042.c:153:19: error: 'value' may be used uninitialized in this function [-Werror=maybe-uninitialized]
   state.write_cmd = val;
   ~~~~~~~~~~~~~~~~^~~~~
hw/i8042.c:298:5: note: 'value' was declared here
  u8 value;
     ^~~~~
cc1: all warnings being treated as errors
make: *** [Makefile:483: hw/i8042.o] Error 1

这是因为在Makefile中CFLAGS加了-Werror参数,将所有警告当做error处理。将Makefile中的-Werror参数注释掉,如下:

#ifneq ($(WERROR),0)
#       CFLAGS += -Werror
#endif
#
  • aarch64架构下报Makefile:347: *** No libfdt found. Please install libfdt-dev package,缺包问题
wget https://vault.centos.org/centos/8/PowerTools/aarch64/os/Packages/libfdt-devel-1.6.0-1.el8.aarch64.rpm
wget https://vault.centos.org/centos/8/AppStream/aarch64/os/Packages/libfdt-1.6.0-1.el8.aarch64.rpm

rpm -ivh libfdt-1.6.0-1.el8.aarch64.rpm
rpm -ivh libfdt-devel-1.6.0-1.el8.aarch64.rpm
  • 编译lkvm时报No rule to make target ‘/usr/include/gnu/stubs-64.h’, needed by ‘builtin-balloon.o’. Stop.错误,具体如下
Makefile:361: Skipping optional libraries: bfd aio
make: *** No rule to make target '/usr/include/gnu/stubs-64.h', needed by 'builtin-balloon.o'.  Stop.

问题为当时基于x86环境进行了编译为清理,拷贝至aarch64架构未进行清理,故需要执行make clean,再make,问题解决

  • 启动虚拟机时,报virtio-net device was not detected.错误,具体如下:
  # KVM compatibility warning.
        virtio-net device was not detected.
        While you have requested a virtio-net device, the guest kernel did not initialize it.
        Please make sure that the guest kernel was compiled with CONFIG_VIRTIO_NET=y enabled in .config.

问题为menuconfig 编译内核是把CONFIG_VIRTIO_NET设置为m,即模块,需要将CONFIG_VIRTIO_NET=y,直接编译进内核

  • 启动虚拟机时,报/etc/init.d/rcS: line 4: can’t create /proc/sys/kernel/hotplug: nonexistent directory
    内核需要将UEVENT_HELPER 设置y,直接编译进内核

6. 参考文献:

https://github.com/kvmtool/kvmtool
https://jerling.github.io/post/%E4%BD%BF%E7%94%A8kvmtool%E5%90%AF%E5%8A%A8linux/
https://blog.csdn.net/caojinhuajy/article/details/119277087
https://www.bilibili.com/read/cv7118525
kernel:https://mirrors.tuna.tsinghua.edu.cn/kernel/
http://patchwork.ozlabs.org/project/buildroot/patch/20190523131444.36058-1-andriy.shevchenko@linux.intel.com/

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐