In the previous articles, the kernel initialized hardware, loaded drivers, and mounted the root filesystem. The kernel itself is not a program you interact with. It is the platform on which programs run. Now it needs to hand control to a program that will build the rest of the system -- start services, mount additional filesystems, configure networking, and eventually present you with a login prompt.
That program is process number one. Every other process on the system descends from it.
The Handoff
At the very end of kernel initialization, the kernel calls a function named kernel_init. This function does one thing: it looks for an executable to run as the first userspace process. The kernel searches a short list of paths in order:
- Whatever was passed as
init=on the kernel command line /sbin/init/etc/init/bin/init/bin/sh(last resort)
When it finds one, the kernel creates a new process, assigns it PID 1 (process identifier 1), and executes the program. From this moment forward, the kernel's job is to provide system calls and manage hardware. PID 1 is responsible for everything else.
Why PID 1 Is Special
PID 1 is not just the first process. The kernel treats it differently from every other process on the system.
It cannot be killed. The kernel will not deliver fatal signals to PID 1 unless PID 1 has explicitly registered a handler for that signal. If you run kill -9 1 as root, nothing happens. On any other process, signal 9 (SIGKILL) is instant, unavoidable death. PID 1 is immune. If PID 1 dies, the kernel panics and the system halts.
It adopts orphans. When a process dies, its children need a parent. The kernel reassigns orphaned children to PID 1. This prevents the process table from filling with unmanaged entries.
It reaps zombies. When a child process exits, it lingers as a zombie until its parent reads the exit status. PID 1 must periodically call wait() to collect these dead children. If it does not, zombie processes accumulate.
These responsibilities make PID 1 the most critical userspace program on the system. Everything else can crash and be restarted. PID 1 must keep running from the moment it starts until the system shuts down.
A Brief History of Init
The concept of a first process dates back to the earliest Unix systems in the 1970s. Over the decades, several implementations have competed for the role.
SysV Init
The original System V init, dating to the early 1980s, is the simplest design. It reads a file called /etc/inittab that defines runlevels -- numbered operating modes for the system.
| Runlevel | Purpose |
|---|---|
| 0 | Halt (shut down) |
| 1 | Single-user mode (maintenance) |
| 2 | Multi-user, no networking |
| 3 | Multi-user with networking |
| 5 | Multi-user with networking and GUI |
| 6 | Reboot |
SysV init starts services by running shell scripts sequentially. The scripts live in directories like /etc/rc3.d/ (for runlevel 3). Each script is named with a prefix like S01 or K99 -- the letter indicates start or kill, and the number sets the order.
This design is simple to understand but slow. Services start one at a time, in a fixed order, even when they have no dependency on each other. On modern hardware with dozens of services, booting with SysV init takes noticeably longer than it should.
Upstart
Ubuntu introduced Upstart in 2006 as an event-driven replacement for SysV init. Instead of fixed runlevels and sequential scripts, Upstart could react to events -- "when the network is up, start the web server." This was a significant improvement, but Upstart's event model was complex and its adoption remained limited to Ubuntu and a few other distributions.
systemd
In 2010, Lennart Poettering and Kay Sievers created systemd. By 2015, virtually every major Linux distribution had adopted it. systemd is what you are almost certainly running today.
systemd replaced more than just the init process. It absorbed functionality that was previously scattered across dozens of separate tools: service management, logging, device management, login tracking, time synchronization, DNS resolution, and more. This consolidation is both its greatest strength and its most frequent criticism.
How systemd Works
systemd organizes the system around units. A unit is a configuration file that describes a resource the system manages. There are several types:
| Unit Type | File Extension | Purpose |
|---|---|---|
| Service | .service | A daemon or one-shot program |
| Target | .target | A group of units (replaces runlevels) |
| Mount | .mount | A filesystem mount point |
| Socket | .socket | A network or IPC socket |
| Timer | .timer | A scheduled task (replaces cron) |
| Device | .device | A kernel device |
Unit files live in /usr/lib/systemd/system/ (distribution defaults) and /etc/systemd/system/ (administrator overrides). When both exist for the same unit, the /etc version wins.
Targets Replace Runlevels
systemd does not use runlevels. Instead, it uses targets -- units that group other units together. The mapping is roughly:
| SysV Runlevel | systemd Target |
|---|---|
| 0 | poweroff.target |
| 1 | rescue.target |
| 3 | multi-user.target |
| 5 | graphical.target |
| 6 | reboot.target |
The default target is usually graphical.target on desktop systems and multi-user.target on servers. You can check your system's default with:
systemctl get-default
Parallel Startup
The most visible improvement systemd brings is parallelism. SysV init starts services one at a time. systemd reads all the unit files, builds a dependency graph, and starts everything it can simultaneously.
If service A and service B have no dependency on each other, they start at the same time. If service C depends on A, it waits only for A and starts as soon as A reports ready. This can cut boot times in half or better.
A Service Unit File
Here is a typical service unit file:
[Unit]
Description=OpenSSH Daemon
After=network.target
[Service]
Type=notify
ExecStart=/usr/sbin/sshd -D
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
[Install]
WantedBy=multi-user.target
The [Unit] section declares ordering -- this service should start after the network is available. The [Service] section defines how to run the program. Type=notify means the service will explicitly tell systemd when it is ready. Restart=on-failure means systemd will restart it if it crashes. The [Install] section says that when this service is enabled, it becomes part of multi-user.target.
Managing Services with systemctl
systemctl is the command you use to interact with systemd. The essential operations:
systemctl start sshd # Start a service now
systemctl stop sshd # Stop a service now
systemctl restart sshd # Stop, then start
systemctl status sshd # Show current state
systemctl enable sshd # Start at boot
systemctl disable sshd # Do not start at boot
systemctl is-active sshd # Check if running
enable and disable control what happens at boot. start and stop control what is happening right now. They are independent -- you can start a service without enabling it, or enable it without starting it immediately.
The Boot Sequence Under systemd
When the kernel starts systemd as PID 1, the boot proceeds through a predictable chain of targets:
- sysinit.target -- mount essential filesystems, load kernel modules, activate swap, seed the random number generator.
- basic.target -- start logging, timers, and socket activation.
- multi-user.target -- start all non-graphical services: networking, SSH, databases, web servers.
- graphical.target (if configured) -- start the display manager and desktop environment.
Each target pulls in the targets before it through dependency chains. systemd resolves the entire graph at once and starts everything it can in parallel, only serializing where an explicit ordering exists.
The Journal
systemd includes its own logging system called the journal, managed by journald. Instead of plain text files in /var/log/, the journal stores structured, indexed, binary log entries.
journalctl -u sshd # Logs from sshd
journalctl -b # Logs from current boot
journalctl --since "1 hour ago"
journalctl -f # Follow new entries (like tail -f)
The journal captures both stdout and stderr from every service. This means you do not need to configure logging in each service individually -- systemd captures it all.
Controversy and Alternatives
systemd's expansion beyond a simple init replacement has drawn criticism. Some argue it violates the Unix philosophy of small, focused tools. Others worry about the complexity of depending on a single project for so many system functions.
Alternatives exist. OpenRC is used by Gentoo and Alpine Linux. runit is used by Void Linux. s6 is a supervision suite popular in container images. Each takes a more minimal approach, managing services without absorbing logging, networking, and device management.
For learning purposes, understanding systemd is essential -- it runs on the vast majority of Linux installations. But it is worth knowing that PID 1 does not have to be this complex. The kernel only requires that something runs as PID 1, reaps zombies, and adopts orphans. Everything else is a design choice.
What PID 1 Means for You
When you sit down at a Linux system and see a login prompt, that prompt exists because PID 1 started a chain of services that made it possible. The network works because PID 1 started NetworkManager. Your SSH sessions work because PID 1 started sshd. Your disk is mounted because PID 1 triggered the mount units.
If a service is not running, systemctl status will tell you why. If the system will not boot, understanding the target chain tells you where to look. PID 1 is the root of the entire userspace tree, and every other process on the system exists because, directly or indirectly, PID 1 started it.
Next: The Process Model