DKMS 软件包指南
32 位 – CLR – CMake – 交叉编译 – DKMS – Eclipse – Electron – 字体 – Free Pascal – GNOME – Go – Haskell – Java – KDE – 内核模块 – Lisp – Meson – MinGW – Node.js – 非自由软件 – OCaml – Perl – PHP – Python – R – Ruby – Rust - 安全 – Shell – VCS – Web 应用 – Wine
这里是在创建 DKMS 软件包时需要遵循的一些指南。
软件包名称
DKMS 软件包的命名方式是在原始软件包名称后附加 "-dkms"。
变量 $_pkgname 通常在 $pkgname 之后使用,以描述不包含 "-dkms" 后缀的软件包名称 (例如 _pkgname="${pkgname%-*}")。
依赖关系
将 dkms 添加到 depends 数组中。这非常重要,因为它将提供工具和钩子,以便在内核更新时重建 -dkms 软件包提供的内核驱动程序。
不要在 PKGBUILD 中包含 linux-headers – 或任何其他 Linux 头文件软件包。这些头文件已经列为 dkms 的可选依赖项,并且每个内核软件包都有自己的头文件软件包,因此在 -dkms 软件包中包含头文件软件包依赖项既是不必要的冗余,也是限制性的。
源代码位置
软件包应将内核模块的源文件安装到
/usr/src/PACKAGE_NAME-PACKAGE_VERSION
其中 PACKAGE_NAME 和 PACKAGE_VERSION 是内核模块的名称和版本。
强烈建议将 PACKAGE_NAME 设置为 $_pkgname 的值(参见 #软件包名称),并将 PACKAGE_VERSION 设置为 $pkgver。
打补丁
源代码可以直接在 PKGBUILD 中打补丁,也可以通过 dkms.conf 打补丁。
如果通过 dkms.conf 打补丁,请确保将补丁安装到 /usr/src/PACKAGE_NAME-PACKAGE_VERSION/patches/ 目录中,并为要应用的每个补丁添加一个 PATCH[number]=patch_filename,将 number 替换为从 0 开始的递增值。有关更多信息,请参见 dkms(8) § DKMS.CONF。
在 .install 文件中自动加载模块
不要使用 .install 文件来加载或卸载模块。将其留给用户,因为模块在加载时可能会崩溃。
同样不要调用 dkms,因为它会通过 dkms 提供的 pacman 钩子 自动完成。此钩子运行 dkms install 和 dkms remove,软件包维护者无需手动操作。
dkms install 确保在其过程结束时调用 depmod。dkms install 依赖于 dkms build(针对当前内核构建源代码),而 dkms build 本身又依赖于 dkms add(添加从 /var/lib/dkms/PACKAGE_NAME/PACKAGE_VERSION/source 到 /usr/src/PACKAGE_NAME-PACKAGE_VERSION 的符号链接)。示例
这是一个示例软件包,它根据软件包名称和版本编辑 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 "${pkgdir}/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
此示例显示了安装后和升级后的一条消息,建议卸载冲突模块 (example-conflicting-module),然后加载此软件包的模块 (example) 以立即使用,当用户此时不想重启系统时。
example.install
post_install() {
cat<<EOF
Unload and load kernel modules:
rmmod example-conflicting-module
modprobe example
EOF
}
post_upgrade() {
post_install
}
模块黑名单配置
当已知 example-conflicting-module 与此软件包的 example 模块冲突时,应将其列入黑名单
example-dkms.conf
blacklist example-conflicting-module