Linux之DKMS

DKMS简介

DKMS(Dynamic Kernel Module Support)是由 Dell 公司开发的一套内核模块管理框架,用于在 Linux 操作系统中动态构建和维护内核模块,已经被大多数 Linux 发行版采用。

dkms - Dynamic Kernel Module Support

dkms is a framework which allows kernel modules to be dynamically built for each kernel on your system in a simplified and organized fashion.

官网:https://github.com/dell/dkms

在 DKMS 中,每个内核模块都被视为一个源代码包,并通过一个称为 dkms.conf 的配置文件进行管理。该配置文件指定了源代码的位置、编译和安装模块所需的命令,以及其他必要的信息。当内核更新时,DKMS 会自动重建和安装内核模块,以确保它们与新内核版本兼容。

DKMS配置文件

当执行前面的add添加操作时,添加的源码里必须包含一个恰当的dkms.conf配置文件,里面包含了一些告诉dkms的必要信息,包括源代码的位置、编译和安装模块所需的命令等。

几个比较特别的选项:

  • AUTOINSTALL= :如果该选项为yes,当一个新的内核被安装后,dkms就会自动编译该内核对应的驱动版本。
  • REMAKE_INITRD= :如果该选项为yes,当模块被安装后就会重新构建一次initrd。
  • POST_INSTALL= :可指定安装之后需要执行的脚本。
  • POST_ADD= :同上类似
  • POST_BUILD= :同上类似
  • POST_REMOVE= :同上类似
  • PRE_INSTALL= :可指定安装之前需要执行的脚本。
  • PRE_BUILD= :同上类似

一个简单的dkms.conf例子:

PACKAGE_NAME="XXXX"
PACKAGE_VERSION="01"
AUTOINSTALL="yes"
#REMAKE_INITRD="yes"
BUILD_EXCLUSIVE_KERNEL="^5.4.*|^5.10.*"

BUILT_MODULE_NAME[0]="compat"
DEST_MODULE_NAME[0]="compat"
BUILT_MODULE_LOCATION[0]="compat"
DEST_MODULE_LOCATION[0]="/updates/dkms/compat"

... ...

BUILT_MODULE_NAME[13]="mac80211"
DEST_MODULE_NAME[13]="mac80211"
BUILT_MODULE_LOCATION[13]="net/mac80211/"
DEST_MODULE_LOCATION[13]="/updates/dkms/net/mac80211"

BUILT_MODULE_NAME[14]="cfg80211"
DEST_MODULE_NAME[14]="cfg80211"
BUILT_MODULE_LOCATION[14]="net/wireless/"
DEST_MODULE_LOCATION[14]="/updates/dkms/net/wireless"

# Find out how many CPU cores can be use if we pass appropriate -j option to make.
# DKMS could use all cores on multicore systems to build the kernel module.
num_cpu_cores()
{
        if [ -x /usr/bin/nproc ]; then
                nproc
        else
                echo "1"
        fi
}

MAKE[0]="unset KERNELRELEASE;make -j$(num_cpu_cores)"

DKMS简单操作

现在大多数Linux发行版都默认已经自带有dkms,如没有可手动安装,如:

sudo apt-get install dkms

相关常用命令:

#显示已安装的内核模块及其状态
dkms status

#将内核模块源代码添加到 DKMS 中,源码默认要求放在 /usr/src/<module>-<module-version>/
dkms add -m <module-name> -v <module-version>  [/path/to/source-tree]
#使用 DKMS 构建内核模块,后面加上-k <kernel-version>还可以构建对应内核版本的内核模块
dkms build -m <module-name> -v <module-version> 
#使用 DKMS 安装内核模块,同上,可以跟上-k 选项
dkms install -m <module-name> -v <module-version>
#与上面相对应,使用 DKMS 卸载内核模块
dkms uninstall -m <module-name> -v <module-version>
#从 DKMS 中删除内核模块,-all选项表示删除所有安装的版本
dkms remove -m <module-name> -v <module-version> --all

#创建指定内核模块的源代码压缩包,可以用于备份或分发
dkms mktarball -m <module-name> -v <module-version>
#创建指定内核模块的Debian包
dkms mkdeb -m <module-name> -v <module-version>
#创建指定内核模块的RPM包
dkms mkrpm -m <module-name> -v <module-version>

更多帮助信息可查看dkms的man手册

注:DKMS 虽然不依赖于内核源代码,但是它使用内核头文件和符号文件进行编译,所以需要安装相应的内核头文件包,即:linux-headers-xxx

参考