deep-dive2025-03-30ยท13 minยท132/348

Linux Kernel Module Loading and Unloading: A Practical Guide

How to load, unload, and manage kernel modules on Linux, including insmod, modprobe, and module configuration for custom drivers.

Introduction

The Linux kernel is modular by design. Rather than compiling every possible driver and feature into the kernel image, most functionality is loaded on demand as kernel modules. This keeps the base kernel small and allows hardware support and features to be added without rebooting. Understanding how modules work is essential for hardware troubleshooting, driver management, and kernel development.

Environment

The examples use a Debian 12 system running kernel 6.1 LTS. The system has several custom modules loaded for a specialized network interface card.

uname -r
# 6.1.0-23-amd64

lsmod | wc -l
# 342

Problem

You need to load a custom kernel module for a piece of hardware, but the module fails to load:

sudo insmod /lib/modules/6.1.0-23-amd64/kernel/drivers/net/ethernet/custom/nic.ko
# insmod: ERROR: could not insert module nic.ko: Invalid module format

Or the module loads but causes a kernel panic on certain operations.

Analysis

Kernel modules interact directly with the kernel's internal APIs. A module must be compiled against the exact kernel version and configuration it will be loaded into. The Invalid module format error means the module's version magic does not match the running kernel.

Check module information:

modinfo /lib/modules/6.1.0-23-amd64/kernel/drivers/net/ethernet/custom/nic.ko
# filename:       /lib/modules/6.1.0-23-amd64/kernel/drivers/net/ethernet/custom/nic.ko
# vermagic:       6.1.0-23-amd64 SMP preempt mod_unload
# depends:        mii
# alias:          pci:v00001234d00005678sv*sd*bc02sc00i*

Compare with your running kernel:

cat /proc/version
# Linux version 6.1.0-23-amd64 (debian-kernel@lists.debian.org) (gcc-12 (Debian 12.2.0-14) 12.2.0, GNU ld (GNU Binutils for Debian) 2.40) #1 SMP PREEMPT_DYNAMIC Debian 6.1.0-23

Solution

1. Load a module with insmod (basic)

sudo insmod /path/to/module.ko

insmod loads a module directly from a file path. It does not resolve dependencies.

2. Load a module with modprobe (recommended)

sudo modprobe nic

modprobe automatically resolves dependencies and loads required modules first. It searches /lib/modules/$(uname -r)/.

3. List loaded modules

lsmod
# Module                  Size  Used by
# nic                   131072  0
# mii                    16384  1 nic
# usbcore               311296  0

4. Remove a module

sudo modprobe -r nic

Or using rmmod (does not handle dependencies):

sudo rmmod nic

5. Auto-load modules at boot

echo "nic" | sudo tee /etc/modules-load.d/nic.conf

Or add to /etc/modules:

echo "nic" | sudo tee -a /etc/modules

6. Blacklist unwanted modules

echo "blacklist nouveau" | sudo tee /etc/modprobe.d/blacklist-nouveau.conf

This prevents the module from loading automatically.

7. Pass parameters to modules

# At load time
sudo modprobe nic parameter=value

# Persistently
echo "options nic parameter=value" | sudo tee /etc/modprobe.d/nic.conf

8. Check module dependencies

modprobe --show-depends nic
# /lib/modules/6.1.0-23-amd64/kernel/drivers/net/mii/mii.ko
# /lib/modules/6.1.0-23-amd64/kernel/drivers/net/ethernet/custom/nic.ko

9. Build module dependencies

After installing new modules:

sudo depmod -a

10. Debug module loading issues

# Check kernel logs for module-related messages
dmesg | tail -50

# Check for taint flags
cat /proc/sys/kernel/tainted
# 0 = clean, nonzero = tainted by proprietary modules or other issues

11. Use modinfo for detailed module information

modinfo -p nic
# parm:           debug:Debug level (0=none, 5=all) (int)
# parm:           speed:Link speed in Mbps (int)

12. Module versioning and kernel headers

To compile modules against your running kernel:

sudo apt-get install linux-headers-$(uname -r)
ls /lib/modules/$(uname -r)/build/
# Makefile  Module.symvers  include/

13. Check for live references before unloading

lsmod | grep nic
# nic  131072  0    # The 0 means no other modules reference it

If the count is non-zero, another module depends on it and it cannot be unloaded until the dependent is removed first.

Lessons Learned

Kernel module management is fundamental to Linux system administration. Always use modprobe over insmod for production work because it handles dependencies correctly. Compile modules against the exact kernel headers of your running kernel. And always check dmesg after loading a module to catch errors or warnings that may not be immediately apparent. A module that loads successfully may still have runtime bugs that only surface under specific conditions.


This blog does not accept any external sponsorships, affiliate marketing, or ad revenue.