Translation(s): English - Русский


This page describes how to create Debian packages containing Linux kernel modules sources to be built automatically upon installation using DKMS.


Introduction

As documented in its man page, the DKMS ("Dynamic Kernel Module Support") framework allows kernel modules to be dynamically built for each kernel on users' systems in a simplified and organized fashion. Such building of kernel modules happens "on the fly" (mainly at a given module package installation time) on users' machines, rather than on the Debian infrastructure. DKMS "binary" module packages usually contain only their module sources and depend on dkms package. See ddcci-dkms as an example.

Using DKMS vs binary module packages has the following advantages:


Package Configuration

DKMS config

For each "binary" DKMS package, create a file named "package-name.dkms" in debian folder, for example debian/mydriver-kernel-dkms.dkms. If there's only 1 binary package, the file may be named simply debian/dkms. These files should either follow the format documented in the dkms man page or contain a path (relative to the package's root) to a relevant upstream DKMS config file. A typical example:

PACKAGE_NAME="mydriver"
PACKAGE_VERSION="1"
AUTOINSTALL=yes

BUILT_MODULE_NAME[0]="$PACKAGE_NAME"
DEST_MODULE_LOCATION[0]=/updates

MAKE[0]="make -C ${kernel_source_dir} M=${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build"
CLEAN="make -C ${kernel_source_dir} M=${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build clean"

Notes:


Module Makefile

As rules to build or clean module binaries are provided by the kernel Makefile infrastructure, a Makefile for a DKMS module usually only needs to append its modules' object filenames to obj-m var, for example:

obj-m += mydriver.o

If your module's source is divided into several files (for example mydriver-dma-helpers.c and mydriver-main.c), you need to specify, what object-files your module is composed of, by defining a variable named ${MODULE_NAME}-objs. For example:

obj-m += mydriver.o
mydriver-objs := mydriver-dma-helpers.o mydriver-main.o

If you need some special CC flags, append them to ccflags-y var:

ccflags-y += -D__MYDRIVER_USE_DMA

See the related kernel Makefile docs.

An upstream Makefile may try to autodetect and override values for -C and M, which sometimes does not work as intended in a DKMS context. In such case the Makefile may need to be patched accordingly.


rules

In a generic case, all that is necessary is to add --with dkms to dh arguments: (ToDo: there must be no space before #!/usr/bin/make -f but it is then inproperly rendered by this wiki)

 #!/usr/bin/make -f

%:
        dh $@ --with dkms

This will trigger dh_dkms to generate postinst and prerm for each binary package for which a DKMS config file exists.


control


install

Each "binary" DKMS package's source files and Makefile must be installed in /usr/src/${PACKAGE_NAME}-${PACKAGE_VERSION}/ folder, where PACKAGE_NAME and PACKAGE_VERSION values are the ones from the corresponding DKMS config. For example if kernel module files and Makefile for mydriver defined in the config above are located in kernel subfolder of the source package, its install file may look like this:

kernel/* /usr/src/mydriver-1/


Common problems

dpkg-buildpackage builds modules instead of packaging sources

This happens because the module's Makefile (or its parent) is in the root folder of the source package, so dh_auto_clean, dh_auto_build and dh_auto_install pick it up. Use override_dh_auto_* rules to fix it.


Missing generated/autoconf.h when building modules

Symptoms:

Module build fails and make.log contains a message similar to the below:

/usr/src/linux-headers-6.12.57+deb13-common/include/linux/kconfig.h:5:10: fatal error: generated/autoconf.h: No such file or directory

Possible reasons and resolutions:

This sometimes randomly happens across various distros (for example Manjaro, Arch). The exact reasons are not clearly explained anywhere, but purging a given module package, then purging a given kernel version headers packages, then removing manually any leftovers of both and finally reinstalling, usually solves the problem.


Related resources

Original discussion: <1255800860.2488.616.camel@localhost>

Debian links:

External guides:


Help wanted

ToDo: other documentation that might need changes:


CategoryKernel | CategoryPackaging