rmmod
lsmod
modinfo
modprobe
depmod
Module Parameters
/proc/modules
/sys/module
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.
| 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 (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
.kofile. - It is a low-level tool — use it during development when you are working with modules not yet installed in
/lib/modules.
# 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 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:
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 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 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:
- 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
- Module is installed in /lib/modules
- Module has dependencies
- Writing init scripts or systemd services
- Production / deployment environments
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.
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.
