The Linux kernel is the single program that owns your hardware. It schedules CPU time, maps memory, drives devices, and enforces permissions for every process on the machine. Everything else, from bash to nginx, is a userspace program that asks the kernel for services through system calls. This guide covers how the kernel is structured, how modules extend it at runtime, how a machine travels from power-on to a login prompt, and how to fix the most common failures along the way.
Quick Takeaways
- The Linux kernel is a monolithic kernel with loadable modules. Core subsystems run in one address space, and drivers can load or unload without a reboot.
- Userspace talks to the kernel through system calls. Hardware talks to it through interrupts.
- Boot flows through firmware, bootloader (GRUB), kernel decompression, initramfs, then
systemdas PID 1. - Use
lsmod,modinfo,modprobe, anddmesgfor nearly all day-to-day kernel inspection.
| Component | Role | Where to inspect |
|---|---|---|
| Kernel image | The running kernel | /boot/vmlinuz-* |
| initramfs | Temporary root with early drivers | /boot/initramfs-* or initrd.img-* |
| Kernel modules | Loadable drivers and features | /lib/modules/$(uname -r)/ |
| Kernel parameters | Runtime tunables | /proc/sys/, sysctl |
| Ring buffer | Kernel log messages | dmesg, journalctl -k |
Prerequisites
You need a Linux system with root or sudo access. The examples work on Debian, Ubuntu, Fedora, RHEL, Rocky Linux, and Arch with minor package-manager differences. Check your current kernel first:
uname -r # kernel release string
uname -a # full system and kernel info
cat /proc/version # kernel version and compiler used
-rprints only the release, such as6.8.0-45-generic.-aadds hostname, architecture, and build date.
What the Kernel Actually Does
The kernel sits between hardware and applications. It performs five core jobs:
- Process management: creates, schedules, and terminates tasks.
- Memory management: virtual memory, paging, swapping, and the page cache.
- Device management: drivers expose hardware through files in
/dev. - Filesystem management: the Virtual File System (VFS) presents ext4, XFS, Btrfs, and NFS through one interface.
- Networking: the TCP/IP stack, netfilter, and socket layer.
Kernel Space vs. User Space
The CPU enforces two privilege levels. Kernel code runs in ring 0 with unrestricted hardware access. Applications run in ring 3 and cannot touch hardware or other processes’ memory directly. A program crosses the boundary through a system call, such as read(), write(), open(), or fork().
Watch system calls live with strace:
strace -c ls /etc
-cprints a summary table of syscall counts and time spent.
Linux Kernel Architecture
Linux uses a monolithic design. The scheduler, memory manager, VFS, network stack, and most drivers share one address space. That reduces context-switch overhead and keeps performance high. The cost is that a faulty driver can crash the whole system, which is why a bad module produces a kernel panic rather than a polite error.
Major Subsystems
| Subsystem | Responsibility | Key Interface |
|---|---|---|
| Process Scheduler (CFS/EEVDF) | Divides CPU time among tasks | /proc/sched_debug, nice, chrt |
| Memory Manager | Virtual memory, paging, OOM killer | /proc/meminfo, vm.* sysctls |
| Virtual File System | Unified filesystem abstraction | /proc/filesystems, mount |
| Network Stack | Sockets, TCP/IP, netfilter | ss, ip, net.* sysctls |
| Device Drivers | Hardware control | /dev, /sys |
| Security (LSM) | SELinux, AppArmor hooks | /sys/kernel/security |
| IPC | Pipes, shared memory, semaphores | ipcs |
Recent kernels replaced the long-standing Completely Fair Scheduler with EEVDF (Earliest Eligible Virtual Deadline First), starting in kernel 6.6. Both aim for proportional CPU sharing with low latency.
Monolithic vs. Microkernel vs. Hybrid
| Attribute | Monolithic (Linux) | Microkernel (Minix, QNX) | Hybrid (Windows NT, XNU) |
|---|---|---|---|
| Drivers run in | Kernel space | User space | Mixed |
| Performance | High, few context switches | Lower, heavy IPC | Moderate to high |
| Fault isolation | Weak | Strong | Moderate |
| Complexity | Large single codebase | Small core, many services | Layered |
| Extensibility | Loadable modules | Servers in userspace | Drivers and subsystems |
The /proc and /sys Interfaces
The kernel exports its internal state as virtual files.
/procexposes process info and kernel tunables (/proc/cpuinfo,/proc/meminfo,/proc/<PID>/)./sysexposes the device model, one directory per device and driver./devholds device nodes managed byudev.
cat /proc/meminfo | head -5
ls /sys/class/net/
Kernel Modules
A loadable kernel module (LKM) is an object file with a .ko extension that attaches to the running kernel. Modules let you add filesystems, network drivers, and GPU drivers without recompiling or rebooting. They live under /lib/modules/$(uname -r)/.
Listing and Inspecting Modules
lsmod
modinfo ext4
lsmodlists loaded modules, their size, and a use count with dependents.modinfoshows the module’s description, author, license, parameters, and dependencies.
Loading and Unloading
sudo modprobe vfat # load module and its dependencies
sudo modprobe -r vfat # unload module and unused dependencies
sudo insmod ./mydriver.ko # load a specific file, no dependency resolution
sudo rmmod mydriver # remove a module directly
Prefer modprobe over insmod. It reads /lib/modules/$(uname -r)/modules.dep and resolves dependencies automatically. Pass options at load time:
sudo modprobe usbcore autosuspend=-1
Making Module Settings Persistent
Create a file in /etc/modprobe.d/:
echo "options snd_hda_intel power_save=0" | sudo tee /etc/modprobe.d/audio.conf
Load a module at every boot with /etc/modules-load.d/:
echo "br_netfilter" | sudo tee /etc/modules-load.d/k8s.conf
Block a module you never want loaded:
echo "blacklist nouveau" | sudo tee /etc/modprobe.d/blacklist-nouveau.conf
Rebuild the initramfs afterward so the change applies at early boot:
sudo update-initramfs -u # Debian/Ubuntu
sudo dracut --force # RHEL/Fedora/Rocky
Writing a Minimal Module
A tiny module shows the lifecycle: an init function on load, an exit function on unload.
#include <linux/module.h>
#include <linux/kernel.h>
static int __init hello_init(void) {
pr_info("hello: module loaded\n");
return 0;
}
static void __exit hello_exit(void) {
pr_info("hello: module unloaded\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Minimal example module");
Build it with a Kbuild 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 the headers first: sudo apt install linux-headers-$(uname -r) on Debian/Ubuntu. Then run:
make
sudo insmod hello.ko
sudo dmesg | tail -n 2
sudo rmmod hello
Module Signing and Secure Boot
With Secure Boot enabled, the kernel rejects unsigned modules. Check status with mokutil --sb-state. Sign third-party modules (NVIDIA, VirtualBox) with a Machine Owner Key (MOK) enrolled through mokutil --import. Verify enforcement with cat /proc/sys/kernel/modules_disabled and dmesg | grep -i "module verification".
How the Linux Kernel Boots
The boot process has six stages. Each hands control to the next.
| Stage | Component | What happens |
|---|---|---|
| 1 | UEFI/BIOS firmware | POST runs, hardware is initialized, boot device is chosen |
| 2 | Bootloader (GRUB2, systemd-boot) | Loads kernel image and initramfs into RAM |
| 3 | Kernel decompression | vmlinuz self-extracts, sets up CPU and memory |
| 4 | Kernel init | Mounts initramfs, initializes subsystems, loads early modules |
| 5 | initramfs | Finds and mounts the real root filesystem, then switch_root |
| 6 | systemd (PID 1) |
Starts services and targets until the login prompt |
Stage 1: Firmware
On UEFI systems, firmware reads the EFI System Partition (ESP), typically mounted at /boot/efi, and runs the bootloader binary. On legacy BIOS, it reads the first 440 bytes of the disk (the MBR boot code). Confirm your mode:
[ -d /sys/firmware/efi ] && echo "UEFI" || echo "Legacy BIOS"
Stage 2: Bootloader
GRUB2 reads /boot/grub/grub.cfg, which is generated from /etc/default/grub and scripts in /etc/grub.d/. Never edit grub.cfg directly. Edit /etc/default/grub, then regenerate:
sudo update-grub # Debian/Ubuntu
sudo grub2-mkconfig -o /boot/grub2/grub.cfg # RHEL/Fedora (BIOS)
Pass parameters to the kernel through the GRUB_CMDLINE_LINUX variable. View the current command line with:
cat /proc/cmdline
Stage 3 and 4: Kernel Startup
The bootloader loads vmlinuz, a compressed kernel image. The kernel decompresses itself, switches the CPU to its full operating mode, builds page tables, starts the scheduler, and initializes built-in drivers. Inspect this stage afterward:
dmesg | head -n 40
journalctl -k -b
-kfilters kernel messages.-blimits output to the current boot.
Stage 5: initramfs
The initramfs is a small compressed archive unpacked into a RAM-based root. It holds the drivers needed to reach the real root filesystem, such as NVMe, RAID, LVM, LUKS, and filesystem modules. Inspect its contents:
lsinitramfs /boot/initrd.img-$(uname -r) | head # Debian/Ubuntu
lsinitrd /boot/initramfs-$(uname -r).img | head # RHEL/Fedora
When the real root is mounted, the kernel runs switch_root and executes /sbin/init.
Stage 6: systemd
systemd runs as PID 1. It reads unit files from /etc/systemd/system/ and /usr/lib/systemd/system/, then reaches the default target (usually graphical.target or multi-user.target). Analyze boot time:
systemd-analyze
systemd-analyze blame | head
systemd-analyze critical-chain
blamelists units by startup time.critical-chainshows the dependency path that gated boot.
Kernel Parameters and Runtime Tuning
Tunables live under /proc/sys/ and are managed with sysctl.
sysctl vm.swappiness # read a value
sudo sysctl -w vm.swappiness=10 # change it until reboot
Persist settings in /etc/sysctl.d/99-custom.conf:
vm.swappiness = 10
net.core.somaxconn = 4096
net.ipv4.tcp_syncookies = 1
fs.file-max = 2097152
Apply without rebooting:
sudo sysctl --system
| Parameter | Default (typical) | Purpose | Server Recommendation |
|---|---|---|---|
vm.swappiness |
60 | Swap aggressiveness | 10 for databases |
net.core.somaxconn |
4096 (newer kernels) | Listen queue depth | Raise for busy web servers |
fs.file-max |
Varies | System-wide open file limit | Raise for high-concurrency apps |
kernel.panic |
0 | Seconds before auto-reboot after panic | 10 on unattended servers |
vm.overcommit_memory |
0 | Memory overcommit policy | 1 for Redis |
Choosing and Managing Kernel Versions
| Kernel Type | Example | Support Window | Best For |
|---|---|---|---|
| Mainline | 6.x latest | Short, until next release | Developers, new hardware |
| Stable | 6.x.y | A few months | Rolling-release desktops |
| LTS | 5.15, 6.1, 6.6 | Multi-year (2 to 6 years) | Production servers |
| Distro kernel | RHEL 5.14, Ubuntu HWE | Vendor-defined, backported patches | Enterprise environments |
List installed kernels and remove old ones to reclaim /boot space:
dpkg --list | grep linux-image # Debian/Ubuntu
sudo apt autoremove --purge # remove unused kernels
rpm -q kernel # RHEL/Fedora
sudo dnf remove --oldinstallonly # remove old kernels
Set the default boot entry on GRUB systems:
sudo grubby --default-kernel # RHEL/Fedora: show default
sudo grubby --set-default /boot/vmlinuz-<version>
Real-World Troubleshooting
Fixing GRUB Bootloader Corruption (UEFI)
Symptom: the machine drops to a grub> or grub rescue> prompt.
- Boot a live USB of your distribution.
- Identify partitions:
lsblk -f
- Mount the root and ESP, then chroot:
sudo mount /dev/nvme0n1p2 /mnt
sudo mount /dev/nvme0n1p1 /mnt/boot/efi
for d in dev proc sys run; do sudo mount --rbind /$d /mnt/$d; done
sudo chroot /mnt
- Reinstall and regenerate:
grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=GRUB
update-grub
exit
Replace the device names with the output of lsblk. Reboot after unmounting.
Fixing “Kernel Panic: VFS: Unable to mount root fs”
This error means the kernel could not find or mount the root filesystem. Common causes are a missing initramfs driver or a wrong root= parameter.
- At GRUB, pick an older kernel entry under Advanced options.
- Once booted, rebuild the initramfs for the broken kernel:
sudo update-initramfs -c -k <version> # Debian/Ubuntu
sudo dracut --force --kver <version> # RHEL/Fedora
- Confirm the
root=value matchesblkidoutput, then runsudo update-grub.
Diagnosing a Misbehaving Module
dmesg --level=err,warn | tail -n 30
lsmod | grep <module>
sudo modprobe -r <module> && sudo modprobe <module>
If a module hangs a boot, add modprobe.blacklist=<module> to the kernel command line from the GRUB edit screen (press e) to boot without it.
Preventing Disk Saturation From Kernel Logs
Unbounded journals can fill /var. Cap them in /etc/systemd/journald.conf:
[Journal]
SystemMaxUse=500M
MaxRetentionSec=1month
Apply with sudo systemctl restart systemd-journald.
Recovering With Single-User Mode
Edit the GRUB entry, append systemd.unit=rescue.target (or init=/bin/bash for a bare shell) to the linux line, and press Ctrl+X. Remount root as writable with mount -o remount,rw / before making changes.
Verification Checklist
After any kernel, module, or boot change, confirm the result:
uname -r # running kernel matches expectation
cat /proc/cmdline # parameters applied
lsmod | grep <module> # module loaded
systemctl --failed # no failed units
journalctl -p 3 -b # no error-level messages this boot
FAQ
What is the Linux kernel in simple terms?
The Linux kernel is the core program of the operating system. It manages CPU, memory, devices, and filesystems, and gives applications controlled access to them through system calls. Distributions such as Ubuntu and Fedora bundle it with userspace tools.
What is the difference between a kernel module and a driver?
A driver is code that controls hardware. A kernel module is a packaging format that lets that code load and unload at runtime. Many drivers ship as modules, but others are compiled directly into the kernel image.
How do I check which Linux kernel version I’m running?
Run uname -r for the release string or cat /proc/version for build details. Both commands read from the running kernel, so they reflect what is actually loaded, not just what is installed.
How does the Linux boot process work step by step?
Firmware runs POST and launches the bootloader. The bootloader loads vmlinuz and the initramfs. The kernel initializes hardware, mounts the real root filesystem via initramfs, and starts systemd as PID 1, which brings up services and reaches the default target.




