Dynamic Kernel Module Support
From Wikipedia:
- Dynamic Kernel Module Support (DKMS) is a program/framework that enables generating Linux kernel modules whose sources generally reside outside the kernel source tree. The concept is to have DKMS modules automatically rebuilt when a new kernel is installed.
Effects
The positive effect of using DKMS is that modules are often able to be rebuilt when the kernel is upgrading. This means that a user does not have to wait for a company, project, or package maintainer to release a new version of the module.
The negative effect of using DKMS is that DKMS breaks the Pacman database. The problem is that the resulting modules do not belong to the package anymore, so Pacman cannot track them. Theoretically though, support could be added through hooks (see: FS#2985).
Installation
Install the dkms package.
Enable the dkms
systemd service to have DKMS modules rebuilt automatically upon reboot after a kernel upgrade.
A good number of modules that lie outside the kernel source tree have a DKMS variant; a few are hosted in the official repositories, most are found in the AUR. Listed below are a few of the software packages that have a DKMS variant with additional links to dedicated sections where available:
- AMD Catalyst: catalyst-dkmsAUR
- NVIDIA:
- VirtualBox, section VirtualBox#Hosts running a custom kernel
- VMware, section VMware#Using DKMS to manage the modules
Upgrades
Though modules are able to be rebuilt usually through a good number of kernel upgrades, at times the package will need to get upgraded. To deal with changes in the kernel, fix bugs, or add necessary features consider upgrading the DKMS package before rebooting.
Usage
Usage for invoking DKMS manually.
Tab-completion is available by doing:
# source /usr/share/bash-completion/completions/dkms
Rebuild modules
Rebuild all modules:
# dkms autoinstall -k $(uname -r)
or for a specific kernel:
# dkms autoinstall -k 3.16.4-1-ARCH
To build a specific module (e.g. for current kernel):
# dkms install -m nvidia -v 334.21 -k $(uname -r)
or simply:
# dkms install nvidia/334.21 -k $(uname -r)
To build a module for all kernels:
# dkms install nvidia/334.21 --all
Remove modules
To remove a module (old ones are not automatically removed):
# dkms remove -m nvidia -v 331.49 --all
or simply:
# dkms remove nvidia/331.49 --all
If the package dkms is removed the information regarding previous module build files is lost. If this is the case, go through /usr/lib/modules/KERNELVERSION-ARCH
and delete or files and directories no longer in use.
DKMS package creation
Here are some guidelines to follow when creating a DKMS package.
Package name
DKMS packages are named by appending "-dkms" to the original package name.
The variable $_pkgname
is often used below $pkgname
to describe the package name minus the "-dkms" suffix (e.g. _pkgname=${pkgname%-*}
). This is useful to help keep similarities between the original package PKGBUILD and the DKMS variant.
Dependencies
Dependencies should be inherited from the original version with dkms added and linux-headers removed (as it is listed by the dkms pacakge as optional).
Build source location
Build sources should go into (this is the default build directory for DKMS):
/usr/src/PACKAGE_NAME-PACKAGE_VERSION
In the package directory, a DKMS configuration tells DKMS how to build the module (dkms.conf
), including the variables PACKAGE_NAME
and PACKAGE_VERSION
.
-
PACKAGE_NAME
- the actual project name (usually$_pkgname
or$_pkgbase
). -
PACKAGE_VERSION
- by convention this should also be the$pkgver
.
Patching
The sources can be patched either directly in the PKGBUILD or through dkms.conf
.
Module loading automatically in .install
Loading and unloading modules should be left to the user. Consider the possibility a module may crash when loaded.
namcap output
namcap (which attempts to check for common mistakes and non-standard decisions in a package) is good practice to use at least once on any package; however, it has not yet been updated for DKMS specific guidelines.
For example, DKMS uses /usr/src/
by default, but Namcap believes this to be a non-standard directory, a little contrary to its reference.
Example
Here is an example package that edits dkms.conf
according to the package name and version.
PKGBUILD
PKGBUILD
# Maintainer: foo <foo(at)gmail(dot)com> # Contributor: bar <bar(at)gmai(dot)com> _pkgbase=amazing pkgname=amazing-dkms pkgver=1 pkgrel=1 pkgdesc="The Amazing kernel modules (DKMS)" arch=('i686' 'x86_64') url="https://www.amazing.com/" license=('GPL2') depends=('dkms') conflicts=("${_pkgbase}") install=${pkgname}.install source=("${url}/files/tarball.tar.gz" 'dkms.conf' 'linux-3.14.patch') md5sums=(use 'updpkgsums') build() { cd ${_pkgbase}-${pkgver} # Patch patch -p1 -i "${srcdir}"/linux-3.14.patch # Build msg2 "Starting ./configure..." ./configure msg2 "Starting make..." make } package() { # Install msg2 "Starting make install..." make DESTDIR="${pkgdir}" install # 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}/ }
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
Instead of depmod
now dkms install
can be used (it depends on dkms build
, which depends on dkms add
):
amazing-dkms.install
# old version (without -$pkgrel): ${1%%-*} # new version (without -$pkgrel): ${2%%-*} post_install() { dkms install amazing/${1%%-*} } pre_upgrade() { pre_remove ${2%%-*} } post_upgrade() { post_install ${1%%-*} } pre_remove() { dkms remove amazing/${1%%-*} --all }