You know that moment when you plug in a USB device and it just works? Or when you connect to WiFi and everything magically happens? That's kernel modules working behind the scenes. Today, I want to pull back the curtain and show you the engine that makes Linux tick.
Don't worry—we're going to make this beginner-friendly. I remember when someone first mentioned "kernel modules" to me, and I thought it sounded impossibly complex. But once I understood what they actually do, it was like finally understanding how the magic tricks work.
Think of the Linux kernel as the brain of your computer. But unlike a human brain that's fixed, the Linux kernel is modular—you can add and remove pieces while it's running.
Imagine your Linux system as a busy restaurant:
- The Kitchen (Kernel): The core area where all the cooking happens
When a customer orders sushi (you plug in a USB device), the restaurant manager (kernel) calls in the sushi specialist (USB module) to handle that specific task.
Without modules: Your kernel would need to include every possible driver and feature, making it huge and slow.
With modules: Your kernel starts lean and fast, loading only what you need when you need it.
I'll never forget the first time I had to deal with kernel modules. I bought a new WiFi adapter, plugged it in, and... nothing. No internet. The device wasn't recognized.
My friend, a Linux veteran, typed a few commands:
lsmod | grep wifi
modprobe rtl8812au
Suddenly, my WiFi adapter worked! That was my first glimpse into the modular magic of Linux.
Every kernel module goes through these states:
1. Unloaded: Module exists as a file but isn't active 2. Loading: Module is being inserted into the kernel 3. Loaded: Module is active and providing functionality 4. Unloading: Module is being removed from the kernel
Let's trace what happens when you plug in a USB drive:
# Before plugging in the USB drive
lsmod | grep usb_storage
# (probably shows nothing)
# Plug in your USB drive
# The kernel automatically detects it and loads modules
# Check what modules are now loaded
lsmod | grep usb
You'll see modules like:
usb_storage
: Handles USB storage devicessd_mod
: SCSI disk support (USB drives use SCSI commands)usb_core
: Core USB functionality# List all loaded modules
lsmod
# Search for specific modules
lsmod | grep wifi
lsmod | grep bluetooth
lsmod | grep sound
Real example: When my sound stopped working, I ran:
lsmod | grep snd
And discovered the sound modules weren't loaded.
# Load a module
sudo modprobe module_name
# Load a module with parameters
sudo modprobe module_name parameter=value
Story time: I once had a graphics card that needed a specific parameter to work properly:
sudo modprobe nvidia nvidia-drm.modeset=1
# Remove a module
sudo modprobe -r module_name
# Force remove (be careful!)
sudo rmmod module_name
When I use this: Sometimes a WiFi module gets stuck and I need to reload it:
sudo modprobe -r iwlwifi
sudo modprobe iwlwifi
# Get detailed info about a module
modinfo module_name
# Example: Learn about your WiFi module
modinfo iwlwifi
This shows you:
Now that you understand modules, let's talk about system tuning—making your Linux system run better.
Linux has a special directory called /proc/sys
that contains files representing system settings. Think of it as your system's control panel, but in file form.
# Look at the system tuning categories
ls /proc/sys/
You'll see directories like:
vm/
: Virtual memory settingsnet/
: Network settingskernel/
: Kernel behavior settingsfs/
: Filesystem settings# Check current swappiness (how aggressively Linux uses swap)
cat /proc/sys/vm/swappiness
# Make it less likely to swap (good for systems with plenty of RAM)
echo 10 | sudo tee /proc/sys/vm/swappiness
What this does: By default, Linux might start swapping when RAM is 60% full. Setting it to 10 means it waits until RAM is 90% full.
# Increase network buffer sizes for better throughput
echo 16777216 | sudo tee /proc/sys/net/core/rmem_max
echo 16777216 | sudo tee /proc/sys/net/core/wmem_max
When this helps: If you're transferring large files over the network or running a web server.
# Increase the number of files that can be watched
echo 524288 | sudo tee /proc/sys/fs/inotify/max_user_watches
Real scenario: IDEs like VS Code use file watching. If you're working on large projects, you might hit the default limit.
The changes above only last until reboot. To make them permanent, edit /etc/sysctl.conf
:
# Edit the system configuration
sudo nano /etc/sysctl.conf
# Add your settings
vm.swappiness = 10
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
fs.inotify.max_user_watches = 524288
# Apply the changes
sudo sysctl -p
Let's create a "Hello World" kernel module. Don't worry—it's simpler than you think!
Create a file called hello.c
:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
// Function called when module is loaded
static int __init hello_init(void)
{
printk(KERN_INFO "Hello from the kernel!\n");
return 0; // 0 means success
}
// Function called when module is removed
static void __exit hello_exit(void)
{
printk(KERN_INFO "Goodbye from the kernel!\n");
}
// Register the functions
module_init(hello_init);
module_exit(hello_exit);
// Module information
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("A simple hello world module");
MODULE_VERSION("1.0");
Create a 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
# Install kernel headers (needed for compilation)
sudo apt install linux-headers-$(uname -r) # Ubuntu/Debian
sudo dnf install kernel-devel # Fedora
# Compile the module
make
# Load the module
sudo insmod hello.ko
# Check if it loaded
lsmod | grep hello
# Check kernel messages
dmesg | tail
# Remove the module
sudo rmmod hello
# Check kernel messages again
dmesg | tail
What you'll see: Messages like "Hello from the kernel!" and "Goodbye from the kernel!" in the kernel log.
# Check system load
uptime
# Monitor system resources
htop
iostat 1 # Disk I/O every second
sar 1 # System activity every second
Reading load averages: If you see "load average: 1.5, 1.2, 0.8", that means:
# Check memory usage
free -h
# Clear caches (safe, but usually unnecessary)
sudo sync
echo 3 | sudo tee /proc/sys/vm/drop_caches
When to use cache clearing: Almost never in normal operation. Linux manages caches very well.
# Check disk scheduler
cat /sys/block/sda/queue/scheduler
# Change to deadline scheduler (good for SSDs)
echo deadline | sudo tee /sys/block/sda/queue/scheduler
# Check disk stats
iostat -x 1
# Check what WiFi hardware you have
lspci | grep -i wireless
# Check available WiFi modules
find /lib/modules/$(uname -r) -name "*wifi*" -o -name "*wireless*"
# Try loading different modules
sudo modprobe iwlwifi # Intel
sudo modprobe ath9k # Atheros
sudo modprobe rt2800usb # Realtek USB
# Check graphics hardware
lspci | grep -i vga
# Check loaded graphics modules
lsmod | grep -i nvidia
lsmod | grep -i radeon
lsmod | grep -i intel
# Reload graphics module
sudo modprobe -r nvidia
sudo modprobe nvidia
# Check sound modules
lsmod | grep snd
# Reload ALSA
sudo modprobe -r snd_hda_intel
sudo modprobe snd_hda_intel
# Reset PulseAudio
pulseaudio -k
pulseaudio --start
# CPU usage
top
htop
# Memory usage
free -h
cat /proc/meminfo
# Disk usage
df -h
du -sh /home/*
# Network usage
nethogs # Per-process network usage
iftop # Network traffic
# Check CPU information
cat /proc/cpuinfo
# Count CPU cores
nproc
# Check CPU frequency
cat /proc/cpuinfo | grep MHz
1. Never load unknown modules: They run with full kernel privileges 2. Backup before tuning: System changes can make your system unstable 3. Test before permanent: Try settings temporarily before making them permanent 4. Document changes: Keep notes of what you've modified
# Boot with a different kernel (from GRUB menu)
# Usually shows up as "Advanced options"
# Reset all sysctl settings
sudo sysctl -p /etc/sysctl.conf
# Remove all custom modules
sudo modprobe -r module_name
# Reduce input lag
echo 1 | sudo tee /proc/sys/net/core/netdev_budget
# Prioritize performance over power saving
echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
# Increase file descriptor limits
echo 65536 | sudo tee /proc/sys/fs/file-max
# Optimize TCP settings
echo 1 | sudo tee /proc/sys/net/ipv4/tcp_window_scaling
echo 1 | sudo tee /proc/sys/net/ipv4/tcp_timestamps
# Increase inotify limits for file watching
echo 524288 | sudo tee /proc/sys/fs/inotify/max_user_watches
# Increase shared memory for IDEs
echo 268435456 | sudo tee /proc/sys/kernel/shmmax
Error: "Required key not available" Solution: Disable Secure Boot in BIOS, or sign the module
Error: "Invalid module format" Solution: Module was compiled for different kernel version
Error: "Device or resource busy" Solution: Something is using the device; find and stop it
1. Try Ctrl+Alt+F2: Switch to text console 2. Magic SysRq keys: Alt+SysRq+R,E,I,S,U,B (safely reboot) 3. Boot from recovery: Use GRUB recovery mode
Understanding kernel modules and system tuning is like learning to be a mechanic for your Linux system. You don't need to know everything, but understanding the basics helps you:
- Troubleshoot hardware issues more effectively
You now understand:
The world of kernel modules and system tuning is vast, but you've got the foundation. From here, you can explore:
Remember: the kernel is powerful but fragile. Always test changes carefully, and don't be afraid to revert if something doesn't work as expected.