User:Dbognar/dkms

From Gentoo Wiki
Jump to:navigation Jump to:search
This article is a work in progress; treat its contents with caution - dbognar (talk | contribs).
Resources

The main goal of the dkms (Dynamic Kernel Module System) project is to provide a generic interface for managing Linux kernel modules (LKM). It allows one to build and install multiple versions of a module against/into multiple versions of kernel. The source of a module is typically stored at /usr/src/<module-name>-<module-version> and contains a dkms.conf file which is used by the dkms command to handle the code.

In the following article a simple will be created in the Development section, which will be built and installed in the Management section.


Installation

There is currently no dkms ebuild available in the official gentoo repository, but one can easily setup alternative repositories to install a package from. These unofficial ebuild containers called overlays and one can add a new source with the eselect repository command:

root #eselect repository add brelod git https://github.com/brelod/gentoo-public
root #emerge --sync
root #emerge -avt dkms

Development

As a bare minimum, a kernel module needs to define and register an init and an exit method. The first will be called when inserting the module into the kernel with the modprobe command, while the second will be called when the module gets removed by a modprobe -r command.

CODE hello.c
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
  
MODULE_VERSION("0.0.1");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Simon Paul");
MODULE_DESCRIPTION("Sound of silence");
  
static int __init silence_init(void)
{
    printk(KERN_INFO "Hello darkness, my old friend\n");
    return 0;
}
  
static void __exit silence_exit(void)
{
    printk(KERN_INFO "And whispered in the sounds of silence\n");
}
  
module_init(silence_init);
module_exit(silence_exit);


CODE Makefile
obj-m = silence.o

all:
        make -C /lib/modules/$(KERNEL_VERSION)/build/ M=$(PWD) modules
clean:
        make -C /lib/modules/$(KERNEL_VERSION)/build M=$(PWD) clean

The dkms.conf file needs to be at the root of the module. It will be sourced by the dkms command as bash script, hence the array like notation in some of the variable names. Some variables like $kernelver will be automatically available at runtime holding build specific information passed as cli arguments.

CODE dkms.conf
AUTOINSTALL=yes
PACKAGE_NAME="silence"
PACKAGE_VERSION=0.0.1
BUILT_MODULE_NAME[0]="silence"
DEST_MODULE_LOCATION[0]="/kernel/drivers/other/silence"

MAKE[0]="make all KERNEL_VERSION=$kernelver"
CLEAN="make clean KERNEL_VERSION=$kernelver"

Management

The main goal of dkms is to make it easy to handle the out-of-source kernel modules. Prerequisite: Existing module source at /usr/src/<module>-<version> with a valid dkms.conf We are going to use the example module created in the Development section.

Tip
When one tries to install a module which is not added / built by dkms yet, it will automatically do the job, so the Add and Build sections can be skipped.

New module

Add

root #dkms add silence/0.0.1
Creating symlink /var/lib/dkms/silence/0.0.1/source -> /usr/src/silence-0.0.1
user $dkms status
silence/0.0.1: added
user $tree /var/lib/dkms/silence/
/var/lib/dkms/silence/
└── 0.0.1
    ├── build
    └── source -> /usr/src/silence-0.0.1

3 directories, 0 files

Build

root #dkms build silence/0.0.1 -k 5.15.19-gentoo/x86_64
Building module:
cleaning build area...
make -j8 KERNELRELEASE=5.15.19-gentoo all KERNEL_VERSION=5.15.19-gentoo...
cleaning build area...
root #dkms status
silence/0.0.1, 5.15.19-gentoo, x86_64: built
root #tree /var/lib/dkms/silence/
/var/lib/dkms/silence/
└── 0.0.1
    ├── 5.15.19-gentoo
    │   └── x86_64
    │       ├── log
    │       │   └── make.log
    │       └── module
    │           └── silence.ko
    └── source -> /usr/src/silence-0.0.1

6 directories, 2 files

Install

To place the built kernel object into the kernel tree and this way to make it available for the modprobe / modinfo commands, one can use the install command which has the same parameters as the build command.

root #dkms install silence/0.0.1 -k 5.15.19-gentoo/x86_64
silence.ko:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/5.15.19-gentoo/kernel/drivers/other/silence/
depmod...

Status

root #dkms status
silence/0.0.1, 5.15.19-gentoo, x86_64: installed


Test

Once the kernel object has been installed, one can load it to into the kernel by:

root #modprobe silence && rmmod silence
root #dmesg | tail -2
[ 6174.426531] Hello darkness, my old friend
[ 6312.536789] And whispered in the sounds of silence

Remove module

Uninstall

root #dkms uninstall silence/0.0.1 -k 5.15.19-gentoo/x86_64
Module silence-0.0.1 for kernel 5.15.19-gentoo (x86_64).
Before uninstall, this module version was ACTIVE on this kernel.

silence.ko:
 - Uninstallation
   - Deleting from: /lib/modules/5.15.19-gentoo/kernel/drivers/other/silence/
 - Original module
   - No original module was found for this module on this kernel.
   - Use the dkms install command to reinstall any previous module version.
depmod...


Unbuild

root #dkms unbuild silence/0.0.1 -k 5.15.19-gentoo/x86_64
Module silence 0.0.1 is not installed for kernel 5.15.19-gentoo (x86_64). Skipping...
Warning
This message seems to be a bug... (it also removes the entry from dkms status

Remove

If somebody don't want to use kernel module anymore, it can be easily removed from the dkms tree by

root #dkms remove silence/0.0.1 -k 5.15.19-gentoo/x86_64

or one can remove from all the kernels by

root #dkms remove silence/0.0.1 --all