Kernel Modules
Kernel modules extend the Linux kernel at runtime without rebooting. Device drivers, filesystems, network protocols — all can be loaded as modules when needed and unloaded when done. The kernel you boot is lean; modules add what's needed on demand. This is why Linux supports thousands of hardware devices without a monolithic kernel.
Managing Modules
# List loaded modules:
lsmod
# Module Size Used by
# nvidia 10000000 35
# nvidia_uvm 100000 0
# ext4 1234567 1
# libcrc32c 12345 2 ext4,btrfs
# Load a module:
modprobe ext4 # loads with auto-dependencies
insmod /path/to/mod.ko # load specific file, no auto-deps
# Unload:
modprobe -r ext4 # unload + unload unused dependencies
rmmod ext4 # unload specific module (fails if in use)
# Get module info:
modinfo ext4
# filename: /lib/modules/6.1.0/kernel/fs/ext4/ext4.ko
# description: Fourth Extended Filesystem
# author: Remy Card, ...
# license: GPL
# depends: mbcache,jbd2
# parm: debug_wants_extra_isize:int
# Module parameters:
modprobe usbcore autosuspend=-1 # load with parameter
echo -1 > /sys/module/usbcore/parameters/autosuspend # change live
Writing a Minimal Kernel Module
/* hello.c — minimal kernel module */
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("TuteWorld");
MODULE_DESCRIPTION("Minimal hello world module");
static int __init hello_init(void)
{
printk(KERN_INFO "Hello, kernel world!\n");
return 0; /* 0 = success, negative = error */
}
static void __exit hello_exit(void)
{
printk(KERN_INFO "Goodbye, kernel world!\n");
}
module_init(hello_init);
module_exit(hello_exit);
# Makefile:
obj-m += hello.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
# Build and load:
make
sudo insmod hello.ko
dmesg | tail -1
# [ 1234.567] Hello, kernel world!
sudo rmmod hello
dmesg | tail -1
# [ 2345.678] Goodbye, kernel world!
Module Parameters
/* module with parameters */
#include <linux/module.h>
#include <linux/moduleparam.h>
static int myval = 42;
module_param(myval, int, 0644);
MODULE_PARM_DESC(myval, "An integer parameter");
static char *mystr = "hello";
module_param(mystr, charp, 0644);
MODULE_PARM_DESC(mystr, "A string parameter");
/* Load with custom values: */
/* insmod mymodule.ko myval=100 mystr="world" */
/* Read/write live values: */
/* cat /sys/module/mymodule/parameters/myval */
/* echo 200 > /sys/module/mymodule/parameters/myval */
Module Signing and Secure Boot
# Modules can be signed with a cryptographic key
# Required when Secure Boot is active
# Check if a module is signed:
modinfo nvidia | grep sig
# signer: NVIDIA corporation
# sig_key: AA:BB:CC:...
# sig_hashalgo: sha256
# Check if the kernel requires signed modules:
cat /sys/kernel/security/lockdown
# [integrity] = modules must be signed
# Generate your own key (for custom modules):
openssl req -new -x509 -newkey rsa:2048 \
-keyout MOK.priv -outform DER -out MOK.der \
-days 36500 -subj "/CN=MyModuleKey/"
# Sign a module:
/usr/src/linux-headers-$(uname -r)/scripts/sign-file \
sha256 MOK.priv MOK.der mymodule.ko
# Enroll key in MOK database (requires reboot):
mokutil --import MOK.der