在做的一个项目需要使用ARMv8的硬件虚拟化支持,而购买的Firefly-3568默认的操作系统内核没有打开kvm虚拟化支持,所以尝试重新编译了一下内核开启虚拟化支持,并将遇到的问题和一些解决方案记录一下。
关于内核几个配置文件的介绍可以参考[浅谈内核的Makefile、Kconfig和.config文件](浅谈内核的Makefile、Kconfig和.config文件 (baidu.com))
简单来说,内核配置过程主要由3个文件控制,Kconfig, Makefile, .config。上面文中比喻很好,类比去饭店吃饭:
在使用虚拟机的过程中,为了提升虚拟机性能,需要开启KVM虚拟化支持。通过配置内核修改.config文件,最终实现内核集成KVM。
一些前期尝试:
首先,既然发现.config文件就是内核的配置文件,首先意识到可不可以直接修改.config文件,在其中修改内核的支持项。但尝试后发现,每次修改完再执行Makefile时,系统会自动将.config文件改为初始配置。这里估计是.config文件与每个目录下的Kconfig文件建立了联系,且.config文件并非最终用作内核配置的文件(更倾向于是用作给使用者看的文件),所以必须将其保存至真正的配置使用文件。
网上的教程说真正用作配置的文件一般是在kernel/arch/arm64(架构目录,如果是x86的话就是kernel/arch/x86)/configs目录下。所以尝试了可以执行如下命令进行保存:
#配置
#以下命令都在kernel目录下执行
make savedefconfig
mv defconfig arch/arm64/configs/firefly_linux_defconfig(与板子相关的配置文件,在执行make命令时可以在输出中找到)
#开始编译
执行完这个命令之后,编译过程中确实不会再出现.config文件被重写的问题,但是在firefly3568_pc平台测试过程中简单的在.config文件中加一些项会出现报错,这里估计是许多配置的修改并不是单独的,例如KVM模块的添加可能可能会涉及到许多其他的功能更改,所以到这里这条直接修改.config文件的路算是走不通了,估计还是得通过make menuconfig命令修改。
这里我们选择make menuconfig来作为内核的配置方式,具体make menuconfig的过程分析可以参考menuconfig过程详解。这里我们需要注意的是如下几点:
下面正式以rk3568的修改为例子,介绍如何添加kvm到内核:
sudo ./build.sh kernel
我们看到关键提示信息如下:
从上图中可以看到内核配置文件为firefly_linux_deconfig,架构为arm64,设备相关文件为rk3568-firefly-roc-pc。因为不太了解具体build.sh文件是如何执行的,我们打开build.sh文件查找相关项:
找到两条编译指令,通过观察参数,我们发现第一条make是编译内核相关的,第二条make是编译设备树相关的,这里我们需要自己编译内核,所以把第一条注释,自己执行相关编译命令。
发现前一步中显示的默认文件firefly_linux_deconfig,将其复制到kernel目录下,替换原来的.config文件。
sudo cp arch/arm64/configs/firefly_linux_deconfig .config
然后执行,这里注意,ARCH=arm64一定不能少,不然默认会生成x86架构的配置文件:
sudo make ARCH=arm64 menuconfig
这里注意两点:一是查看下一些默认配置如Linux/arm64以及Linaro GCC 6.3-2017.05是否与前面复制的.config文件中一致,如果不一致说明没能正常打开当前目录下的.config文件,需要重新复制配置文件到当前目录下(因为执行menuconfig过程中会修改.config文件)。二是移动光标到Virtualization选项,并按Y打开模块功能(*号表示功能编译进内核),然后再按Enter进入内部详情界面,再根据需求添加功能(如打开kvm支持),如下图所示。
然后Save后选择Exit退出。为确认.config配置完成,可以推出后看看.config文件中是否变为了上文中的kvm模块添加后状态。
至此内核配置完成,并回到上层目录执行如下命令即成功将kvm模块添加至内核中。
sudo ./build.sh kernel
完成编译后将镜像烧录至板子,最后查看是否开启KVM模块,命令如下
zcat /proc/config.gz | grep "CONFIG_VIRTUALIZATION"