Developer working at desk with dark IDE open on monitor, server rack background
Kernel Modules
William  

Linux Kernel Modules: Load, Unload, and Troubleshoot

A kernel module is compiled code you load into a running Linux kernel to add a driver, a filesystem, or a whole subsystem without rebooting. Run lsmod and modinfo to see what is loaded and why, modprobe to load it with dependencies handled, and when a load fails, chase it into dmesg and the module source instead of pasting a config tweak someone swore by. That last habit is the difference between fixing it and fixing it again next week. So when people ask what Linux kernel modules are, that is the honest, working answer.

Last updated: 2026-07-21

If you have spent any time on Linux, you have run into the term "kernel module" and wondered what it actually is and why it matters. I will explain it plainly, without assuming you are a kernel hacker, and show you the exact commands to inspect, load, and troubleshoot modules. Everything here runs on a normal distribution with no special setup.

What are Linux kernel modules, and why does the kernel use them?

A kernel module is a chunk of code that plugs into the kernel at runtime. The kernel is the core of the system: it manages hardware and sits between your programs and the metal. A module extends that core without a full rebuild or reboot. Think of it as a driver or feature the kernel can pick up on demand.

The reason Linux works this way is size. If the kernel had to include every driver for every card, filesystem, and protocol ever made, it would be enormous and mostly dead weight on any given machine. Instead the base kernel stays small, and it pulls in the modules a specific box actually needs. Kernel modules can be loaded and unloaded without a system reboot, which is what makes Linux adapt to new hardware while it is still running.

Here is what that buys you in practice:

  • Hardware support on the fly. Plug in a device and the kernel loads the matching driver module.
  • A lean kernel. Only the code you use sits in memory.
  • Customization. Need an odd filesystem or a security layer? Load its module, skip the rest.

That is the model. The kernel is not one giant binary; it is a small core plus a pile of parts it snaps in as required.

Which kernel modules are loaded right now?

Run lsmod first. The lsmod command displays the currently loaded kernel modules, and its output is more useful than most people read it as:

Module Size Used by
nvidia_drm 0 0
nvidia_modeset 0 0 nvidia_drm
i915 0 0

Read the three columns. The first is the module name. The second is its size in bytes. The third, Used by, is the reference count and the list of modules leaning on this one. That last column matters: a module with a nonzero count and dependents will refuse to unload, and now you know why before you fight it. lsmod is just a pretty-printer for /proc/modules, so cat /proc/modules shows the same data raw if you want it.

For the details on a single module, use modinfo:

modinfo i915

That prints the file path of the .ko, the license, the author, the kernel version it was built for, its dependencies, and every parameter it accepts. I reach for modinfo before I load anything unfamiliar, because the parm: lines tell me which options are even legal. If you want a fuller tour of the listing tools, I wrote a separate walkthrough on listing loaded kernel modules.

How do you load and unload a kernel module?

Use modprobe, not insmod, for almost everything. Here is the difference that trips people up: insmod inserts one exact .ko file and nothing else, so if that module needs another module first, insmod just fails. modprobe reads the dependency map and loads the whole chain in order.

To load a module and its dependencies:

  1. Confirm the name and parameters with modinfo example_module.
  2. Load it: sudo modprobe example_module.
  3. Verify it took: lsmod | grep example_module.
  4. If nothing shows up, read dmesg before you try again.

To unload one:

  1. Check the reference count in lsmod first. A nonzero count means something is using it.
  2. Run sudo modprobe -r example_module, which removes the module and any now-unused dependencies it pulled in.
  3. rmmod is the raw version. The rmmod command unloads a single kernel module with no dependency handling, so I only use it when I know exactly what I am doing.

For the mechanics of on-demand insertion and removal in more depth, see this practical guide to dynamic module loading.

How do you set module options and parameters?

Pass parameters at load time as name=value pairs. For example:

sudo modprobe usbcore autosuspend=-1

Do not guess parameter names. Run modinfo -p usbcore to list exactly what the module accepts, or read them live under /sys/module/<name>/parameters/. Each file there is one parameter; cat it to see the current value. That beats copying a flag off a forum post that was written for a different kernel.

To make an option stick across reboots, drop a file in /etc/modprobe.d/. A line like options usbcore autosuspend=-1 in /etc/modprobe.d/usb.conf applies every time the module loads. Keep one concern per file and name it clearly, so future-you knows why it is there. The official kernel module documentation covers the config-file syntax if you want the exact rules.

Automatic loading at boot versus on demand

Most modules load themselves, and you should let them. When you plug in hardware, udev matches the device to a module alias and loads it without you touching anything. That is why a USB drive just works. For that automatic path, doing nothing is the correct move.

You force a module at boot only when the automatic detection misses it. List the module name, one per line, in a file under /etc/modules-load.d/, for example /etc/modules-load.d/mymod.conf. A systemd service reads those at boot and loads each one. Use this for a module with no hardware to trigger it, like a specific filesystem or a network tweak you always want present.

The wrong instinct is to force-load a pile of modules "just in case." That slows boot and hides real detection bugs. If a module should load and does not, find out why the alias is not matching instead of papering over it in modules-load.d.

How do you resolve module dependencies?

modprobe handles dependencies by reading modules.dep, a map that lists which modules each module needs. That file is generated by depmod, which scans the modules under /lib/modules/$(uname -r)/ and works out the chain. When you install a new kernel or add modules, depmod runs to rebuild the map.

If modprobe complains it cannot find a module you know exists, the map is usually stale. Run sudo depmod -a to regenerate it, then try again. A missing dependency error in dmesg names the exact symbol or module that could not be resolved, so read it rather than guessing. That name is your next lead.

When a build says the module tree itself is missing, the headers or the modules.dep for your running kernel are absent. I covered that specific failure in a fix for the missing kernel modules tree error.

How do you blacklist or alias a module?

Blacklist a module when the kernel keeps loading a driver you do not want. The classic case is the open-source nouveau driver grabbing your GPU before the proprietary NVIDIA one can. To stop it, add a line to a file in /etc/modprobe.d/:

blacklist nouveau

One caveat that bites people: blacklist prevents the module from loading automatically, but it does not stop another module from pulling it in as a dependency. To hard-block it, also add install nouveau /bin/true, which replaces the load action with a no-op. After editing, rebuild your initramfs so the change applies at early boot.

Aliases go the other way. An alias line maps a friendly name or a device pattern to a real module, which is how automatic loading resolves hardware to drivers. You rarely write these by hand, but you will see them when you read the generated config. For the safe way to disable a driver without breaking boot, see these blacklisting best practices.

How do you diagnose a module that will not load?

Read dmesg before you change a single setting. When a module fails, the kernel writes the reason to the ring buffer, and it is almost always specific:

sudo dmesg -T | tail -20

Match the message to the cause. Unknown symbol in module means a dependency or kernel version mismatch, not a broken config. Invalid module format means the module was built for a different kernel, so check uname -r against the version in modinfo. Operation not permitted on a signed-kernel box usually means Secure Boot is rejecting an unsigned module. Each of those wants a different fix, which is exactly why the trial-and-error approach wastes your night.

On a systemd system, journalctl -b -k shows kernel messages from the current boot with timestamps, and journalctl -b -1 -k shows the boot before a crash. Pair the error with the moment you ran modprobe and the picture clears fast. If you want a structured walkthrough of the tooling, here is a beginner's guide to debugging a kernel module.

How do you build your own kernel module?

You need the kernel headers for your running kernel and a two-line Makefile. Install the headers first (linux-headers-$(uname -r) on Debian and Ubuntu, kernel-devel on Fedora), because you cannot build against a kernel you have no headers for.

A minimal module, hello.c:

#include <linux/module.h>
#include <linux/kernel.h>

static int __init hello_init(void) {
 printk(KERN_INFO "hello: loaded\n");
 return 0;
}
static void __exit hello_exit(void) {
 printk(KERN_INFO "hello: unloaded\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");

The 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

Now the steps:

  1. Run make in that directory. You get hello.ko.
  2. Insert it for testing with sudo insmod ./hello.ko.
  3. Confirm it ran: dmesg | tail should show hello: loaded.
  4. Remove it with sudo rmmod hello and check dmesg for the unload line.

Use insmod here, not modprobe, because your .ko is not installed under /lib/modules yet. Once it works and you copy it into the modules tree and run depmod, modprobe will find it by name like any other.

FAQ

Where do kernel modules live on disk?
Under /lib/modules/$(uname -r)/, organized into subdirectories like kernel/drivers and kernel/fs. Each file ends in .ko, short for kernel object. When you switch kernels, you get a whole new tree, which is why a module built for one kernel will not load under another.

Is a kernel module the same thing as a device driver?
Not quite. Every driver on a modular kernel ships as a module, but not every module is a driver. Filesystems, network protocols, and security layers like SELinux all load as modules too. Driver is the most common kind, not the only kind.

Why does a module refuse to unload even though I am root?
Because something is still using it. Look at the Used by column in lsmod; a nonzero reference count means the module is busy or another module depends on it. Stop the process or unload the dependents first, and root has nothing to do with it.

Do I lose loaded modules when I reboot?
Yes, unless they load automatically. Hardware modules come back because udev re-detects the device and reloads them. Modules with no hardware trigger need an entry in /etc/modules-load.d/ to return after a restart.

How do I know a module is safe to load?
Check modinfo for the license and signature, and prefer modules from your distribution's repositories over random binaries. An out-of-tree .ko built for a different kernel will either refuse to load or, worse, crash the box, so match it to uname -r first.

Related: How to Load HPC Modules and Verify Your Shell