9.1. Introduction

Chapter 9 explains how the finished system becomes a running Linux installation, from firmware handoff through dinit service supervision.

Goal: understand the boot path well enough to configure the system deliberately instead of treating startup as a pile of magic files.

The previous chapters built the operating system as a filesystem tree. Chapter 9 is about making that tree wake up as a machine: the kernel must be loaded, the root filesystem must become the active system root, runtime filesystems must appear, and a real init process must take responsibility for the rest of userspace.

Boot is mostly a handoff sequence. Each stage does only enough work to start the next stage, and the first long-running userspace process becomes the parent and coordinator for everything that follows.

The Boot Chain

A typical Linux boot begins in firmware. On modern machines that usually means UEFI. The firmware initializes enough hardware to read the EFI System Partition, then starts a bootloader or a directly bootable EFI program.

The bootloader chooses a kernel, passes a kernel command line, and may also load an initramfs. The command line tells the kernel important early facts, such as where the root filesystem is, whether it should initially be mounted read-only, and which program should be used as init if the default is not correct.

The kernel then takes over. It initializes CPU support, memory management, device discovery, filesystems, and driver infrastructure. At this stage there is no normal userspace yet. The kernel is building the environment that will allow userspace to exist.

If an initramfs is used, the kernel unpacks it into memory and starts its early userspace program first. That early userspace can load modules, unlock encrypted storage, assemble RAID or logical volumes, discover the real root filesystem, and then switch into it. A simple system can boot without an initramfs if the kernel already has everything it needs to find and mount the real root filesystem.

Once the real root filesystem is available, the kernel starts process ID 1. By default it looks for common init paths such as /sbin/init, but this can be overridden with the init= kernel command-line option. From this point on, the kernel is running the system, but init is running userspace.

Early Mounts

The root filesystem is only the beginning. Several important parts of a live Linux system are not ordinary on-disk directories. They are kernel-provided or memory-backed filesystems that must be mounted during early userspace startup.

/proc exposes process and kernel state. Tools such as ps, service supervisors, shells, and many scripts rely on it to inspect running processes and system information.

/sys exposes the kernel device model. It is the main structured view of devices, drivers, buses, block devices, network interfaces, power state, and many tunable kernel attributes.

/dev provides device nodes. On a static system it can contain pre-created nodes, but practical Linux systems usually mount a device filesystem there so device nodes can appear dynamically as the kernel discovers hardware.

/run is a small runtime state filesystem, normally backed by memory. It holds sockets, pid files, lock files, and other state that should not survive a reboot. dinit's system control socket lives here by default as /run/dinitctl.

Other mounts are added as the system becomes more complete. devpts supplies pseudo-terminals under /dev/pts. tmpfs mounts may provide /tmp or other volatile scratch locations. Real filesystems for home directories, boot partitions, removable media, or separate system areas are mounted according to local policy.

The important pattern is that init does not merely start daemons. It also establishes the shape of the running system: the root is checked or remounted as needed, kernel filesystems are mounted, runtime directories are prepared, and only then do higher-level services have a stable place to stand.

What dinit Is

dinit is the init system and service manager used by this book's target system. It can run as process ID 1, which makes it the first normal userspace process and the ancestor of system services. It can also supervise services, track dependencies between them, and provide a control interface through dinitctl.

dinit starts from service descriptions. A service description says what kind of service is being managed, what command starts it, what must start before it, what should wait for it, and how dinit should treat failures. Some services represent long-running processes. Others represent one-shot setup work, internal milestones, or scripted state changes.

This dependency model matters during boot. Instead of one long startup script where every line must be in exactly the right place, dinit can express relationships directly. A login service can wait for mounted filesystems. A network service can depend on device setup. A final boot target can collect the services that define a usable system.

dinit also remains useful after boot. dinitctl can start, stop, restart, enable, disable, and inspect services through the control socket. Because dinit keeps service state in memory, it knows whether a service is starting, started, stopping, failed, or waiting on another dependency.

Chapter Direction

Chapter 9 turns the completed package set into a bootable system. The work ahead is configuration rather than compilation: arrange early mounts, define the initial service graph, connect dinit to the system's chosen init path, and make sure the result is understandable enough to repair from a shell when something goes wrong.

The goal is not to hide boot behind a framework. The goal is to make the machine's startup path explicit, small enough to reason about, and sturdy enough to trust.