Common Kernel Module Operations-Free Linux kernel development course

Previous Lecture 
Next Lecture

Linux Kernel Programming
Chapter 4  |  Part 4 of 6
Common Kernel Module Operations
📚 Practical
⏱ ~20 min
🔐 Kernel 6.x

🔍 Topics Covered
insmod
rmmod
lsmod
modinfo
modprobe
depmod
Module Parameters
/proc/modules
/sys/module

🎯 The Module Toolbox

Now that you can write and build a kernel module, let us explore all the tools available to manage modules on a running system. These are commands you will use constantly in your development and debugging workflow. Understanding each one deeply will save you a lot of time.

🛠 Quick Reference — All Module Commands
Kernel Module Management Commands
Command What It Does Needs Root?
insmod Load a .ko file directly, no dependency resolution Yes
rmmod Remove a loaded module by name Yes
lsmod List all currently loaded modules No
modinfo Show metadata of a .ko file or loaded module No
modprobe Smart load/unload with automatic dependency handling Yes
depmod Rebuild module dependency database Yes

📥 insmod — The Direct Loader

insmod (insert module) is the simplest way to load a kernel module. You give it the full path to the .ko file and it loads it.

# Basic usage — load module from current directory:
sudo insmod hello.ko

# Load and pass a parameter:
sudo insmod hello.ko my_param=42

# insmod gives no output on success.
# On failure it prints a brief error message.
# Always check dmesg for details on failures.

Limitations of insmod:

  • Does not resolve dependencies. If your module depends on another module that is not loaded yet, insmod will fail with “Unknown symbol” errors.
  • You must provide the complete path to the .ko file.
  • It is a low-level tool — use it during development when you are working with modules not yet installed in /lib/modules.

📤 rmmod — The Remover
# Remove a loaded module by name (no .ko extension, no path):
sudo rmmod hello

# Force removal (use with extreme caution — can cause crashes):
sudo rmmod -f hello

# Verbose removal:
sudo rmmod -v hello

rmmod calls the module’s exit function, waits for it to return, then frees the module’s memory. The module name for rmmod is the module name (from the .ko filename), not a path.

rmmod will refuse to remove a module if:

  • The module’s use count is non-zero (something is still using it)
  • Another loaded module depends on it
  • The module does not have an exit function registered
# Check what is using a module:
lsmod | grep hello
# Module         Size    Used by
# hello          16384   1       ← "1" means something is using it

# See what modules depend on bluetooth:
lsmod | grep bluetooth
# bluetooth     720896  42 btusb,rfcomm,bnep,btbcm,btrtl,btintel

📍 lsmod — See What is Loaded

lsmod reads /proc/modules and presents it in a readable format.

lsmod

# Sample output:
# Module                  Size  Used by
# hello                  16384  0
# snd_hda_intel         143360  3
# snd_hda_codec         229376  1 snd_hda_intel
# snd_pcm               196608  4 snd_hda_intel,snd_hda_codec
# bluetooth             720896 42 btusb,rfcomm,bnep

Understanding each column:

lsmod Output Explained
Module
Size
Used by
Module name
Memory in bytes
Use count, then names of modules that depend on this one
bluetooth
720896
42 btusb,rfcomm,bnep

The “42” means 42 things are using bluetooth. The names are other modules that depend on it.

# Filter the list:
lsmod | grep usb        # show USB-related modules
lsmod | wc -l           # count how many modules are loaded

📋 modinfo — Inspect Module Metadata

modinfo reads the metadata embedded in a .ko file. You can use it before loading a module to see what it does, what parameters it accepts, and what kernel it was built for.

# On a .ko file (before loading):
modinfo hello.ko

# On an installed module (by name):
modinfo bluetooth

# Show only the license:
modinfo -F license hello.ko

# Show only the parameters:
modinfo -F parm hello.ko

Key fields in modinfo output:

vermagic — the exact kernel version and config this module was built for. Mismatch = load failure.
depends — other modules this one depends on. Empty means no dependencies.
parm — parameters the module accepts, with their type (int, charp, bool, etc.).
alias — alternative names by which this module can be found, often device IDs.

🔨 modprobe — The Smart Loader

modprobe is the recommended way to load modules in production. It reads the module dependency database and loads all required modules automatically before loading your target module.

# Load a module (and its dependencies automatically):
sudo modprobe bluetooth

# Load with parameters:
sudo modprobe usbcore autosuspend=0

# Remove a module:
sudo modprobe -r bluetooth

# Show what would be done without actually doing it:
sudo modprobe --dry-run bluetooth
sudo modprobe -n bluetooth   # same thing

# Show the full dependency chain that would be loaded:
sudo modprobe --show-depends bluetooth

modprobe vs insmod — when to use which:

Use insmod when:
  • You are developing and testing a module
  • The .ko is in your local directory
  • You know there are no dependencies
  • You want fast iteration during development
Use modprobe when:
  • Module is installed in /lib/modules
  • Module has dependencies
  • Writing init scripts or systemd services
  • Production / deployment environments

⚙ Module Parameters — Configuring Your Module at Load Time

Rather than hardcoding values, you can expose parameters that can be set when loading the module. This is done with the module_param() macro.

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

/* Declare a parameter with a default value */
static int my_count = 5;
static char *my_name = "default";

/* Register the parameters:
 * module_param(variable, type, permissions)
 *   permissions = 0644 makes it readable/writable via /sys/module
 *   permissions = 0    means do not create a sysfs entry
 */
module_param(my_count, int, 0644);
MODULE_PARM_DESC(my_count, "Number of iterations (default: 5)");

module_param(my_name, charp, 0444);
MODULE_PARM_DESC(my_name, "A name string (default: default)");

MODULE_LICENSE("GPL");

static int __init param_init(void)
{
    pr_info("my_count = %d\n", my_count);
    pr_info("my_name  = %s\n", my_name);
    return 0;
}

static void __exit param_exit(void)
{
    pr_info("Goodbye!\n");
}

module_init(param_init);
module_exit(param_exit);

Now you can pass values at load time:

# Load with custom parameters:
sudo insmod param_module.ko my_count=10 my_name="EmbeddedPathashala"

# Verify via dmesg:
dmesg | tail -3
# [1234.0] my_count = 10
# [1234.1] my_name  = EmbeddedPathashala

# Read/write parameters at runtime via sysfs (since we used 0644):
cat /sys/module/param_module/parameters/my_count
echo 20 | sudo tee /sys/module/param_module/parameters/my_count

Supported parameter types: bool, int, uint, long, ulong, short, ushort, charp (char pointer / string), byte.

📄 Module Information in /proc and /sys

The kernel exposes module information through two virtual filesystems:

# /proc/modules — the raw data that lsmod reads:
cat /proc/modules | head -5
# hello 16384 0 - Live 0xffffffffc0a00000
# bluetooth 720896 42 btusb,rfcomm,... Live 0xffffffffc0b00000

# Each line: name, size, usecount, depends, state, address

# /sys/module/ — a directory per loaded module:
ls /sys/module/hello/
# coresize  holders  initsize  initstate  notes  refcnt  sections  taint

# Module state:
cat /sys/module/hello/initstate
# live

# Module parameters (if any):
ls /sys/module/bluetooth/parameters/
# disable_esco  enable_ecred  enable_mgmt  ...

The /sys/module/<name>/parameters/ directory gives you a file for each exposed parameter. Files with permission 0644 can be both read and written at runtime.

🏆 Interview Questions — Module Operations
Q1. What is the difference between insmod and modprobe?
insmod loads a specific .ko file directly without resolving dependencies. modprobe uses the module dependency database in /lib/modules to find the module by name and automatically loads all required dependencies first. modprobe is preferred in production; insmod is used during development.
Q2. How do you pass parameters to a kernel module?
Using the module_param() macro in the module source to declare parameters, then passing them on the command line: insmod mymod.ko param1=value1, or modprobe mymod param1=value1. Parameters with non-zero sysfs permissions can also be read/written at runtime through /sys/module/modname/parameters/.
Q3. What does the third column in lsmod output tell you?
It is the use count — how many things are currently using this module. If it is 0, the module can be safely removed. If it is greater than 0, the module is in use. The column also shows the names of other modules that depend on this one.
Q4. What does depmod do and when do you need to run it?
depmod scans all modules in /lib/modules/$(uname -r)/ and rebuilds the modules.dep, modules.alias, and related files that modprobe uses for dependency resolution. You need to run depmod -a whenever you add, remove, or update a module in /lib/modules — otherwise modprobe will not know the new module exists.
Q5. How can you make modules load automatically at boot?
On systemd systems, add the module name to a file in /etc/modules-load.d/ (e.g., /etc/modules-load.d/mymodule.conf containing just “mymodule”). For parameters, add a file in /etc/modprobe.d/ (e.g., options mymodule my_param=10). The older /etc/modules file still works on many distributions.

Up Next: Part 5 — Kernel Logging and printk
Deep dive into printk, log levels, pr_* macros, dmesg, and the kernel ring buffer.

← Part 3
Part 5: printk & Logging →

Previous Lecture
Next  Lecture

Leave a Reply

Your email address will not be published. Required fields are marked *