概述 DKMS是基于动态内核模块支持的可以让开发者无需使用最新的内核版本而对某个单一的内核模块做升级(比如说是修复bug)
DKMS设计目标 1 实现的是机制(如何更新单一的内核模块并且跟踪)而不是策略(何时应该更新一个单一的内核模块),目的在于将两者隔开
2 允许系统管理员清楚地知道哪个模块、哪个版本为哪个内核以什么样的状态使用
3 让模块的源码保持是在顶层的内核树在kernel.org,使用补丁来使模块与更早的内核相兼容
4 应用内核-提供 创建机制。这样可以减少开发者必需弄清楚Makefile的困难,当有错误的时候
5 保持开发者需要额外的DKMS知识在最少的状态,只需要dkms.conf文件
6 允许多个版本同时出现在系统中,但是在任何时刻只有一个时活跃的,就是说只有一个可以使用在一个时刻
7 允许支持DKMS的驱动能够在linux标准基础上打成RPM格式
8 让多个使用者方便使用:驱动开发者、系统管理员、linux distros和系统售卖者
DKMS的生命周期:
有一个图形的使用说明了DKMS的生命周期,是由多个状态组成的
RPM:RedHat Package Manger 红帽包管理器
使用DKMS 1 Add
首先使用DKMS的模块的源码必需在/usr/src/<module>-<module-version>/.目录下。dkms.conf文件必需在适合的目录下,告诉DKMS在什么地方安装模块和怎样创建它。
命令:
<span style=”font-size:18px;”>dkms add -m module-name -v module-version </span>
将module-name/module-version加入到/var/dkms树中
2 Build
此时需要内核的源码在/lib/module/<kernel-version>/build的软链接下,才能创建(build)
命令: dkms build -m module-name -v module-version -k 2.6.35 解释:在build步骤会编译模块,如果-k后的参数不写出来,则默认为当前运行的内核版本,但是可以很好的编译(不是当前运行的内核,这点很重要,只要你有这个版本内核的软链接在这个目录下)
3 Install
在build完成之后,这样这个模块就可以安装到内核中了,安装将生成的模块二进制文件复制到/lib/modules树下。如果相同名字的模块已经存在,那么dkms将它保存在原来的目录下,这样在新的模块被卸载之后就可以用来代替。例子:
dkms install -m module-name -v version -k kernel-version若这个模块已经被安装,DKMS会保留副本在/var/dkms/<module-name>/original_module/目录下。
4 uninstall和remove
uninstall命令删除/lib/modules下你安装的这个模块
dkms uninstall -m module-name -v version -k kernel-version
同样,如果如果-k参数未指定,则使用当前运行的内核
那么remove则会将这个模块的所有的traces在DKMS树中
dkms remove -m module-name -v version -k kernel-versiondkms remove -m module-name -v version –all
第一个命令,不会将在另外的内核上的这个模块删除
第二个命令,将会删除所有的version在所有版本的内核中
因此,remove命令就是清除DKMS树
5 status命令
status命令返回的是当前的DKMS树的信息,如果没有加参数,就返回所有的信息 逻辑上讲,具体的返回信息取决于你所加的参数
dkms [-m module-name] [-v version] [-k kernel-version]可选参数
6 match
可以将一个内核版本的模块转换到另外的内核,但是要保证在相应的内核模块下有这个模块的相关文件。
dkms match –templatekernel kernel-version -k kernel-version–templatekernel 是说明以这个配置为基础,-k说明是在这个版本上执行
7 mktarball
生成tar文件包
驱动开发 你只需要在驱动的源码中加入dkms.conf文件,接着使用dkms ldtarball –archive /path/to/foo-1.0.tgz
列举两个例子,来说明两个dkms.conf文件
1 最简便的必需的例子 2 非常完整的例子
1 简单必需的例子
包版本的定义、使用make命令编译模块
PACKAGE_NAME 和BUILT_MODULE_NAME通常是相同的(即是复制)
DEST_MODULE_LOCATION数组也是必要的,就是告诉DKMS在/lib/modules下的模块应该安装在什么地方
例子:
PACKAGE_NAME=“bsdocfs”PACKAGE_VERSION=”0.1″MAKE[0]=”make -C ${kernel_source_dir} SUBDIRS=${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build modules”BUILT_MODULE_NAME[0]=”bsdocfs”DEST_MODULE_LOCATION[0]=”/kernel/fs/bsdocfs”
对内核版本和架构的限制
BUILD_EXCLUSIVE_KERNEL=BUILD_EXCLUSIVE_ARCH=这表明只允许指定的内核和架构安装
POST_INSTALL等命令的使用,待以后再说明
举例说明:
1. 安装与当前内核版本对应的内核开发包
2. 安装dkms包
3. 创建目录/usr/src/<module>-<module-version>/
[root@host]# mkdir /usr/src/cifs-1.45fixed/4. 拷贝内核模块的代码到该目录
[root@host]# cd ~/rpmbuild/BUILD/kernel-2.6.18/linux-2.6.18-i686/fs/cifs[root@host cifs]# cp -a * /usr/src/cifs-1.45fixed/5. 新建dkms.conf文件
[root@host cifs]# cd /usr/src/cifs-1.45fixed[root@host cifs-1.45fixed]# vi dkms.conf配置文件dkms.conf要包含如下:
PACKAGE_NAME=”cifs”PACKAGE_VERSION=”1.45fixed”BUILT_MODULE_NAME[0]=”cifs”DEST_MODULE_LOCATION[0]=”/kernel/fs/cifs/”AUTOINSTALL=”yes”ps:<span style=”font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);”>DEST_MODULE_LOCATION[0]在安装模块的是会被忽略</span>
默认的总是 /lib/modules/<kernel-version>/extra/ 目录。
这个参数是在模块被卸载的时候,数据保存的路径 ,类似保留旧模块数据。
6.加入<module>/<module-version> 到DKMS树
[root@host cifs-1.45fixed]# dkms add -m cifs -v 1.45fixed7. 编译DKMS
[root@host cifs-1.45fixed]# dkms build -m cifs -v 1.45fixed8. 安装DKMS[root@host cifs-1.45fixed]# dkms install -m cifs -v 1.45fixed
ps: 在内核2.6.35.3 (i686)可能会报错
参考manpage
http://linux.dell.com/dkms/manpage.html
白皮书
http://linux.dell.com/dkms/dkms-ols2004.pdf