ARMv8架构下修改Linux内核并打开kvm硬件虚拟化支持(平台Firefly-rk3568)

前言

在做的一个项目需要使用ARMv8的硬件虚拟化支持,而购买的Firefly-3568默认的操作系统内核没有打开kvm虚拟化支持,所以尝试重新编译了一下内核开启虚拟化支持,并将遇到的问题和一些解决方案记录一下。

基础知识

关于内核几个配置文件的介绍可以参考[浅谈内核的Makefile、Kconfig和.config文件](浅谈内核的Makefile、Kconfig和.config文件 (baidu.com))
简单来说,内核配置过程主要由3个文件控制,Kconfig, Makefile, .config。上面文中比喻很好,类比去饭店吃饭:

  • Kconfig是菜单,即内核提供给你的各种功能、驱动之类的。例如我们以内核(rk356x_kernel)目录下的Kconfig为例:
    ARMv8架构下修改Linux内核并打开kvm硬件虚拟化支持(平台Firefly-rk3568)_第1张图片
    从上图中可以看出,内核目录下的Kconfig的作用就相当于一个总菜单栏,包括script类、init类等的不同菜类(Kconfig)。
    我们再打开一个子菜单,看真实的菜品(配置项)如下:
    ARMv8架构下修改Linux内核并打开kvm硬件虚拟化支持(平台Firefly-rk3568)_第2张图片
    像图中就定义了两个配置选项,GCC_IS_GCC和GCC_VERSION,这些会在后续的内核配置过程中决定是否编译进内核(是否成为下单的菜)。这一项如果你是打开或者关闭Linux内核本身就有的功能(如KVM)的话,就不用去修改。如果是自己添加某些功能的话,可以参考
    Linux内核中添加驱动模块到menuconfig中
  • Makefile是菜的做法,你在配置kernel config时,将会形成配置文件。然后调用Makefile根据你的配置文件来对内核进行配置。这里也同上,要是一些内置的功能的话,基本不需要修改。
  • .config就是你点的菜,这个文件其实就是最终展示给你查看你需要的功能是否被编译进内核,例如本教程想添加的KVM模块,编译进内核前后.config文件中的内容是不同的:
    kvm模块添加前:
    ARMv8架构下修改Linux内核并打开kvm硬件虚拟化支持(平台Firefly-rk3568)_第3张图片
    kvm模块添加后:
    ARMv8架构下修改Linux内核并打开kvm硬件虚拟化支持(平台Firefly-rk3568)_第4张图片

目的

在使用虚拟机的过程中,为了提升虚拟机性能,需要开启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过程详解。这里我们需要注意的是如下几点:

  • 执行make menuconfig时,相关配置文件来源于前面说明的各个目录下的Kconfig文件,这些文件是Linux内核配置的核心
  • 对某一款开发板来说,其一般都有一个默认配置文件(如这个教程中的),我们在自己进行配置的时候可以参照这个配置文件进行修改,以保留开发板原有的一些功能。
  • 一般SDK开发过程中,会有默认的脚本执行文件来实现快速的编译u-boot、内核和文件系统,我们必须对默认的配置选项进行修改,才能进而修改内核。

下面正式以rk3568的修改为例子,介绍如何添加kvm到内核:

  1. 查看并修改默认编译选项
    参考rk3568 wiki教程,使用如下命令进行编译内核:
sudo ./build.sh kernel

我们看到关键提示信息如下:
ARMv8架构下修改Linux内核并打开kvm硬件虚拟化支持(平台Firefly-rk3568)_第5张图片
从上图中可以看到内核配置文件为firefly_linux_deconfig,架构为arm64,设备相关文件为rk3568-firefly-roc-pc。因为不太了解具体build.sh文件是如何执行的,我们打开build.sh文件查找相关项:
ARMv8架构下修改Linux内核并打开kvm硬件虚拟化支持(平台Firefly-rk3568)_第6张图片
找到两条编译指令,通过观察参数,我们发现第一条make是编译内核相关的,第二条make是编译设备树相关的,这里我们需要自己编译内核,所以把第一条注释,自己执行相关编译命令。
相关编译

  1. 复制默认配置文件,并进行配置
    上文中已经说明在kernel/arch/arm64/configs目录下有默认配置文件,查看目录下文件:

默认配置文件

发现前一步中显示的默认文件firefly_linux_deconfig,将其复制到kernel目录下,替换原来的.config文件。

sudo cp arch/arm64/configs/firefly_linux_deconfig .config

然后执行,这里注意,ARCH=arm64一定不能少,不然默认会生成x86架构的配置文件:

sudo make ARCH=arm64 menuconfig

会出现下面的图形界面:
ARMv8架构下修改Linux内核并打开kvm硬件虚拟化支持(平台Firefly-rk3568)_第7张图片

这里注意两点:一是查看下一些默认配置如Linux/arm64以及Linaro GCC 6.3-2017.05是否与前面复制的.config文件中一致,如果不一致说明没能正常打开当前目录下的.config文件,需要重新复制配置文件到当前目录下(因为执行menuconfig过程中会修改.config文件)。二是移动光标到Virtualization选项,并按Y打开模块功能(*号表示功能编译进内核),然后再按Enter进入内部详情界面,再根据需求添加功能(如打开kvm支持),如下图所示。
ARMv8架构下修改Linux内核并打开kvm硬件虚拟化支持(平台Firefly-rk3568)_第8张图片
然后Save后选择Exit退出。为确认.config配置完成,可以推出后看看.config文件中是否变为了上文中的kvm模块添加后状态。
至此内核配置完成,并回到上层目录执行如下命令即成功将kvm模块添加至内核中。

sudo ./build.sh kernel

完成编译后将镜像烧录至板子,最后查看是否开启KVM模块,命令如下

zcat /proc/config.gz | grep "CONFIG_VIRTUALIZATION"

结果显示Y,大功告成:
验证

你可能感兴趣的:(嵌入式虚拟化,Unix学习,理解计算机系统,arm,架构,linux)