32 位 – CLR – CMake – DKMS – Eclipse – Electron – Free Pascal – GNOME – Go – Haskell – Java – 交叉编译工具 – KDE – Lisp – Meson – MinGW – 内核模块 – Node.js – Nonfree – OCaml – Perl – PHP – Python – R – Ruby – Rust – VCS – Web – Wine – 字体
创建一个新的 DKMS 包时,可以参考下面的指导方针。
包名
DKMS 包的命名方式是:原始包名加"-dkms"后缀。
通常在 $pkgname 后面使用 $_pkgname 记录不包含 "-dkms" 后缀的软件包名 (例如 _pkgname=${pkgname%-*}). 这样可以在原始的软件包 PKGBUILD 和 DKMS 编译文件之间保持相似性。
依赖
依赖的包应该是原来软件包的基础上,加上 dkms包。这一点很重要,因为它将提供工具和 Hook 文件,在内核更新时重建由 -dkms 软件包提供的内核驱动程序。
不要在 PKGBUILD 包含 linux-headers包 或任何其他的Linux头文件包。这些头文件已经作为 dkms包 的可选依赖,同时每个内核包都有自己的头文件包,因此在 -dkms 软件包包含这些头文件包是不必要的重复和限制的。
源代码构建位置
构建模块所需源代码需要放在(这是DKMS构建模块时使用的默认目录):
/usr/src/PACKAGE_NAME-PACKAGE_VERSION
在软件包目录,要包含一个 dkms.conf 配置文件,告诉 DKMS 如何编译。这个配置文件需要包含:
-
PACKAGE_NAME- 实际的项目名称,通常使用$_pkgname(见#包名)或$_pkgbase. -
PACKAGE_VERSION- 通常使用$pkgver.
打补丁
为内核模块源代码打补丁既可以直接在 PKGBUILD 中进行,也可以通过dkms.conf来进行。
If patching through dkms.conf, make sure to install the patches into /usr/src/PACKAGE_NAME-PACKAGE_VERSION/patches/ directory and to add a PATCH[number]=patch_filename for each patch to be applied, replacing number with a incremental value starting at 0. See dkms(8) § DKMS.CONF for more information.
.install 中模块的自动加载
模块的加载和卸载必须由用户自己来执行,设想一下,某个模块可能在加载的时候崩溃。
Also do not call dkms as it is automatically done via pacman hook provided by dkms包. Pacman 会自动执行 dkms install 和 dkms remove 钩子。
dkms install 会确保过程结束时执行 depmod。dkms install 依赖 dkms build (针对当前内核编译源码),build 依赖 dkms add (添加从 /var/lib/dkms/<package>/<version>/source 到 /usr/src/<package> 的链接)。
例子
这儿有个根据包名字和版本来对dkms.conf进行编辑,并安装模块黑名单配置文件的例子。
其它示例请参考官方软件仓库中的 -dkms 软件包和 AUR 中的 -dkms 包。
PKGBUILD
PKGBUILD
# Maintainer: foo <foo(at)example(dot)org>
# Contributor: bar <bar(at)example(dot)org>
_pkgbase=example
pkgname=example-dkms
pkgver=1
pkgrel=1
pkgdesc="The Example kernel modules (DKMS)"
arch=('x86_64')
url="https://www.example.org/"
license=('GPL2')
depends=('dkms')
conflicts=("${_pkgbase}")
install=${pkgname}.install
source=("${url}/files/tarball.tar.gz"
'dkms.conf'
"${pkgname}.conf"
'linux-3.14.patch')
md5sums=(use 'updpkgsums')
prepare() {
cd ${_pkgbase}-${pkgver}
# Patch
patch -p1 -i "${srcdir}"/linux-3.14.patch
}
package() {
# Copy dkms.conf
install -Dm644 dkms.conf "${pkgdir}"/usr/src/${_pkgbase}-${pkgver}/dkms.conf
# Set name and version
sed -e "s/@_PKGBASE@/${_pkgbase}/" \
-e "s/@PKGVER@/${pkgver}/" \
-i "${pkgdir}"/usr/src/${_pkgbase}-${pkgver}/dkms.conf
# Copy sources (including Makefile)
cp -r ${_pkgbase}/* "${pkgdir}"/usr/src/${_pkgbase}-${pkgver}/
# Blacklists conflicting module
install -Dm644 ${pkgname}.conf "${srcdir}/usr/lib/modprobe.d/${pkgname}.conf"
}
dkms.conf
dkms.conf
PACKAGE_NAME="@_PKGBASE@" PACKAGE_VERSION="@PKGVER@" MAKE[0]="make --uname_r=$kernelver" CLEAN="make clean" BUILT_MODULE_NAME[0]="@_PKGBASE@" DEST_MODULE_LOCATION[0]="/kernel/drivers/misc" AUTOINSTALL="yes"
.install
This example shows a message on post-install and post-upgrade that suggests unloading a conflicting module (example-conflicting-module) and then loading this package's module (example) for immediate use, when the user do not want to reboot the system at this moment.
example.install
post_install() {
cat<<EOF
Unload and load kernel modules:
rmmod example-conflicting-module
modprobe example
EOF
}
post_upgrade() {
post_install
}
Module blacklist conf
When it is known that example-conflicting-module conflicts with this package's example module, it should be blacklisted:
example-dkms.conf
blacklist example-conflicting-module