How to: Build dynamic kernel module support (DKMS)

Background information

DKMS (Dynamic Kernel Module Support) is a framework that enables generating Linux kernel modules whose source generally reside outside the kernel source tree. The concept is to have DKMS modules automatically rebuilt when a new kernel is installed.

This article describes two alternative ways to build and install a DKMS module:

  • using DKMS tool directly

  • using e3

Build and install DKMS module with DKMS tool

Prepare a DKMS configure file

To build and install a third-party kernel module as a DKMS module, a dkms.conf file which describes the module source to the DKMS system is required. It usually looks like the following:

PACKAGE_NAME=myModuleName
PACKAGE_VERSION=myModuleVersion
BUILT_MODULE_NAME[0]=myModuleName
AUTOINSTALL=yes

Add this dkms.conf file to your kernel module source, and copy the DKMS source which contains the kernel module and this dkms.conf file into /usr/src/myModuleName-myModuleVersion/

Build and install the module

When the DKMS source and configuration file is ready, launch the DKMS tool to build and install the built DKMS module as:

$ dkms build -m myModuleName -v myModuleVersion

This will, first, copy the DKMS source from the above location to the system’s DKMS build location, and then, build the DKMS module in DKMS build location of the system. After a successful build, install it into the DKMS tree with the following command:

$ dkms install -m myModuleName -v myModuleVersion

This will install the built module into the system’s DKMS tree.

Build and install DKMS module with e3

Create a DKMS configure file

Please see Build and install DKMS module with DKMS tool about how to create DKMS configuration file. The dkms_add rule in the following file generates DKMS configuration file from a template file with macro substitution.

KMOD_NAME := mrf

.PHONY: dkms_add

dkms_add: conf
    $(MSI) -M name="$(E3_MODULE_NAME)" -M  version="$(E3_MODULE_VERSION)" -M kmod_name="$(KMOD_NAME)" $(TOP)/dkms/dkms_with_msi.conf.in > $(TOP)/dkms/dkms_with_msi.conf
    $(QUIET) cat $(TOP)/dkms/dkms_with_msi.conf $(TOP)/dkms/dkms_without_msi.conf > $(TOP)/dkms/dkms.conf
    $(QUIET) install -m 644 $(TOP)/dkms/dkms.conf  $(E3_KMOD_SRC_PATH)
    $(SUDO) install -d /usr/src/$(E3_MODULE_NAME)-$(E3_MODULE_VERSION)
    $(SUDO) cp -r $(TOP)/$(E3_KMOD_SRC_PATH)/* /usr/src/$(E3_MODULE_NAME)-$(E3_MODULE_VERSION)/
    $(SUDO) $(DKMS) add $(DKMS_ARGS)

.PHONY: setup

setup:
    $(QUIET) echo "KERNEL==uio*, ATTR{name}==mrf-pci, MODE=0666" | $(SUDO) tee  /etc/udev/rules.d/99-$(KMOD_NAME).rules
    $(QUIET) $(SUDO) /bin/udevadm control --reload-rules
    $(QUIET) $(SUDO) /bin/udevadm trigger
    $(QUIET) echo $(KMOD_NAME) | $(SUDO) tee /etc/modules-load.d/$(KMOD_NAME).conf
    $(QUIET) $(SUDO) depmod --quick
    $(QUIET) $(SUDO) modprobe -rv $(KMOD_NAME)
    $(QUIET) $(SUDO) modprobe -v $(KMOD_NAME)
    $(QUIET) echo ""
    $(QUIET) echo ""
    $(QUIET) echo "It is OK to see \"E3/RULES_DKMS:37: recipe for target 'setup' failed\""
    $(QUIET) echo "---------------------------------------------------------------------"
    $(QUIET) -ls -l /dev/uio* 2>/dev/null
    $(QUIET) echo "---------------------------------------------------------------------"

.PHONY: setup_clean

setup_clean:
    $(QUIET) $(SUDO) modprobe -rv $(KMOD_NAME)
    $(SUDO) rm -f /etc/modules-load.d/$(KMOD_NAME).conf
    $(SUDO) rm -f /etc/udev/rules.d/99-$(KMOD_NAME).rules

The rule dkms_add processes template DKMS configuration file with macro substitutions, and generates a dkms.conf file. It will install the generated file together with the source into the host file system. The generated dkms.conf file includes E3_MODULE_NAME, E3_MODULE_VERSION and kernel module name.

Steps to build and install a DKMS module with e3

# prepare module source and DKMS configuration file
$ cd /wrapper/top/directory
$ make dkms_build
$ make dkms_install
$ make setup

Note, when using e3 to build and install DKMS module, myModuleName must be the same as the corresponding e3 wrapper module’s name. And myModuleVersion must be the same as the corresponding e3 wrapper module’s version.

The following e3 wrappers use DKMS kernel modules and can be used as a reference: