# 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.

Since the introduction of Pacman#Hooks, the rebuilt of the modules is handled automatically when a kernel is upgraded. See also #Upgrades.

## Installation

Install the dkms package and the headers for your kernel (for the standard kernel this would be linux-headers).

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:
  - nvidia-dkms
  - nvidia-304xx-dkms
  - nvidia-173xx-dkmsAUR
  - nvidia-96xx-dkmsAUR
  - nvidia-grsec-dkmsAUR
- VirtualBox:
  - virtualbox-host-dkms
  - virtualbox-guest-dkms
- VMware, section VMware#Using DKMS to manage the modules

## Upgrades

Though the rebuilt of the DKMS modules is usually seamless during a kernel upgrade, it may still happen that the rebuilt fails. You should pay extra attention to pacman's output! This applies in particular if the system relies on the DKMS module to boot successfully and/or if you use DKMS with a custom kernel not in the Official repositories.

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

### List modules

To list the current status of modules, versions and kernels within the tree:

    # dkms status

### Rebuild modules

Rebuild all modules for the currently running kernel:

    # dkms autoinstall

or for a specific kernel:

    # dkms autoinstall -k 3.16.4-1-ARCH

To build a specific module for the currently running kernel:

    # dkms install -m nvidia -v 334.21

or simply:

    # dkms install nvidia/334.21

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 package 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

The factual accuracy of this article or section is disputed.

Reason: Those actions where moved to pacman hooks AFAIK. (Discuss in Talk:Dynamic Kernel Module Support#)

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
    }

Tip: To keep DKMS packages closer to their non-DKMS counterparts: avoid cluttering up package files with DKMS-specific stuff (e.g. version numbers that need updating).

## See also

- Linux Journal: Exploring Dynamic Kernel Module Support

Category:

- Kernel

Hidden category:

- Pages or sections flagged with Template:Accuracy