Kata rootfs 适配昇腾GPU驱动(Arm平台)
虚拟机
选择
- 系统:驱动适配比较好的系统是CentOS 7.6和8.2,本次制作使用CentOS 8.2.2004 arm 镜像
- 虚拟机:驱动依赖硬件设备,所以选择在宿主机通过qemu启动虚拟机,在虚拟机内部适配驱动
- 其他:开启kvm加速,实测arm架构下开启kvm,需要宿主机是L0(不能是虚拟机),且bios使用edk2
- 宿主机:宿主机系统为银河麒麟v10 arm版
准备工作
- 下载CentOS 8.2.2004 arm 镜像
- 下载bios引导文件,edk2-aarch64的安装包,执行安装
- 下载地址:https://www.kraxel.org/repos/jenkins/edk2/
- 安装后bios文件位于 /usr/share/edk2.git/aarch64/QEMU_EFI.fd
- 安装最新的qemu(建议编译安装,可以选择自己依赖的组件,直接从yum源安装的可能缺少组件)
- 补充说明:qemu启动虚拟机后,可以通过-net user直接共享宿主机的网络,并可以开启ssh通道,该功能依赖slirp,编译配置的时候需要启用slirp
制作虚拟机(宿主机)
- 制作qcow2文件(相当于是硬盘, 文件名hd.qcow2 , 大小100G)
- qemu-img create -f qcow2 hd.qcow2 100G
- 安装操作系统
- qemu启动命令:qemu-system-aarch64 -m 24G -cpu host -smp 16 -M virt,accel=kvm -bios QEMU_EFI.fd -nographic -drive if=none,file=hd.qcow2,id=hd0 -device virtio-blk-device,drive=hd0 -drive if=none,file=CentOS-8.2.2004-aarch64-dvd1.iso,id=cdrom,media=cdrom -device virtio-scsi-device -device scsi-cd,drive=cdrom -net user,hostfwd=tcp::2222-:22 -net nic -device vfio-pci,host=0000:83:00.0
- qemu参数说明:
- -m 24G 指定内存大小
- -cpu host 指定CPU类型和宿主机一致,注意host类型需要开启kvm加速
- -M virt,accel=kvm machineType类型为virt(arm均使用virt),加速器使用kvm
- -smp 16 cpu 16核
- -bios QEMU_EFI.fd 指定edk2的efi文件
- -nographic 因为不是在本地,所以直接通过控制台以基础文本的形式显示
- -drive if=none,file=hd.qcow2,id=hd0 -device virtio-blk-device,drive=hd0 指定硬盘设备及驱动
- -drive if=none,file=CentOS-8.2.2004-aarch64-dvd1.iso,id=cdrom,media=cdrom -device virtio-scsi-device -device scsi-cd,drive=cdrom 指定操作系统安装文件,以cdrom方式加载
- -net user,hostfwd=tcp::2222-:22 -net nic 开启与宿主机的共享网络,同时将虚拟机的22端口映射到宿主机的2222端口
- -device vfio-pci,host=0000:83:00.0 将宿主机的设备vfio直通到虚拟机
- 如果在宿主机无法正常安装,可以考虑本地启动qemu安装,然后将qcow2文件拷贝至服务器
- 安装完成后重启系统即可,以后启动qemu cdrom参数不再需要。
- 注意事项:
- 虚拟机启动后,需要开启sshd,否则无法ssh连接到虚拟机
- QEMU_EFI.fd一定用edk2的,不要使用
https://releases.linaro.org/components/kernel/uefi-linaro/latest/release/qemu64/QEMU_EFI.fd
这个版本,这个无法开启kvm加速 - 全虚拟化的虚拟机慢的要死,开机就要15分钟,一定要开启kvm加速,后面驱动适配在全虚拟化下也会失败(全虚拟化运行太慢,导致驱动执行失败)
- vfio宿主机一定要开启,否则虚拟机无法获取设备
- 设备号可以通过lspci看到
内核制作
修改内核magversion
- 进入内核源码目录,修改 include/linux/vermagic.h
- 修改
#define MODULE_VERMAGIC_MODULE_UNLOAD ""
- 为:
#define MODULE_VERMAGIC_MODULE_UNLOAD "mod_unload"
- 修改
#define MODULE_VERMAGIC_MODVERSIONS ""
- 为:
#define MODULE_VERMAGIC_MODVERSIONS "modversions"
- 修改
编译内核获取bzImage(宿主机或虚拟机都可)
- 直接执行make就行,注意配置和之前保持一致
- 编译完成后,将arch/aarch64/boot/bzImage拷贝出来,作为kata启动的kernel
制作内核rpm安装包(宿主机或虚拟机都可)
- 保持配置不变,执行make rpm-pkg
- 然后将kernel,kernel-devel,kernel-headers三个rpm拷贝出来
虚拟机安装新内核(虚拟机)
- 将编译的rpm安装包拷贝至虚拟机(开启ssh后scp -P 2222 xxx xxx@localhost:~即可)
- 进入虚拟机后,执行rpm -ivh kernel-xxxxx.rpm 安装内核,然后重启虚拟机,用编译版本的内核启动虚拟机,准备后续rootfs制作
rootfs制作
制作rootfs(宿主机或虚拟机都可)
- 进入kata源码kata-containers/tools/osbuilder/目录下,执行make镜像命令
make DISTRO=centos OS_VERSION=8.2.2004 SECCOMP=no DEBUG=true USE_DOCKER=true AGENT_INIT=yes EXTRA_PKGS='net-tools pciutils udev e2fsprogs tar gcc' rootfs
- net-tools pciutils udev e2fsprogs tar gcc 这几样工具是驱动安装过程中需要的,需要提前打包至rootfs
拷贝rootfs至虚拟机
- 上一步操作完成后,当前目录下会出来centos_rootfs文件夹,将该目录打包,拷贝至虚拟机
- tar czvf centos_rootfs.tgz centos_rootfs
- scp -P 2222 centos_rootfs.tgz root@localhost:~
驱动适配
补充缺失文件(虚拟机,其实这一步再打包之前操作也可以)
- 解压rootfs
- /usr/share/zoneinfo文件夹拷贝至 rootfs对应的目录下(centos默认rootfs缺失时区信息,无法安装驱动)
- 拷贝驱动文件,kernel-devel,kernel-headers到rootfs的某目录下(我拷贝到home目录下),用于后续chroot安装
- 创建hook脚本
- mkdir -p /usr/share/oci/hooks/prestart
- cd /usr/share/oci/hooks/prestart
- 创建mount_tmpfs.sh脚本,解决/tmp,/var/log 只读问题,内容如下:
1 | #!/bin/sh |
挂载目录(虚拟机)
export ROOTFS_DIR=/root/centos_rootfs
mount -t sysfs -o ro none ${ROOTFS_DIR}/sys
mount -t proc -o ro none ${ROOTFS_DIR}/proc
mount -o bind,ro /dev ${ROOTFS_DIR}/dev
mount -t devpts none ${ROOTFS_DIR}/dev/pts
mount -t tmpfs none ${ROOTFS_DIR}/tmp
chroot并安装驱动(虚拟机)
- chroot $ROOTFS_DIR
- 进入home目录(驱动和kernel目录)
- 安装kernel-devel和kernel-headers (rpm -ivh kernel*.rpm)
- 创建华为用户组HwHiAiUser 和 用户
groupadd HwHiAiUser
useradd -g HwHiAiUser -d /home/HwHiAiUser -m HwHiAiUser -s /bin/bash
- 安装驱动 ./A300-3000-npu-driver_21.0.3.3_linux-aarch64.run –full
- 驱动安装成功后,执行 /usr/local/sbin/npu-smi info 如果能正常回显,则继续安装驱动,不能正常回显,则重启虚拟机,先exit退出chroot
- 解除挂载
umount ${ROOTFS_DIR}/sys ${ROOTFS_DIR}/proc ${ROOTFS_DIR}/dev/pts ${ROOTFS_DIR}/tmp ${ROOTFS_DIR}/dev
- 然后reboot重启虚拟机,重启后重新挂载目录,然后执行 /usr/local/sbin/npu-smi info 看是否能正常回显
- 正常回显后,安装固件 ./A300-3000-npu-firmware_1.81.22.2.220.run –full
- 然后删除内核源码(/usr/src/kernels下,内核版本的源码删除),删除kernel-devel,kernel-headers,驱动等文件(减少rootfs镜像大小)
- exit退出chroot
- 解除挂载
umount ${ROOTFS_DIR}/sys ${ROOTFS_DIR}/proc ${ROOTFS_DIR}/dev/pts ${ROOTFS_DIR}/tmp ${ROOTFS_DIR}/dev
- 将rootfs打包(如果rootfs在虚拟机中制作,则忽略该步骤),并拷贝到宿主机上
制作镜像
- 解压虚拟机中的rootfs文件
- 切换到kata的image-builder目录(kata-containers/tools/osbuilder/image-builder)
- 制作镜像./image_builder.sh rootfsDir
- 得到kata-containers.img
其他适配
配置文件
- kata的config需要进行以下几个修改
guest_hook_path = "/usr/share/oci/hooks"
kernel_modules=["drv_devdrv_host","drv_davinci_intf_host","drv_tsdrv_platform_host","drv_pcie_vnic_host","drv_pcie_hdc_host","drv_devmm_host"]
hotplug_vfio_on_root_bus = true
pcie_root_port = 2
- 说明:
guest_hook_path
执行hook,路径不需要更改,驱动需要挂载tmpfs,通过hook执行kernel_modules
驱动的modules默认不会加载,需要手动加载,配置到这里,vm启动会自动加载hotplug_vfio_on_root_bus
开启root bus,arm平台需要通过pcie_root_port进行设备热插拔pcie_root_port
单个虚拟机最多可以挂载GPU设备数
Kata源码
- 主要修改如下:
- virt模式支持pcieRootPort设备,通过配置进行加载
- qmp添加设备指定bus为pcieRootPort设备,arm下只有pcieRootPort支持热插拔
Q&A
启动后,kata-runtime exec 进入vm后,/dev/loop设备只有1个
- 修改内核配置
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_LOOP_MIN_COUNT=4
- 修改内核配置
qemu 使用 -cpu host -M virt,accel=kvm 启动虚拟机黑屏
- bios的efi启动文件不正确,使用edk2的efi文件即可
安装驱动npu-smi info执行后提示
dcmi module initialize failed. ret is -8005
- 提示-8005的原因有很多,下面列出来几个适配中遇到过的
- 显卡设备被其他驱动占用,去/sys/bus/pci/drivers/devdrv_device_driver目录下重新bind设备即可。
- 内核模块加载不全,lsmod对比kernel_modules中的配置,是否已经加载全。
- 同时提示
sh: /tmp/pci_get_info_234.tmp: Read-only file system
检查Hook脚本是否执行,可以df看下挂载情况。 - 其他原因,可以通过dmesg查看kernel日志,具体排查
- 提示-8005的原因有很多,下面列出来几个适配中遇到过的
chroot后,安装驱动,提示缺少xxxx组件
- EXTRA_PKGS后面追加缺少的命令的安装包即可,无依赖的,可直接拷贝到rootfs对应目录下
kernel-devel和kernel-headers是否可以不安装?
- 需要安装,驱动安装过程中,有部分模块依赖内核,需要通过内核源码进行重编译,安装完成后,删除对应src目录即可。
- 通过dkms安装会快点,但是依赖过多,不建议
内核日志提示:
drv_seclib_host: version magic '5.4.160-1.el7.aarch64 SMP mod_unload modversions aarch64' should be '5.4.160-1.el7.aarch64 SMP aarch64'
- 内核的version magic和编译的驱动的version magic不一致,参考内核部分修改version magic,重新编译即可
qemu启动时加上-net user提示
-net user: Parameter 'type' expects a net backend type (maybe it is not compiled into this binary)
- 编译qemu缺少slirp,重新config qemu,加上slirp后重新make qemu即可