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