Difference between revisions of "Dynamic Kernel Module Support"

From ArchWiki
Jump to: navigation, search
m (italics)
m (shorten)
Line 28: Line 28:
 
  # dkms install nvidia/334.21 --all
 
  # dkms install nvidia/334.21 --all
  
{{Tip|{{ic|Tab}} completion for module and kernel versions is available.}}
+
{{Tip|{{ic|Tab}} completion is available.}}
  
 
== Submitting my first DKMS package ==
 
== Submitting my first DKMS package ==

Revision as of 15:32, 2 April 2014

Dynamic Kernel Module Support allows one to compile and install kernel modules without recompiling the entire kernel.

Installation

Practically all packages that make use of DKMS are located in the AUR (excluding virtualbox modules). Some of these include:

Enabling on boot

To have modules automatically rebuilt after each kernel upgrade, enable the dkms service:

# systemctl enable dkms
Tip: If a userspace component (such as NVIDIA or Catalyst X driver) is started before the DKMS module is rebuilt, you often need to reboot (or restart the component).

Usage

To rebuild all DKMS modules for a specific kernel (e.g. after an upgrade), use:

# dkms autoinstall -k 3.13.6-1-ARCH

Building a specific module is also possible (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, use:

# dkms install nvidia/334.21 --all
Tip: Tab completion is available.

Submitting my first DKMS package

Here are some guidelines to follow for creating and submitting your first DKMS package to the AUR.

Package name

DKMS packages are named by appending "-dkms" to their names. Those beginning with "dkms-" should be renamed to follow this format.

A variable for $pkgname minus the "-dkms" suffix ($_pkgname or $_pkgbase) is usually helpful in keeping the package in sync with the non-DKMS version.

Dependencies

Dependencies can be taken straight from the non-DKMS version. dkms should then be added and linux-headers removed (dkms already lists it as optional).

Sources location

Sources should go into /usr/src/PACKAGE_NAME-PACKAGE_VERSION/, which is the default path for DKMS commands. PACKAGE_NAME and PACKAGE_VERSION are both set in dkms.conf.

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

For simplicity it can be preferable to keep the DKMS PKGBUILD as close to the non-DKMS version as possible and apply patches in the PKGBUILD.

Loading/reloading modules automatically in .install?

Loading and unloading modules should be left to the user.

Consider a case where a module crashes when loaded. That could end up halting the entire system, which is pretty severe.

Namcap output

We have written this great tool called Namcap, which attempts to check for common mistakes and non-standard decisions in your packages. It's a good practice to have it run at least once on any package, however, it isn't perfect and 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 files

Here's 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 we can now use dkms install (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).

Disadvantages

DKMS breaks the Pacman database

The problem is that the resulting modules don't belong to the package anymore, so Pacman can't track them.

Support could be added through hooks (see: FS#2985).

See Also