DKMS(8)
๐ DKMS ๐
okay bestie, welcome to the dkms (that's Dynamic Kernel Module Support) manual page โ it lives in the System Manager's Manual section (8), and it's about to be your new hyperfixation. grab a boba, we're doing this ๐งโจ
โจ SYNOPSIS โจ
dkms [action] [options] [module/module-version] [/path/to/source-tree]
[/path/to/tarball.tar] [/path/to/driver.rpm]
that's the whole vibe check right there โ action, options, a module, and maybe a path to something ๐ซถ
๐ธ DESCRIPTION ๐ธ
so basically, dkms is a framework that lets kernel modules get dynamically built for every kernel on your system โ in a simplified and organized fashion. no cap. it's the organized bestie of kernel module management, and honestly? iconic. ๐
๐ ACTIONS ๐
each action is its own little main character moment. here we go ๐
add
add [module/module-version|/path/to/source-tree|/path/to/tarball.tar]
- this one adds a module/module-version combo to the tree so it can be built and installed later ๐
- if you pass
module/module-version,-m module/module-version, or-m module -v module-versionas options, then this command needs source sitting in/usr/src/<module>-<module-version>/plus a properly formatteddkms.conffile. both. it's a package deal fr fr - if you pass
/path/to/source-treeas an option, and that source-tree contains adkms.conffile, it'll copy/path/to/source-treeover to/usr/src/module-module-versionโจ - if you pass
/path/to/tarball.tar, this command behaves like theldtarballcommand. plot twist, but make it convenient ๐ฆ
remove
remove [module/module-version] [-k kernel/arch] [--all]
- removes a
module/versionor amodule/version/kernel/archcombination from the tree ๐งน - if the module is currently installed, it uninstalls it first, and if applicable, replaces it with its
original_module. so polite of it honestly - use the
--alloption if you want to remove all instances for every kernel at once. go big or go home ๐
build
build [module/module-version] [-k kernel/arch] [--force]
- builds the specified module/version combo for the specified kernel/arch ๐จ
- no
-koption? then it builds for the currently running kernel and arch. default behavior, love that for you - all builds happen in the directory
/var/lib/dkms/<module>/<module-version>/build/โ that's the build zone ๐ - if the module/module-version combo hasn't been added yet,
dkmswill try to add it โ which meansbuildcan take the same arguments thataddcan. multitasking queen ๐ - if the module is already built, it will not be rebuilt again by default. if you want to force it, that's what
--forceis for โก
unbuild
unbuild [module/module-version] [-k kernel/arch] [--all]
- undoes the build for a
module/versionormodule/version/kernel/archcombination from the tree โฉ๏ธ - if the module is currently installed, it uninstalls it first, and if applicable, replaces it with its
original_module. then, finally, all binary kernel modules get removed ๐ซก - use
--allto remove all instances for every kernel at once. same energy asremove --all, different day ๐
install
install [module/module-version] [-k kernel/arch] [--force]
[/path/to/driver.rpm]
- installs a built module/version combo onto the kernel it was built for ๐
- no kernel option? it assumes the currently running kernel. assumptions are made, respectfully
- module not built yet?
dkmswill try to build it. module not added yet?dkmswill try to add it. and in both of those cases, theinstallcommand can take the same arguments as thebuildoraddcommands. it's giving "we contain multitudes" โจ - already installed? it will not be reinstalled again by default โ
--forceoverrides that ๐จ - if a different version of the module is installed for that kernel, it gets uninstalled first, so that none of its kernel modules are left behind. no crumbs. periodt ๐งน
- if you pass a
.rpmfile,dkmswill try to install that file withrpm -Uvh, and it will perform anautoinstallaction to make sure everything is built for your kernel โ but only if the RPM installed successfully โ
uninstall
uninstall [module/module-version] [-k kernel/arch] [--all]
- uninstalls an installed module/module-version combo from the kernel/arch you passed in the
-koption โ or the current kernel if you didn't pass-k๐ - use
--allto uninstall all instances for every kernel at once. chaos mode but sanctioned - after uninstall completes, the driver is left in the built state ๐๏ธ
- so if you want to completely remove a driver, you need to use the
removeaction instead. uninstall is not the same as remove, iykyk ๐
match
match [--templatekernel kernel/arch] [-k kernel/arch]
matchinstalls modules onto the specified kernel by peeking at the configuration of the specifiedtemplatekernel๐- every module that's installed on the
templatekernelwithindkmsgets installed onto that specified kernel too. copy-paste but make it official ๐ฆ
mktarball
mktarball [module/module-version] [-k kernel/arch]
[--archive /path/to/tarball.tar] [--source-only] [--binaries-only]
- creates a tarball archive for the specified module/version, containing all the files in the DKMS tree for that module/version combination ๐ฆ
- this includes the source and any built modules for kernels in the tree (as specified) ๐
- otherwise, you can specify a singular kernel to archive, or multiple kernels to archive like
-k kernel1/arch1 -k kernel2/arch2โจ - optionally, use
--archiveto specify the file you want to save this tarball to ๐ - you can also use
--binaries-onlyif you want the resultant tarball to not include the module source ๐ซ - likewise,
--source-onlymeans no prebuilt binaries get included in the tarball ๐ - in general,
mktarballis great for systems management purposes โ you can build your driver on just one system, then useldtarballon all your other systems to get the same built modules loaded without waiting for anything to compile. build once, deploy everywhere, the dream fr fr ๐ญ๐ฅ
ldtarball
ldtarball [/path/to/tarball.tar] [--force]
- takes a tarball made from the
mktarballcommand and loads it into your DKMS tree ๐ฅ - this leaves any newly added modules in the built state, and then
dkms installshould be called to install any of them ๐ซถ - if files already exist where
ldtarballis trying to place them, it will warn and not copy over them โ ๏ธ - use
--forceto override that ๐ฅ
status
status [module/module-version] [-k kernel/arch]
- returns the current status of modules, versions and kernels within the tree โ plus whether they've been added, built, or installed ๐
- status can be shown for just a certain module, a certain kernel, a module/version combination, or a module/version/kernel combination. so many options, so little time ๐
- if the source directory, or the symbolic link
sourcepointing to it, is missing, the status of the module/version combination gets displayed as'broken'๐ - in that case,
dkmswill not perform any other action on that particular module/version combination. manual intervention is required, bestie โ no autopilot here ๐จ - if only the symbolic link
sourceis missing, theaddaction may be used to re-add the module/version combination todkms๐ฉน
autoinstall
autoinstall
- attempts to install the latest revision of all modules that have been installed for other kernel revisions ๐
- the DKMS autoinstaller service is a stub that uses this action to perform its work. it's a little helper doing heavy lifting, we love a supportive icon ๐ซถ
generate_mok
generate_mok
- a command to be issued standalone to generate Secure Boot keys ๐
- only required if you need to manipulate the keys beforehand โ otherwise the keys are automatically generated on the first build attempt of a DKMS module โจ
- no additional arguments are parsed. it takes zero notes, zero flags, zero nonsense ๐
still with me? good, because there's more coming ๐โจ
โจ OPTIONS โจ
Okay bestie, this is the big one โ all the little switches and dials you can turn when you run dkms. Every single one is here, no skips, no cap. ๐
-m <module>/<module-version>โ The name of the module and the module version you wanna operate on. The-mpart of this option is optional and can be omitted in virtually all circumstances. โจ-v <module-version>โ The version of the module to execute the specified action upon. You only have to pass this if you gave a-moption that didn't have its own<module-version>component. ๐-k <kernel-version>/<arch>โ The kernel and arch to perform the action on. You can stack multiple kernel version/arch pairs by repeating-kwith a different kernel version and arch. However, not all actions support multiple kernel versions โ it will error out in that case. The arch part can be omitted, and DKMS will assume you want the arch of the currently running system. ๐ฆ-a,--archโ The system architecture to perform the action upon. It's optional if you pass it as part of the-koption. If you don't specify it, DKMS assumes the arch of the currently running system (uname -m). You can pass multiple arch parameters on the same command line by repeating-awith a different architecture name. When multiple architectures are specified, there must be a 1:1 relationship between-karguments and-aarguments. DKMS will assume the first-aaligns with the first-k, the second with the second, and so on. For example, if you were to specify:
-k kernel1 -k kernel2 -a i386 -k kernel3 -a i686 -a x86_64
DKMS would process this as: kernel1-i386, kernel2-i686, kernel3-x86_64. ๐ฅ
-q,--quietโ Quiet. Shhh. ๐คซ-V,--versionโ Prints the currently installed version ofdkmsand exits. ๐-h,--helpโ ๐ Help flag, bestie.-c <dkms.conf-location>โ The location of thedkms.conffile. This is needed for theaddaction, and if not specified, it is assumed to be located in/usr/src/<module>-<module-version>/. See below for more information on the format ofdkms.conf. ๐--config <kernel-include/config/auto.conf-location>โ During a build, this option specifies an alternate location for the kernelinclude/config/auto.confconfiguration file which contains that kernel configuration. Normally,dkmsis able to derive the location of the configuration file from the filesystem, but if there's a problem in the detection, you'll need to telldkmswhere the necessaryinclude/config/auto.conffile (or the legacy.configfile) can be found so your kernel can be properly prepared for the module build. ๐ธ--archive <tarball-location>โ Used during aldtarballaction to specify the location of the tarball you wish to load into your DKMS tree. You only have to specify the--archivepart of this option if<tarball-location>does not already exist as a file. ๐--templatekernel <kernel-version>โ Required for the action:match. Match will look at the templatekernel specified and install all of the same module/version combinations on the other kernel. ๐ซ--forceโ Can be used in conjunction withbuild,installandldtarballto force copying over existing files. ๐ค--force-version-overrideโ Skips the checks whether the version of the module which is going to be installed is newer than the already installed version. โก--binaries-onlyโ Can be used withmktarballto create a DKMS tarball which does not contain the source for the module within it. This helps reduce the tarball size if you know the system this tarball will be loaded upon already has the source installed. In order to load a tarball made as binaries-only, you must have the module source in that system's DKMS tree. If you don't, DKMS will refuse to load a binaries-only tarball. ๐ซ--source-onlyโ Can be used withmktarballwhen you don't want the tarball you create to have any prebuilt modules within it. Passing this option keeps its internal DKMS tarball from containing any prebuilt modules. ๐ฑ--allโ Automatically specifies all relevant kernels/arches for a module/module-version. Can be used for things likeremove,unbuildanduninstall. Saves you the trouble of actually specifying-k kernel1 -a arch1 -k kernel2 -a arch2for every kernel you have built your module for. ๐ซถ--no-depmodโ Prevents DKMS from running thedepmodcommand duringinstallanduninstall, which avoids (re)calculating module dependencies and thereby saves time. โฑ๏ธ--modprobe-on-installโ Executesmodprobeon the modules upon successful installation. ๐--kernelsourcedir <kernel-source-directory-location>โ Lets you specify the location of your kernel source directory. Most likely you won't need to set this if your kernel source is accessible via/lib/modules/$kernel_version/build. ๐--directive <"cli-directive=cli-value">โ Lets you specify additional directives from the command line. The--directiveoption can be used multiple times on the same command line to specify multiple additional command line directives. ๐ฌ--rpm_safe_upgradeโ This flag should be used when packaging DKMS enabled modules in RPMs. It should be specified during both theaddandremoveactions in the RPM spec to ensure that DKMS and RPM behave correctly in all scenarios when upgrading between various versions of a dkms enabled module RPM package. ๐ฆ--dkmstree path/to/placeโ Provides a destination tree for building and installing modules to. Useful when you don't want to contaminate a system when using it solely for building. ๐ณ--sourcetree path/to/placeโ Provides a location to build a DKMS package from. Useful for systems where you may not have root access, but you'd still like to be able to build DKMS packages. ๐จ--installtree path/to/placeโ Provides a location to place modules when adkms installcommand is issued. ๐ฆ-j numberโ Run no more thannumberjobs in parallel; see the-joption ofmake(1). Defaults to the number of CPUs in the system, detected bynproc(1). Specify0to impose no limit on the number of parallel jobs. ๐งต--verboseโ Enable verbose output of external commands executed in DKMS. ๐ฃ๏ธ
๐ฆ ORIGINAL MODULES ๐ฆ
So, during the first install of a module for a <kernelversion>, dkms will search /lib/modules/<kernelversion> for a pre-existing module of the same name. If one is found, it will automatically be saved as an "original_module" so that if the newer module is later removed, dkms will put the original module back in its place. ๐ซถ
Currently, DKMS searches for these original modules with first preference going to modules located in /lib/modules/<kernelversion>/updates/ followed by $DEST_MODULE_LOCATION (as specified in dkms.conf). If one cannot be found in either location, a find will be used to locate one for that kernel. If none are found, then during a later uninstall, your kernel will not have that module replaced. ๐ญ
If more than one is found, then the first one located (by preference indicated above) will be considered the "original_module". As well, all copies of the same-named module will be removed from your kernel tree and placed into /var/lib/dkms/<module>/original_module/$kernelver/collisions so that they can be manually accessible later. DKMS will never actually do anything with the modules found underneath the /collisions directory, and they will be stored there until you manually delete them. ๐
๐ DKMS.CONF ๐
When performing an add, a proper dkms.conf file must be found. A properly formatted configuration file is essential for communicating to DKMS how and where the module should be installed. While not all the directives are required, providing as many as possible helps to limit any ambiguity. ๐
Note that dkms.conf is really only a shell-script of variable definitions which are then sourced in by the dkms executable (of the format, DIRECTIVE="directive text goes here"). As well, the directives are case-sensitive and should be given in ALL CAPS. ๐
It is important to understand that many of the DKMS directives are arrays whose index values are tied together. These array associations can be considered families, and there are currently three such families of directive arrays. MAKE[#] and MAKE_MATCH[#] make up one family. PATCH[#] and PATCH_MATCH[#] make up the second family. The third and largest family consists of BUILT_MODULE_NAME[#], BUILT_MODULE_LOCATION[#], DEST_MODULE_NAME[#], DEST_MODULE_LOCATION[#] and STRIP[#]. When indexing these arrays when creating your dkms.conf, each family should start at index value 0. ๐งฉ
PACKAGE_NAME=โ This directive gives the name associated with the entire package of modules. This is the same name that is used with the-moption when building, adding, etc. and may not necessarily be the same as theMODULE_NAME. This directive must be present in every DKMS configuration file. ๐PACKAGE_VERSION=โ This directive gives the version associated with the entire package of modules being installed within that dkms package. This directive must be present in every DKMS configuration file. โญBUILT_MODULE_NAME[#]=โ This directive gives the name of the module just after it is built. If your DKMS module package contains more than one module to install, this is a required directive for all of the modules. This directive should explicitly not contain any trailing".o"or".ko". Note that for each module within a dkms package, the numeric value of#must be the same for each ofBUILT_MODULE_NAME,BUILT_MODULE_LOCATION,DEST_MODULE_NAMEandDEST_MODULE_LOCATION, and that the numbering should start at0(eg.BUILT_MODULE_NAME[0]="qla2200"BUILT_MODULE_NAME[1]="qla2300"). ๐
BUILT_MODULE_LOCATION[#]=
Okay so bestie, this one tells DKMS where your built module is actually chillin' after it gets built. ๐
The pathname here should be given relative to the root directory of your source files โ that's the place where your dkms.conf file can be found, iykyk.
If you leave it unset, DKMS expects to find your BUILT_MODULE_NAME[#] in the root directory of your source files. No cap.
โ ๏ธ Real talk: for each module within a dkms package, the numeric value of#must be the same for each ofBUILT_MODULE_NAME,BUILT_MODULE_LOCATION,DEST_MODULE_NAMEandDEST_MODULE_LOCATION, and the numbering should start at0.
Like, for example:
BUILT_MODULE_LOCATION[0]="some/dir/"
BUILT_MODULE_LOCATION[1]="other/dir/"
See how the numbers line up? That's the vibe. โจ
DEST_MODULE_NAME[#]=
This directive lets you specify the name of the module as it should be installed. Basically it'll rename the module from BUILT_MODULE_NAME[#] to DEST_MODULE_NAME[#]. Glow-up for your module fr fr. ๐
It should explicitly not contain any trailing ".o" or ".ko" โ like, do not do that.
If unset, it is assumed to be the same value as BUILT_MODULE_NAME[#].
โ ๏ธ Same rule as before: for each module within a dkms package, the numeric value of#must be the same for each ofBUILT_MODULE_NAME,BUILT_MODULE_LOCATION,DEST_MODULE_NAMEandDEST_MODULE_LOCATION, and the numbering should start at0.
Example:
DEST_MODULE_NAME[0]="qla2200_6x"
DEST_MODULE_NAME[1]="qla2300_6x"
DEST_MODULE_LOCATION[#]=
This directive specifies the destination where a module should be installed to, once compiled. It also is used for finding original_modules. ๐
This is a required directive, except as noted below. It must start with the text "/kernel" โ which is in reference to /lib/modules/<kernelversion>/kernel.
โ ๏ธ And yes, the same numbering thing AGAIN: for each module within a dkms package, the numeric value of#must be the same for each ofBUILT_MODULE_NAME,BUILT_MODULE_LOCATION,DEST_MODULE_NAMEandDEST_MODULE_LOCATION, and the numbering should start at0.
Example:
DEST_MODULE_LOCATION[0]="/kernel/drivers/something/"
DEST_MODULE_LOCATION[1]="/kernel/drivers/other/"
Now the plot twist: DEST_MODULE_LOCATION is ignored on Fedora, Red Hat Enterprise Linux, SuSE Linux Enterprise Server, openSUSE and Ubuntu. Instead, the proper distribution-specific directory is used. So on those distros your cute little path just gets ghosted. ๐
STRIP[#]=
By default strip is considered to be "yes". If you set it to "no", DKMS will not run strip -g against your built module to remove debug symbols from it. So like, if you're out here debugging and you need those symbols, this is your girl. ๐
STRIP[0] is used as the default for any unset entries in the STRIP array. Periodt.
MAKE[#]=
The MAKE directive array tells DKMS which make command should be used for building your module. ๐ ๏ธ
- The default make command should be put into
MAKE[0]. - Other entries in the
MAKEarray will only be used if their corresponding entry inMAKE_MATCH[#]matches, as a regular expression (usinggrep -E), the kernel that the module is being built for. - Heads up: if no value is placed in
MAKE_MATCH[#]for anyMAKE[#]where# > 0, then thatMAKEdirective is ignored. ๐ MAKE_MATCH[0]is optional, and if it is populated, it will be used to determine ifMAKE[0]should be used to build the module for that kernel.- If multiple
MAKE_MATCHdirectives match against the kernel being built for, the last matchingMAKE[#]will be used to build your module. - If no
MAKEdirective is specified, or if noMAKE_MATCHmatches the kernel being built for, DKMS will attempt to use a generic make command to build your module.
Also, sneaky detail: KERNELRELEASE=$kernelver -j$parallel_jobs will be automatically appended to MAKE[#]. If you want to suppress this behavior, you can quote the make command: 'make'. ๐ซถ
MAKE_MATCH[#]=
See the above entry on MAKE[#] directives, bestie. This array should be populated with regular expressions which, when matched against the kernel being built for, will tell DKMS to use the corresponding make command in the MAKE[#] directive array to build your module. It's giving conditional logic, but make it regex. โจ
NO_WEAK_MODULES=
The NO_WEAK_MODULES directive, when set to "yes", prevents dkms from creating a symlink into the weak-updates directory. ๐ซ
The weak modules facility was designed to eliminate the need to rebuild kernel modules when kernel upgrades occur, and it relies on the symbols within the kABI. Valid values are "yes" or "no".
The kABI kernel module interface is currently supported on Red Hat Enterprise Linux (and derivatives), SUSE Linux Enterprise Server and openSUSE Leap; on other distributions this directive is ignored.
OBSOLETE_BY=
โ ๏ธ DEPRECATED ALERT โ ๏ธ This directive is deprecated and will be removed in a future version. Consider usingBUILD_EXCLUSIVE_KERNEL_MAXinstead ofOBSOLETE_BY, as the former is a more general approach to solve the same problem. Like, the upgrade path is right there bestie, take it. ๐ญ
It allows you to specify a kernel version that obsoletes the necessity for this particular DKMS module. This can be specified as a particular upstream kernel or an ABI bump of a kernel. For example, "2.6.24" would be an upstream kernel and "2.6.24-16" would represent an ABI bump for a kernel. Both are valid in this area. ๐
Its use indicates a lack of proper module versioning using MODULE_VERSION() tags in the module source itself. It is better to fix the MODULE_VERSION() tags than use OBSOLETE_BY. This also introduces an implicit distribution/version dependency on the package, as the value of OBSOLETE_BY is meaningful only in the context of a single distribution/version. So yeah, it's lowkey a red flag in your config. ๐ฉ
PATCH[#]=
Use the PATCH directive array to specify patches which should be applied to your source before a build occurs. ๐งต
- All patches are expected to be in
-p1format and are applied with thepatch -p1command. - Each directive should specify the filename of the patch to apply.
- All patches must be located in the
patchessubdirectory of your source directory (/usr/src/<module>-<module-version>/patches/) or in/etc/dkms/<module>/patches/(which takes precedence over the source directory). So like,/etc/dkmsis the main character here. ๐ - If any patch fails to apply, the build will be halted and the rejections can be inspected in
/var/lib/dkms/<module>/<module-version>/build/. - If a patch should only be applied conditionally, the
PATCH_MATCH[#]array should be used, and a corresponding regular expression should be placed inPATCH_MATCH[#]which will alert dkms to only use thatPATCH[#]if the regular expression matches the kernel which the module is currently being built for.
PATCH_MATCH[#]=
See the above description for PATCH[#] directives. If you only want a patch applied in certain scenarios, the PATCH_MATCH array should be utilized by giving a regular expression which matches the kernels you intend the corresponding PATCH[#] to be applied to before building that module. Conditional patching, we love to see it. ๐ฆ
AUTOINSTALL=
If this directive is set to "yes" then the DKMS autoinstaller service will automatically try to install this module on any kernel you boot into. See the section on DKMS AUTOINSTALLER for more information. Valid values are "yes" or "no". Set it and forget it, honestly. โจ
BUILD_DEPENDS[#]=
This optional directive is an array that allows you to specify other modules as dependencies for your module. ๐ซถ
- Each array element should be the
PACKAGE_NAMEof another module that is managed by dkms. - Do not specify a version or architecture in the dependency.
- A missing dependency requires the parameter
[--force]to still attempt the build of the module.
When invoked through autoinstall, unresolved dependencies are handled differently depending on whether they are known to dkms:
- A dependency that is itself a dkms-managed module but failed to install (for example because of a circular dependency or a build error) is treated as a hard failure and causes
autoinstallto exit non-zero. - A dependency that is not registered with dkms at the time
autoinstallruns is treated as deferred: a warning is emitted and the dependent module is left in theaddedstate, butautoinstallexits successfully.
This avoids spurious failures during multi-package installs where the dependency's source package has not yet had its postinst run, or where the dependency is supplied by something outside dkms. The dependent module will be picked up by the next autoinstall trigger once the dependency becomes available. Not me being patient and emotionally mature about dependency ordering. ๐
Example: Ubuntu system with module A and module B depending on A. During an update, both the kernel and module A get updated, so autoinstall runs as a kernel post hook. This means the whole dependency logic fails because module A is not yet installed to satisfy module B.
BUILD_DEPENDS_REBUILD=
If this directive is set to yes then the module which has BUILD_DEPENDS being set will get rebuilt every time a dependency changes version. ๐ This is usually provided in a specific /etc/dkms/<module>.conf on a per installation basis.
To keep track of the dependency change, the version of the module that was used at build time is recorded in the file:
/var/lib/dkms/<module>/<kernel_version>-<arch>/.dep_<dependency>
As soon as the module version changes, this is compared and the dependent module is rebuilt. With the parameter --force the dependency is not tracked.
BUILD_EXCLUSIVE_KERNEL=
This optional directive allows you to specify a regular expression which defines the subset of kernels which DKMS is allowed to build your module for. ๐
If the kernel being built for does not match against this regular expression (or does not satisfy the constraints of any other BUILD_EXCLUSIVE_* directive), the build will error out with exit code 77. Note that dkms autoinstall will ignore this type of error condition and simply skip the respective modules. So it's less "screaming" and more "silently walking away". ๐
For example, if you set it as ="^2.4.*", your module would not be built for 2.6 or later kernels.
okay so bestie, we're still in the dkms.conf zone ๐
and these next bits are all about telling DKMS exactly which kernels and architectures your module is allowed to play with. no cap.
BUILD_EXCLUSIVE_KERNEL_MIN=andBUILD_EXCLUSIVE_KERNEL_MAX=โ these are optional and they let you set the min and max kernel versions your module supports. if you set one or both, your module won't be built for kernels outside those limits. for example, if you setBUILD_EXCLUSIVE_KERNEL_MINas"=3.5", your module gets built for"3.5-rc2","3.6.18"or later, but not for"3.4.999"or earlier. similarly, if you setBUILD_EXCLUSIVE_KERNEL_MAXas="4.12", your module gets built for"4.11.999","3.9-rc5"or earlier, but not for"4.12-rc1"or later. periodt.BUILD_EXCLUSIVE_ARCH=โ this one is like the kernel one but for architecture. if you set it to="i.86", your module won't be built foria32e,x86_64,amd64,s390, etc. it's giving picky but valid. ๐BUILD_EXCLUSIVE_CONFIG=โ this optional directive lets you give a space-separated list of kernel config options ("CONFIG_FOO") that must be enabled in the target kernel's.configfile (either compiled in or as a module) or absent (if prefixed with an exclamation mark, e.g."!CONFIG_BAR") for the module to build. for example, if you set it as="CONFIG_PCI !CONFIG_PREEMPT_RT", your module only builds for kernels with PCI enabled but the RT patchset disabled. slay. โจBUILD_EXCLUSIVE_KERNEL[#]=,BUILD_EXCLUSIVE_KERNEL_MIN[#]=,BUILD_EXCLUSIVE_KERNEL_MAX[#]=,BUILD_EXCLUSIVE_ARCH[#]=,BUILD_EXCLUSIVE_CONFIG[#]=โ these are the per-module versions of all the above. they work exactly like the global ones but only apply to the specific module at the given index. so you can have different constraints for each module in a multi-module package. the globalBUILD_EXCLUSIVEdirectives are still checked for backward compatibility, and if any module fails either global or its specific per-module constraints, the build gets excluded. for example, if you have two modules:BUILD_EXCLUSIVE_KERNEL[0]="^5..*"andBUILD_EXCLUSIVE_KERNEL[1]="^6..*"โ module 0 only builds for kernel 5.x, module 1 only for 6.x. iconic.POST_ADD=โ the name of the script to run after an add is performed. the path should be given relative to the root directory of your source.POST_BUILD=โ the name of the script to run after a build is performed. path relative to the root of your source.POST_INSTALL=โ the name of the script to run after an install is performed. path relative to the root of your source.POST_REMOVE=โ the name of the script to run after a remove is performed. path relative to the root of your source.PRE_BUILD=โ the name of the script to run before a build is performed. path relative to the root of your source.PRE_INSTALL=โ the name of the script to run before an install is performed. path relative to the root of your source. if the script exits with a non-zero value, the install will be aborted. this is typically used to perform a custom version comparison. so if your script is like โnahโ, install stops. ๐
all scripts (POST_ADD, PRE_BUILD, POST_BUILD, PRE_INSTALL, POST_INSTALL, POST_REMOVE) can also be placed in /etc/dkms/<module>/ instead of the module source directory. scripts in /etc/dkms/<module>/ take precedence over scripts in the source directory. so if you want to override, that's where you go. ๐
โจ DKMS.CONF VARIABLES โจ
inside your DKMS config file, you can use certain variables that get replaced at run-time with their values. it's like magic but it's just shell.
$kernelverโ can be used within a directive definition, and when it's used, the actual kernel version in question gets substituted in its place. this is especially useful inMAKEcommands when specifying whichINCLUDEstatements should be used when compiling your module (e.g.MAKE="make all INCLUDEDIR=/lib/modules/${kernelver}/build/include"). so you don't have to hardcode that path. queen behavior.$kernel_source_dirโ holds the value of the location of your kernel source directory. usually, this will be/lib/modules/$kernelver/build, unless otherwise specified with the--kernelsourcediroption. so it's like the home base for your kernel source.
๐ธ DKMS.CONF OVERRIDES ๐ธ
you can override directives provided in the module-provided dkms.conf files. every time after a dkms.conf file is read, dkms will look for and read the following files in order:
/etc/dkms/<module>.conf/etc/dkms/<module>-<module-version>.conf/etc/dkms/<module>-<module-version>-<kernel>.conf/etc/dkms/<module>-<module-version>-<kernel>-<arch>.conf
you can use these files to override settings in the module-provided dkms.conf file. so if you need to tweak something without touching the source, this is the move. ๐
additionally, patches and scripts can be placed in /etc/dkms/<module>/ to override those provided by the module source tree:
/etc/dkms/<module>/patches/โ patch files (override same-named patches from the source directory; the directory structure is preserved, so patches in subdirectories such as/etc/dkms/<module>/patches/subdir/patch.patchwill override the correspondingsubdir/patch.patchfrom the source tree)/etc/dkms/<module>/โ scripts referenced byPRE_BUILD,POST_BUILD, etc. (override same-named scripts from the source directory)
so if you want to be extra and customize everything, you can. no judgement. ๐ซถ
๐ FRAMEWORK.CONF MAIN CONFIGURATION ๐
the /etc/dkms/framework.conf configuration file controls how the overall DKMS framework handles. it is sourced in every time the dkms command is run. mainly it can currently be used to set different default values for the variables. the file contains descriptions for each directive it supports. additionally to /etc/dkms/framework.conf, any file matching the glob /etc/dkms/framework.conf.d/*.conf will be loaded as well. so you can split your config if you want. very modular, very chic. โจ
dkms_tree,source_tree,install_tree,tmp_locationโ control which folders DKMS uses for components and artifacts. like where it puts its stuff.verboseโ can be set to anything but a null value to enable verbose output of external commands executed in DKMS. so if you want the tea, set it. โsymlink_modulesโ controls whether binary modules are copied to/lib/modulesor if only symlinks are created there. note that these variables can also be manipulated on the command line with--dkmstree,--sourcetree,--installtreeand--symlink-modulesoptions. so you have options, bestie.autoinstall_all_kernelsโ used by the common postinst for DKMS modules. it controls if the build should be done for all installed kernels or only for the current and latest installed kernel. it has no command line equivalent. so it's a config-only vibe.sign_fileโ this is the path of thesign-filekernel binary that is used to sign the kernel modules. the variable$kernelvercan be used in path to represent the target kernel version. the path for the binary depends on the distribution. so you might need to look it up for your distro.mok_signing_key,mok_certificateโ location of the key and certificate files used for Secure boot. the variable$kernelvercan be used in path to represent the target kernel version. NOTE: if any of the files specified bymok_signing_keyandmok_certificateare non-existent, dkms will re-create both files.mok_signing_keycan also be a"pkcs11:..."string for PKCS#11 engine, as long as thesign-fileprogram supports it. so secure boot is handled, but watch out for it recreating files. ๐ญmodprobe_on_installโ automatically load the built modules upon successful installation. so you don't have tomodprobemanually. convenient. ๐parallel_jobsโ run no more than this number of jobs in parallel. so if you have a beefy machine, you can crank it up. but don't go overboard.compress_gzip_opts,compress_xz_opts,compress_zstd_optsโ control how modules are compressed. by default, the highest available level of compression is used. so it's already trying its best. ๐build_environmentโ if the directive is set to any non null-value, when building modules, the exported variables that are in the file will be imported into the DKMS shell with thesourcecommand. can be used to specify a custom gcc installed in a custom path; and the variable$kernelvercan be used inside the environment file to represent the target kernel version. some examples: define a custom script to point to a specific GCC (export CC=/opt/gcc12/bin/gcc):build_environment="/opt/gcc12/env"; enable the software collectiongcc-toolset-11and use it for building an UEK kernel on Oracle Linux:build_environment="/opt/rh/gcc-toolset-11/enable". so you can have different toolchains per build. very flexible. ๐ฅpost_transactionโ if the directive is set to any non null-value, the content of the directive will be executed with any command that change the content of the kernel modules folder, that isdkms autoinstall,dkms installanddkms remove/unbuild/uninstall. can be used to trigger a global initrd rebuild or to call a script that performs some other tasks (callingkexec, triggering the restart of services not contained in a DKMS package, etc.). the command is constructed with the shell built-inevaland the variable$kernelvercan be used to represent the target kernel version. some examples: regenerate the ram disk for the target kernel:post_transaction="dracut --force --kver $kernelver"(Red Hat style) orpost_transaction="update-initramfs -k $kernelver"(Debian style); launch an arbitrary script:post_transaction="/path/to/script.sh"; restart a service:post_transaction="systemctl restart something.service"; regenerate the ram disk for all installed kernels, ignoring the kernel version passed as the parameter:post_transaction="dracut --force --regenerate-all"(Red Hat style) orpost_transaction="update-initramfs -k all"(Debian style). so it's like a hook after any kernel module folder change. powerful stuff. ๐
๐ฆ DKMS AUTOINSTALLER ๐ฆ
the DKMS autoinstaller service (which can be dkms_autoinstaller or dkms.service depending on your distribution) is a boot-time service that automatically installs any module which has AUTOINSTALL="yes" set in its dkms.conf file. the service works quite simply and if multiple versions of a module are in your system's DKMS tree, it will not do anything and instead explain that manual intervention is required. so it's like โi got you, but if it's complicated, you're on your ownโ. fair. ๐
๐ AUTHOR ๐
Gary Lerhaupt, Emil Velikov, Simone Caronni, Xu Zhen
๐ WEBPAGE ๐
okay bestie so if you wanna go stare at the source of truth with your own two eyeballs, the official webpage is:
https://github.com/dkms-project/dkms
like. that's the whole section. short and sweet, we love a low-effort queen ๐ โจ
aaaand that's a wrap on the whole DKMS(8) page, bestie!! ๐ you just read all of it, every flag, every variable, every config file, every warning, no skips, no cap. that's genuinely iconic of you ๐ซถ
this version was dkms-3.4.4, and it's dated 05 Oct 2026 โ so if you're reading this and the calendar says otherwise, maybe go peek at the repo above for something fresher ๐๐ธ
go build something, go load a module, go be the main character of your own kernel ๐ byeee!! ๐ฆโจ
๐ฆ where this page comes from
- epel 10: dkms 3.4.4-1.el10_3 ยท GPL-2.0-or-later
- epel 9: dkms 3.4.4-1.el9 ยท GPL-2.0-or-later
- fedora 43: dkms 3.4.4-1.fc43 ยท GPL-2.0-or-later
- fedora 44: dkms 3.4.4-1.fc44 ยท GPL-2.0-or-later
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms