Skip to content
ALB Wiki

Diff — Inside a Linux System

Comparing rev 1 → rev 2

{{infobox
| title = Inside a Linux System
| chapter = Linux Handbook, chapter 17 — the boot sequence, init, services, the anatomy
| core | kernel + initramfs + PID 1 + services + login — the whole arc
| paths = SysVinit (the readable path) · systemd (the standard path)
| skills | boot chain · runlevels/units · service management · logs
| next | Networking — the system's window outward
}}
**A Linux system is an arc**: firmware hands to a bootloader, the bootloader hands to a kernel, the kernel mounts a rootfs and execs PID 1, PID 1 brings up services, services reach a login. This chapter walks the whole arc — both init paths (SysVinit's readable rc scripts and systemd's unit graph) — and teaches you to read and control the machine's own machinery.
## The boot chain — six handoffs
```
firmware → bootloader → kernel (+initramfs) → rootfs → PID 1 → services → login
```
1. **Firmware** — BIOS or UEFI — POSTs, finds a boot device, loads the bootloader. UEFI reads the ESP's `EFI/` tree.
2. **Bootloader** — GRUB (usually) — presents the menu, loads `vmlinuz` + `initramfs` into memory, hands over with a kernel command line (`root=/dev/sda3 ro quiet`).
3. **Kernel** — decompresses, initializes drivers, mounts the rootfs, runs `/sbin/init` as **PID 1**. (The initramfs — a temporary rootfs in RAM — carries drivers the kernel needs to *reach* the real rootfs.)
4. **PID 1** — init — the ancestor of every process; brings the system to a usable state.
5. **Services** — gettys, daemons, network, logging — all spawned by init.
6. **Login** — a getty prompts; `login` checks `/etc/passwd`+shadow; a shell starts.
Each handoff is inspectable: `dmesg` is the kernel's own log of stage 3; `journalctl` or `/var/log/messages` covers stages 4–6.
## PID 1 — the two paths
### SysVinit — the readable path
```sh
cat /etc/inittab          # the runlevel map — id:3:initdefault:
ls /etc/rc.d/             # rc.S (sysinit) rc.M (multiuser) rc.6 (reboot) rc.inet1 rc.sshd
/etc/rc.d/rc.sshd restart # the interface — scripts you can READ
```
Inittab defines **runlevels** — 0 halt, 1 single-user, 3 multiuser (Slackware default), 4 X11, 6 reboot. `telinit 3` changes them. Services are `rc.*` shell scripts, started in order. The beauty: **it's all shell** — `cat /etc/rc.d/rc.M` shows you *exactly* what boot does. Slackware's entire init system fits in a few readable scripts.
### systemd — the standard path
```sh
systemctl status sshd        # state of a unit
systemctl start sshd         # bring up
systemctl enable sshd        # start at boot
systemctl list-units --type=service
systemctl list-dependencies  # the dependency graph
systemctl isolate multi-user.target   # the "runlevel" equivalent
journalctl -u sshd           # the unit's log
journalctl -b                # this boot's whole log
journalctl -f                # follow live
```
Systemd replaces scripts with **units** — declarative files in `/etc/systemd/system/` + `/usr/lib/systemd/system/` — started by dependency order, not sequence. Faster, parallel, self-logging — and opaque in ways SysVinit never is. `.service`, `.mount`, `.socket`, `.timer`, `.target` — the unit types; `.target`s are the runlevel analogues (`multi-user.target` ≈ runlevel 3).
## The services' plumbing
**gettys** — the login prompts: one per virtual console (`Ctrl-Alt-F2` switches). Inittab's `c1:12345:respawn:/sbin/agetty tty1` or systemd's `[email protected]` — `respawn` is the self-healing restart.
**Daemons** — long-running services — daemonize by detaching from the terminal (setsid, no tty); systemd manages them as units. Logs to syslog (`/var/log/messages`) or journald.
**Cron** — the scheduler: `crontab -e` — `0 3 * * * /usr/local/bin/backup` — minute hour day month weekday. `/etc/cron.daily/` et al. for the system. systemd **timers** are the modern unit-based equivalent.
+
## systemd units — the anatomy
+
+
```ini
+
# /etc/systemd/system/myservice.service — a complete unit
+
[Unit]
+
Description=My service
+
After=network.target
+
Wants=network-online.target
+
+
[Service]
+
Type=simple                    # simple|forking|oneshot|notify|dbus|idle|exec
+
ExecStart=/usr/bin/myservice --flag
+
ExecReload=/bin/kill -HUP $MAINPID
+
Restart=on-failure             # always|on-success|on-failure|no
+
RestartSec=5
+
User=mysvc
+
Group=mysvc
+
WorkingDirectory=/var/lib/mysvc
+
Environment=VAR=val
+
ExecStartPre=/usr/bin/precheck
+
ExecStartPost=/usr/bin/post
+
LimitNOFILE=65536
+
ProtectSystem=strict           # read-only /
+
PrivateTmp=true                # own /tmp
+
NoNewPrivileges=true
+
+
[Install]
+
WantedBy=multi-user.target     # enable → symlink into the target's .wants/
+
```
+
+
The sections: `[Unit]` dependencies, `[Service]` the process config, `[Install]` how `enable` wires it into boot. `Type=` is the contract — `simple` (foreground), `forking` (daemonizes), `oneshot` (runs once), `notify` (sd_notify protocol). `systemctl daemon-reload` after editing; `systemctl cat` shows the composed unit.
+
+
## The unit types
+
+
`.service` processes · `.socket` socket-activation · `.timer` cron-replacement · `.mount` mounts · `.automount` lazy-mounts · `.target` runlevel-groups · `.path` inotify triggers · `.slice` cgroup buckets · `.device` udev-derived. `systemctl list-units --type=service` enumerates.
+
+
## The journal — structured logging
+
+
```sh
+
journalctl --list-boots             # every boot, ever — pick one to read
+
journalctl _PID=1234                # by process
+
journalctl -g 'pattern'             # grep the journal
+
journalctl -o json-pretty           # structured output
+
journalctl --priority=emerg..err    # level band
+
journalctl _SYSTEMD_UNIT=sshd.service _COMM=sshd
+
```
+
+
Fields are queryable (`_PID`, `_COMM`, `_SYSTEMD_UNIT`) — journald is a queryable database, not text files.
+
## The kernel's own interfaces
- **`dmesg`** — the kernel ring buffer: hardware detection, driver loads, oopses — boot's transcript
- **`/proc`** — processes + kernel state as files
- **`/sys`** — devices/drivers as a browsable object tree
- **`sysctl`/`/proc/sys`** — live kernel knobs: `sysctl -w net.ipv4.ip_forward=1`
- **`modprobe`**/`lsmod`/`modinfo` — loadable modules — the driver's hotplug layer
## Runlevels / targets — the modes
```sh
runlevel              # SysV — where you are
telinit 1             # single-user — maintenance mode (the rescue level)
telinit 3             # multiuser text
telinit 6             # reboot
systemctl isolate rescue.target     # systemd's single-user
systemctl reboot / poweroff         # the controlled shutdowns
shutdown -h now                     # traditional halt
```
Runlevel 1 / `rescue.target` — single-user mode — is the maintenance door: minimal services, root shell, the place filesystem checks and password resets happen. The kernel command line's `single` or `init=/bin/bash` boots straight there — the rescue technique of last resort.
## The LFS system's boot — what you built
The LFS SysVinit path installs `sysvinit` + `sysklogd` + the boot scripts — `/etc/rc.d/init.d/` scripts for cleanfs, modules, network, sysklogd — a minimal but *legible* init. Chapter 6's `/etc/inittab` + fstab + rc scripts are the whole machine's waking machinery — you wrote them from nothing.
## Where the system goes wrong
| Symptom | Cause |
| --- | --- |
| Boots to `grub>` or rescue | Bootloader/config — chapter 6 territory |
| Kernel panic — can't mount root | rootfs driver/filesystem not built-in |
| Boots, no login prompt | getty not spawning — inittab/agetty |
| Service won't start | `systemctl status`/`journalctl -u` — or the rc script's exit code |
| Slow boot | `systemd-analyze blame` — or a blocking rc script |
| `dmesg` flooded with errors | Driver/hardware — `dmesg -l err` filters |
| Can't change runlevel | systemd targets ≠ SysV runlevels — wrong tool for the init |
## Exercises
1. `dmesg | less` — read your kernel's boot transcript.
2. `cat /etc/inittab` (SysV) or `systemctl list-dependencies` (systemd) — the boot plan.
3. `pstree -p | head -20` — the fork family from PID 1.
4. `journalctl -b` or `less /var/log/messages` — this boot's log.
5. Switch a virtual console (Ctrl-Alt-F2); identify the getty that owns it.
6. `sysctl -a | less` — the kernel's tunable mind.
## Timeline
| Handoff | The mechanism |
| --- | --- |
| firmware | BIOS/UEFI → ESP/boot sector |
| bootloader | GRUB → vmlinuz + initramfs + cmdline |
| kernel | init → mount rootfs → /sbin/init |
| PID 1 | rc scripts or unit graph |
| services | gettys, daemons, network, logging |
| login | getty → login → shell |
## See also
- [[Linux]] · [[LFS Kernel and Boot]] · [[Processes]] · [[Filesystem]]
[[Category:Linux]]
[[Category:Handbook]]
[[Category:Boot]]