DKMS:基于源码自动升级内核模块以匹配内核升级
DKMS(Dynamic Kernel Module Support)是一个用于在系统内核升级时自动重新编译和安装第三方内核模块的功能。Linux 内核升级后,第三方内核模块(如 NVIDIA/AMD GPU 驱动、VirtualBox、无线网卡驱动等)需要重新编译才能与新内核兼容。DKMS自动跟踪当前运行的内核版本,当检测到内核更新或新内核启动时,自动为新内核重新编译模块,并确保其在启动时可用。
1 DKMS 的作用
DKMS 是 Linux 系统中用于 动态管理内核模块的框架,核心作用如下:
-
自动适配不同内核版本:当内核升级后,第三方模块(如 GPU 驱动、闭源驱动)仍能自动重新编译和安装。
-
简化模块维护:第三方驱动只需一次源码安装,无需针对每个内核手动编译。
- 提高兼容性:内核升级时通过自动触发机制生成新的.ko,保证模块能被系统加载。
-
支持开发和测试:模块开发者可直接用 DKMS 管理源码与不同内核版本。
2 DKMS 工作原理
核心机制
步骤 | 说明 |
---|---|
源码管理 | 模块源码安装在/usr/src/<module>-<version> |
编译规则 | 由dkms.conf定义模块名、版本、Makefile 规则 |
数据库管理 | /var/lib/dkms记录已注册模块信息(模块名、版本、内核版本、状态) |
内核升级触发 | dkms_autoinstaller自动扫描数据库,为新内核编译模块 |
安装路径 | 编译好的.ko安装到/lib/modules/<kernel-version>/updates/dkms/ |
模块加载 | depmod -a更新模块依赖;modprobe按需加载 |
DKMS 负责生成和安装模块,实际加载由内核、udev 或用户触发。
3 DKMS 触发编译的流程
3.1 安装模块时触发
dkms add -m <module> -v <version> dkms build -m <module> -v <version> dkms install -m <module> -v <version>
流程:
-
在 /usr/src/<module>-<version> 查找源码。
-
编译模块针对当前内核版本。
-
安装 .ko 到 /lib/modules/<kernel-version>/updates/dkms/。
-
执行 depmod -a 更新模块依赖。
3.2 内核升级时触发
-
内核升级后:
-
dkms_autoinstaller扫描 /var/lib/dkms/
-
自动 build/install 针对新内核
-
更新依赖和 alias
-
3.3 手动触发
dkms build -m <module> -v <version> -k <kernel-version>
dkms install -m <module> -v <version> -k <kernel-version>
4 DKMS 模块加载机制
模块生成位置
/lib/modules/<kernel-version>/updates/dkms/<module>.ko
加载方式
- 按需自动加载
-
-
GPU/设备存在时,udev 触发 modprobe <module>
-
内核通过 alias 匹配设备,加载 DKMS 模块
-
- 手动加载:modprobe <module>
- 直接 insmod
-
-
指定完整 .ko 路径加载
-
不会解析依赖
-
DKMS 仅生成模块;加载仍需内核或用户触发。
5 DKMS 示例模块
5.1 目录结构
按照如下结构创建一个DKMS示例:
hellodkms-1.0.0/ ├── dkms.conf ├── hellodkms.c └── Makefile
5.2 源码 hellodkms.c
#include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> MODULE_LICENSE("GPL"); MODULE_AUTHOR("YourName"); MODULE_DESCRIPTION("Hello DKMS Example Module"); MODULE_VERSION("1.0"); static int __init hellodkms_init(void) { pr_info("hellodkms: module loaded!\n"); return 0; } static void __exit hellodkms_exit(void) { pr_info("hellodkms: module unloaded!\n"); } module_init(hellodkms_init); module_exit(hellodkms_exit);
5.3 Makefile
obj-m += hellodkms.o all: make -C /lib/modules/$(KERNELRELEASE)/build M=$(PWD) modules clean: make -C /lib/modules/$(KERNELRELEASE)/build M=$(PWD) clean
5.4 dkms.conf
PACKAGE_NAME="hellodkms" PACKAGE_VERSION="1.0.0" CLEAN="make clean" MAKE="make KERNELRELEASE=${kernelver}" BUILT_MODULE_NAME[0]="hellodkms" DEST_MODULE_LOCATION[0]="/updates" AUTOINSTALL="yes"
5.5 安装与测试
拷贝到/usr/src中:
sudo cp -r hellodkms-1.0.0 /usr/src/
注册模块
sudo dkms add -m hellodkms -v 1.0.0 Deprecated feature: CLEAN (/usr/src/hellodkms-1.0.0/dkms.conf) Creating symlink /var/lib/dkms/hellodkms/1.0.0/source -> /usr/src/hellodkms-1.0.0
编译模块:
sudo dkms build -m hellodkms -v 1.0.0 Deprecated feature: CLEAN (/var/lib/dkms/hellodkms/1.0.0/source/dkms.conf) Sign command: /usr/bin/kmodsign Signing key: /var/lib/shim-signed/mok/MOK.priv Public certificate (MOK): /var/lib/shim-signed/mok/MOK.der Building module(s)... done. Signing module /var/lib/dkms/hellodkms/1.0.0/build/hellodkms.ko
安装模块:
sudo dkms install -m hellodkms -v 1.0.0 Deprecated feature: CLEAN (/var/lib/dkms/hellodkms/1.0.0/source/dkms.conf) Installing /lib/modules/6.14.0-29-generic/updates/dkms/hellodkms.ko.zst Running depmod... done.--更新/lib/modules/<kernel version>/modules.dep文件。
查看状态:
dkms status hellodkms/1.0.0, 6.14.0-29-generic, x86_64: installed
加载模块:
sudo modprobe hellodkms [327877.875311] hellodkms: module loaded!
卸载模块:
sudo modprobe -r hellodkms [327888.964115] hellodkms: module unloaded!
6 总结
-
作用:自动管理内核模块,支持内核升级。
-
原理:源码注册 → 编译 → 安装 → 更新依赖 → 加载模块。
-
触发条件:安装模块、内核升级、手动 build/install。
-
模块加载:自动加载(按需)、手动 modprobe、直接 insmod。
-
示例:hellodkms 完整源码 + Makefile + dkms.conf。
比如通过DKMS管理amdgpu ko升级:Ubuntu native installation — Data Center GPU driver。