diff --git a/meta-isar/conf/local.conf.sample b/meta-isar/conf/local.conf.sample
index 77585ec..67a98d6 100644
--- a/meta-isar/conf/local.conf.sample
+++ b/meta-isar/conf/local.conf.sample
@@ -178,7 +178,10 @@ CONF_VERSION = "1"
 
 #
 # The default list of extra packages to be installed.
-IMAGE_INSTALL = "hello-isar example-raw example-module-${KERNEL_NAME} enable-fsck isar-exclude-docs samefile hello isar-disable-apt-cache cowsay example-prebuilt"
+IMAGE_INSTALL = "hello-isar example-raw example-module-${KERNEL_NAME} example-dkms-module-${KERNEL_NAME} enable-fsck isar-exclude-docs samefile hello isar-disable-apt-cache cowsay example-prebuilt"
+
+# v4l2loopback module does not build on armhf
+IMAGE_INSTALL_remove_armhf = "example-dkms-module-${KERNEL_NAME}"
 
 #
 # Enable cross-compilation support
diff --git a/meta-isar/recipes-kernel/example-dkms-module/example-dkms-module.bb b/meta-isar/recipes-kernel/example-dkms-module/example-dkms-module.bb
new file mode 100644
index 0000000..113f232
--- /dev/null
+++ b/meta-isar/recipes-kernel/example-dkms-module/example-dkms-module.bb
@@ -0,0 +1,14 @@
+# Example recipe for building the binary version of a DKMS module
+#
+# This software is a part of ISAR.
+# Copyright (c) Siemens AG, 2021
+#
+# SPDX-License-Identifier: MIT
+
+inherit dkms-module
+
+PN .= "-${KERNEL_NAME}"
+
+#package name (without -dkms. E.g "v4l2loopback" for package "v4l2loopback-dkms")
+DKMS_PACKAGE_NAME = "v4l2loopback"
+AUTOLOAD += "v4l2loopback"
diff --git a/meta/classes/dkms-module.bbclass b/meta/classes/dkms-module.bbclass
new file mode 100644
index 0000000..283bff7
--- /dev/null
+++ b/meta/classes/dkms-module.bbclass
@@ -0,0 +1,76 @@
+# This software is a part of ISAR.
+# Copyright (C) 2021 Siemens AG
+#
+# SPDX-License-Identifier: MIT
+
+inherit dpkg-raw
+
+# Build and install a kernel module that is available via a debian DKMS package.
+# As it is hard to directly build and install the package we create and distribute
+# a meta package that is independent of the kernel version.
+# In that package, we depend on the versioned prebuild kernel module package.
+#
+# To build the dkms module, we add two tasks and directly
+# use dkms to build the debian package containing the binary module
+# Then we just copy the binary-module debian package to the workdir,
+# so ISAR's do_deploy_deb picks it up.
+
+#package name (without -dkms. E.g "dpdk-kmods" for package "dpdk-kmods-dkms")
+DKMS_PACKAGE_NAME ?= ""
+AUTOLOAD ?= ""
+
+DESCRIPTION ?= "Kernel module from DKMS package for ${PN}"
+DEPENDS += "linux-headers-${KERNEL_NAME}"
+DEBIAN_DEPENDS += "${DKMS_PACKAGE_NAME}-modules,"
+DEBIAN_BUILD_DEPENDS += "linux-headers-${KERNEL_NAME}, ${DKMS_PACKAGE_NAME}-dkms,"
+
+ISAR_CROSS_COMPILE = "0"
+
+# install configuration to auto-load the modules in ${AUTOLOAD}
+do_install() {
+    # auto load the module
+    install -v -d ${D}/etc/modules-load.d
+    for module in "${AUTOLOAD}"; do
+        echo $module > ${D}/etc/modules-load.d/${PN}.conf
+    done
+}
+
+# build the binary kernel module and package as debian package (versioned)
+do_module_build() {
+    # we have to find out the module version, e.g. dpdk-kmods/0~20201113+git -k 5.10.0-3-rt-amd64/x86_64
+    REVISION=$(find ${BUILDCHROOT_DIR}/usr/src/${DKMS_PACKAGE_NAME}-* -type d -exec basename {} + | sed 's/${DKMS_PACKAGE_NAME}-//g')
+    DKMS_ARCH=$(echo ${DISTRO_ARCH} | sed 's/amd64/x86_64/g' | sed 's/arm64/aarch64/g' | sed 's/i386/i686/g')
+    if ! dpkg -s --root=${BUILDCHROOT_DIR} linux-headers-${KERNEL_NAME} | grep "Depends:.*linux-headers"; then
+        # custom kernels directly place their files in linux-image-KERNEL-NAME, instead
+        # of using a meta package + a versioned package with the resources
+        # The prebuild DKMS binary package depends on the versioned kernel package,
+        # but that is not available on custom kernels. Hence, we just remove the dependency.
+        bbnote "Building ${DKMS_PACKAGE_NAME} for custom kernel ${KERNEL_NAME}"
+        cp ${BUILDCHROOT_DIR}/etc/dkms/template-dkms-mkbmdeb/debian/control ${WORKDIR}/control.dkms.orig
+        sudo sed -i 's/, linux-image-KERNEL_VERSION//' ${BUILDCHROOT_DIR}/etc/dkms/template-dkms-mkbmdeb/debian/control
+	KERNEL_FULLNAME=${KERNEL_NAME}
+    else
+	KERNEL_FULLNAME=$(dpkg -s --root=${BUILDCHROOT_DIR} linux-headers-${KERNEL_NAME} | grep "Depends:.*linux-headers" | sed 's/Depends: linux-headers-//g')
+	bbnote "Building for kernel $KERNEL_FULLNAME"
+    fi
+    # build the module for all installed kernels (should be just one)
+    sudo -E chroot ${BUILDCHROOT_DIR} dkms build ${DKMS_PACKAGE_NAME}/${REVISION} -k ${KERNEL_FULLNAME}/${DKMS_ARCH}
+    sudo -E chroot ${BUILDCHROOT_DIR} dkms mkbmdeb ${DKMS_PACKAGE_NAME}/${REVISION} -k ${KERNEL_FULLNAME}/${DKMS_ARCH}
+    DKMS_PACKAGE_VERSIONED=$(find ${BUILDCHROOT_DIR}/var/lib/dkms/${DKMS_PACKAGE_NAME}/ -name "${DKMS_PACKAGE_NAME}-modules*.deb" -exec dpkg -I {} + | grep "Package:" | awk '{print $2}')
+    if [ -z "$DKMS_PACKAGE_VERSIONED" ]; then
+        bberror "No prebuild dkms module found"
+        exit 1
+    fi
+    # restore dkms template (if any)
+    cp ${WORKDIR}/control.dkms.orig ${BUILDCHROOT_DIR}/etc/dkms/template-dkms-mkbmdeb/debian/control || true
+}
+
+# simply copy our module from the build tree to the expected output location
+# of this recipe. Then, do_deploy_dep finds it and adds it to the
+# debian isar repo
+do_module_deploy() {
+    cp ${BUILDCHROOT_DIR}/var/lib/dkms/${DKMS_PACKAGE_NAME}/*/bmdeb/*.deb ${S}/../
+}
+
+addtask module_build after do_install_builddeps before do_dpkg_build
+addtask module_deploy after do_module_build before do_deploy_deb
diff --git a/scripts/ci_build.sh b/scripts/ci_build.sh
index adc22e4..1426569 100755
--- a/scripts/ci_build.sh
+++ b/scripts/ci_build.sh
@@ -259,6 +259,7 @@ mv ${BUILDDIR}/tmp/deploy/images/qemuamd64/isar-image-base-debian-stretch-qemuam
 
 # Finalize with containerized images, since they remove some not-needed packages from the local.conf
 sed -i -e 's/\(IMAGE_INSTALL = .*\) example-module-${KERNEL_NAME}\(.*\)/\1\2/g' conf/local.conf
+sed -i -e 's/\(IMAGE_INSTALL = .*\) example-dkms-module-${KERNEL_NAME}\(.*\)/\1\2/g' conf/local.conf
 sed -i -e 's/\(IMAGE_INSTALL = .*\) enable-fsck\(.*\)/\1\2/g' conf/local.conf
 bitbake $BB_ARGS $TARGETS_CONTAINERS
 while [ -e bitbake.sock ]; do sleep 1; done
