November 30, 2024 · software linux

Configure Kernel Modules like a Pro

Kernel modules are powerful pieces of code that extend the capability of your kernel, for example, WireGuard was originally developed as a kernel module. Modules can be loaded at the time of kernel image load, initramfs load, or later on during the boot sequence. Unfortunately, the syntax of config files, options, and modules can be quite confusing, which is why I created a complete guide to loading kernel modules, in order of the boot sequence:

Kernel Image Stage (vmlinux)

The bootloader first loads the kernel image. You must manually compile modules into the kernel to load kernel modules at this stage. To set a module option, append modname.modoption=abc to the appropriate kernel command line in the GRUB config file (e.g. /etc/default/grub). GRUB_CMDLINE_LINUX_DEFAULT affects only normal boot, while GRUB_CMDLINE_LINUX affects both normal and recovery boot. Don't forget to run update-grub. To permanently blacklist a kernel module, add module_blacklist=modname1,modname2 to your kernel command line. If there are issues during boot, you can edit the kernel command by pressing Esc and e key during GRUB boot to enter the editor.

Initial RAM-filesystem Stage (initramfs)

The initramfs is a virtual file system mounted and read from memory. udev is loaded which then makes calls to modprobe to load the required kernel modules. You can force load a module by editing the /etc/initramfs-tools/modules file on Debian. Each line in the file has syntax modname1 or if using options, modname1 modoption=abc,123. Note, this has precedence over a modprobe.d blacklist.

To configure module options without force loading it, add the line options modname1 modoption=abc,123 to a .conf file in /etc/modprobe.d. The file must end in .conf to be detected, but the filename is arbitrary. Conversely, you can blacklist a module from loading by adding the line blacklist modname1 to a .conf file. After editing /etc/modprobe.d, regenerate the initramfs (depmod -ae && update-initramfs -u on Debian).

If required, you can also prevent loading of a module at the initramfs stage, by adding modprobe.blacklist=modname1 to your kernel command line.

See the Debian guide to blacklisting for more information on blacklisting stubborn kernel modules. Note that distributions like OpenWRT don't include an initramfs as the kernel image is sufficient.

Init Stage (PID 1)

At this stage, the root filesystem has been mounted and the initramfs has been cleared. Older init processes such as sysvinit load modules from the /etc/modules file. Syntax is similar to above, modname1 or modname1 modoption=abc,123. Newer distros using systemd-modules-load.service will start loading modules from /etc/modules-load.d/*.conf; /run/modules-load.d/*.conf; /usr/lib/modules-load.d/*.conf, there is no capability of options or blacklisting here. You also have the option with this service to add a kernel command line: modules_load=modname1,modname2.

In OpenWRT, you can configure module loading and options by creating files in /etc/modules.d (no filename restrictions), using syntax modname1 or modname1 modoption=abc,123. Another method is to edit the /etc/modules.conf file and use similar syntax to modprobe.d above.

Shell Stage (Userspace)

You can get a list of currently loaded modules with lsmod. To load a module from the terminal, use modprobe modname1 or modprobe modname1 modoption=abc. To unload a module, use rmmod.