Chapter 22 — Init systems, kernel modules, and device drivers
In one sentence
The init system (PID 1) starts and supervises every other process on the machine in the right order, while kernel modules and device drivers are how the kernel supports new hardware and features without needing to be entirely recompiled for each one.
Why this matters
systemctl status, systemctl restart, and journalctl -u <service> are
commands you will run constantly in any real Linux role — knowing what's
actually happening underneath makes them far more useful than memorised
incantations.
How it actually works
THE INIT SYSTEM'S JOB: start services (networking, logging, your
database, your web server) in the correct ORDER (some depend on
others being up first), keep track of what's supposed to be running,
RESTART things that crash unexpectedly (if configured to), and clean
up properly on shutdown.
SYSTEMD (the default init system on most major Linux distributions
today -- Debian, Ubuntu, RHEL/Fedora, and others) organises this
around UNIT FILES: small config files describing a service, what it
depends on, how to start/stop/restart it, and when it should run.
$ systemctl status nginx # is it running? recent log lines?
$ systemctl start|stop|restart nginx
$ systemctl enable nginx # start automatically on boot
$ journalctl -u nginx # this service's own logs
# (Chapter 34 covers this properly)
KERNEL MODULES let the kernel load ADDITIONAL CODE -- typically
device drivers, but also filesystem implementations and other
optional functionality -- WITHOUT needing to be entirely recompiled.
A module is loaded on demand (when the hardware/feature is actually
needed) or explicitly:
$ lsmod # what's currently loaded
$ modprobe some_module # load a module (and its dependencies)
$ rmmod some_module # unload one (if nothing's using it)
A DEVICE DRIVER is the specific kernel code that knows how to talk to
a particular piece of hardware (a network card, a disk controller, a
GPU) -- translating the KERNEL's generic notion of "read some bytes
from this block device" into the exact commands THAT SPECIFIC
hardware chip understands. This is the layer that makes the rest of
the OS's abstractions (Chapter 1's "lies") possible at all: the
kernel doesn't need to know the details of every disk controller ever
made, because each one's driver handles that translation.
Real-world example
The move from SysVinit (the older, decades-standard Unix init
system, based on sequential shell scripts) TO systemd is one of the
most publicly, extensively DEBATED changes in Linux's recent history
-- Debian's own Technical Committee held a formal, documented,
contentious vote on the matter in 2014 (its minutes and the public
mailing-list debate are still findable and make for a genuinely
interesting real look at how a major open-source project makes a
consequential technical decision). systemd's designer, Lennart
Poettering, argued publicly for its core advantages: PARALLELISED
service startup (SysVinit's sequential scripts started services one
at a time, in a fixed order, which was slow; systemd could start
INDEPENDENT services simultaneously, dramatically speeding up boot
times on modern multi-core hardware) and built-in SERVICE
SUPERVISION (automatically restarting a crashed service, something
SysVinit didn't do natively). Critics raised real, substantive
concerns about scope creep (systemd grew to manage far more than
just process startup -- logging, networking, and more) and
architectural philosophy (Debated: whether bundling so much
functionality into one project violates the traditional Unix
philosophy of small, focused tools). Today, systemd is the default
on most major distributions, but the debate itself remains a genuinely
useful real case study in trade-offs between "simple and well
understood" and "more capable but more complex."
Try it yourself
# Explore your own init system
systemctl list-units --type=service --state=running | head -15
systemctl status ssh 2>/dev/null || systemctl status sshd 2>/dev/null
# See which services are set to auto-start on boot
systemctl list-unit-files --type=service --state=enabled | head -10
# See kernel modules currently loaded, and pick one to inspect
lsmod | head -10
modinfo $(lsmod | awk 'NR==2{print $1}') 2>/dev/null | head -10
# See how long your boot took, and what was slowest
systemd-analyze 2>/dev/null
systemd-analyze blame 2>/dev/null | head -5
Common mistakes
- Using
service <name> restartandsystemctl restart <name>interchangeably without knowing which init system you actually have. Most modern distros alias the old commands to systemd equivalents, but don't assume this on every system you touch. - Forgetting
systemctl enablevssystemctl startare different.startruns it now;enablemakes it start automatically on the NEXT boot. You often want both, and forgettingenableis a common real cause of "the service was fine, then the server rebooted and it wasn't running." - Assuming a loaded kernel module means the hardware is working correctly. The module loading successfully means the DRIVER is present; it doesn't guarantee the underlying hardware itself is functioning correctly.
Check yourself
- What is a unit file, and what does
systemctl enabledo thatsystemctl startdoesn't? - What is a kernel module, and why does the kernel support loading them dynamically instead of compiling everything in?
- Name one concrete advantage systemd's designers argued for over SysVinit, and one substantive criticism raised against it.
Further reading
- Reference:
man 1 systemctl,man 5 systemd.unit,man 8 modprobe. - Docs:
freedesktop.org's systemd documentation — the authoritative source, maintained by the project itself. - History: search "Debian technical committee init system 2014" for the public debate and its resolution — a genuinely worthwhile real case study.
End of Phase 1 — Milestone check
- I can explain what "the OS" is actually doing for every program I run, in plain language
- I understand the kernel/user-space boundary and what a syscall is
- I can trace a process's full life: fork, exec, running, exiting, and being reaped
- I know the difference between a thread and a process, and why that distinction matters for safety and performance
- I can read process states (
R/S/D/Z/T) and use them to diagnose "what is this process actually doing" - I understand virtual memory, page faults, and why
free -h's numbers often confuse people - I have watched a race condition produce a wrong answer, then fixed it with a lock
- I know what a signal is, and specifically why SIGTERM matters for graceful shutdown
- I can describe the boot chain from power-on to login prompt