System Boot and systemd - GRUB, runlevels, systemctl
What You Will Achieve
- Explain the four boot stages in order (BIOS/UEFI to bootloader to kernel to init/systemd)
- Change GRUB2 settings safely through
/etc/default/grub - Control service start, stop, and autostart with
systemctl - Answer the mapping between boot targets and SysVinit runlevels
- Run a time-scheduled reboot or shutdown with
shutdown - Investigate boot-time logs with
dmesg/journalctl
This is the core of LPIC-1 objectives 101.2 "Boot the system" and 101.3 "Change runlevels / boot targets and shut down or reboot system". It is the foundation of server operations.
How Does the Boot Process Proceed?
From power-on to a usable system, Linux passes through four stages in order. Grasping this "baton relay" structure, where each stage loads the next, lets you isolate where a failure occurred.
| Stage | Owner | Main role |
|---|---|---|
| 1. Firmware | BIOS / UEFI | Hardware init, select boot device |
| 2. Bootloader | GRUB2 | Load kernel and initramfs into memory |
| 3. Kernel | Linux kernel | Detect hardware, mount the root filesystem |
| 4. init | systemd | Start services, reach a target |
BIOS loads the bootloader from the MBR (the first 512 bytes of the disk), while UEFI loads the bootloader (*.efi) from the EFI System Partition. In both environments, the major modern distributions use GRUB2 as the bootloader and systemd as the init system.
The initramfs (initial RAM filesystem) that the kernel loads is a temporary environment containing the drivers needed to mount the root filesystem. This allows mounting even when root sits on an encrypted volume, LVM, or special storage.
Where Do You Edit GRUB2 Settings?
GRUB2 behavior should be changed by editing /etc/default/grub and /etc/grub.d/ and then regenerating, not by editing the generated grub.cfg. Never edit grub.cfg directly.
The main GRUB2 files are as follows.
| File | Role |
|---|---|
/boot/grub/grub.cfg (Debian family) |
Generated final config. Do not edit directly |
/boot/grub2/grub.cfg (RHEL family) |
Same. The path differs by distribution |
/etc/default/grub |
Source of timeout, default entry, and kernel parameters |
/etc/grub.d/ |
Scripts that generate menu entries |
Representative items in /etc/default/grub.
GRUB_TIMEOUT=5 GRUB_DEFAULT=0 GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
GRUB_TIMEOUT is the menu display seconds, GRUB_DEFAULT is the entry selected by default, and GRUB_CMDLINE_LINUX_DEFAULT is the boot parameters passed to the kernel.
Regenerate grub.cfg
After editing, regenerate grub.cfg to apply changes. The command name differs by distribution.
sudo grub-mkconfig -o /boot/grub/grub.cfg
Generating grub configuration file ... Found linux image: /boot/vmlinuz-6.1.0-18-amd64 Found initrd image: /boot/initrd.img-6.1.0-18-amd64 done
The Debian / Ubuntu family has update-grub, which wraps the above. The RHEL / Fedora family uses grub2-mkconfig -o /boot/grub2/grub.cfg.
| Distribution | Regenerate command | Output |
|---|---|---|
| Debian / Ubuntu | update-grub or grub-mkconfig -o ... |
/boot/grub/grub.cfg |
| RHEL / Fedora / CentOS | grub2-mkconfig -o ... |
/boot/grub2/grub.cfg |
Even if you edit grub.cfg directly, it is overwritten and lost the next time grub-mkconfig runs. For permanent changes, always edit /etc/default/grub or /etc/grub.d/ and then regenerate.
How Do You Operate Services with systemctl?
In systemd, systemctl is the center of service control. Start, stop, status check, and autostart configuration are all done with this command.
What systemd manages is called a "unit", and the extension differs by type.
| Unit type | Extension | Content |
|---|---|---|
| Service | .service |
Daemon / process |
| Target | .target |
A group of units (the old runlevel equivalent) |
| Socket | .socket |
Socket-activation listener |
| Mount | .mount |
A filesystem mount point |
Main systemctl subcommands
systemctl status sshd systemctl start sshd systemctl stop sshd systemctl restart sshd systemctl enable sshd systemctl disable sshd
● sshd.service - OpenSSH server daemon
Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; preset: enabled)
Active: active (running) since Fri 2026-05-30 09:00:00 JST; 2h ago
The Active: line of status is the current running state, and enabled/disabled at the end of the Loaded: line is the autostart setting. start starts immediately, while enable configures autostart from the next boot onward.
start and enable are different. start starts immediately but reverts after reboot, while enable configures autostart but does not start now. To do both at once, use systemctl enable --now sshd.
How Do Boot Targets Map to Runlevels?
A systemd boot target is the concept that replaced SysVinit runlevels (0 to 6). The mapping table appears frequently on the exam.
| SysVinit runlevel | systemd target | State |
|---|---|---|
| 0 | poweroff.target |
Halt (power off) |
| 1 | rescue.target |
Single user (rescue) |
| 2, 3, 4 | multi-user.target |
Multi-user (CLI) |
| 5 | graphical.target |
Multi-user plus GUI |
| 6 | reboot.target |
Reboot |
Note that runlevels 2, 3, and 4 all map to multi-user.target. It is easier to remember that GUI boot is graphical.target (old runlevel 5) and CLI boot is multi-user.target (old runlevel 3).
Check and change the default target
systemctl get-default sudo systemctl set-default multi-user.target
graphical.target Removed "/etc/systemd/system/default.target". Created symlink /etc/systemd/system/default.target → /usr/lib/systemd/system/multi-user.target.
get-default shows the target at the next boot, and set-default changes it. default.target is actually a symbolic link, and what it points to becomes the default target.
Switch the target while running
sudo systemctl isolate multi-user.target runlevel
N 5
isolate switches the current target without rebooting (units not belonging to the specified target are stopped). The SysVinit-compatible runlevel command shows the "previous runlevel" and "current runlevel" (above, no previous N, current 5).
How Do You Halt or Reboot Safely?
Halt and reboot are based on the shutdown command. Time scheduling and warning messages keep the impact on other users low.
Time scheduling with shutdown
sudo shutdown -h now sudo shutdown -r +10 sudo shutdown -h 23:30 sudo shutdown -c
Shutdown scheduled for Fri 2026-05-30 23:30:00 JST, use 'shutdown -c' to cancel.
-h halts (halt/poweroff) and -r reboots. The time is given as now (immediate), +m (m minutes from now), or hh:mm (a clock time). shutdown -c cancels a scheduled halt.
Related commands
| Command | Action |
|---|---|
shutdown -h +m |
Halt in m minutes (recommended; warns all users) |
shutdown -r +m |
Reboot in m minutes |
reboot |
Reboot immediately (equivalent to systemctl reboot) |
poweroff |
Power off immediately (equivalent to systemctl poweroff) |
halt |
Halt the system (may not power off) |
wall |
Send a message to all logged-in users |
echo "Maintenance reboot in 10 minutes" | wall
shutdown automatically sends a wall-style warning when scheduling. To send an arbitrary notice manually, use wall by itself.
Where Do You Look for Boot Trouble?
Isolate boot-related problems from kernel messages and boot logs. dmesg and journalctl are the two pillars.
dmesg | less journalctl -k journalctl -b journalctl -b -1
[ 0.000000] Linux version 6.1.0-18-amd64 ... [ 1.234567] EXT4-fs (sda1): mounted filesystem ...
dmesg shows the kernel ring buffer (hardware detection and driver messages). journalctl -k shows kernel messages only, journalctl -b shows the current boot, and journalctl -b -1 shows the previous boot's logs. Being able to trace the cause of the previous boot's failure with -b -1 is a systemd advantage.
systemd-analyze lets you analyze boot time. systemd-analyze blame lists how long each service took to start in descending order, helping identify slow-starting causes.
Common Mistakes and Fixes
Here are points that trip people up in both practice and the exam.
Mistake 1: Reversing the runlevel-to-target mapping
Runlevel 5 is graphical.target (GUI) and runlevel 3 is multi-user.target (CLI). Remember by direction: "the larger number 5 is GUI". The point that runlevels 2, 3, and 4 all consolidate into multi-user.target is also frequent.
Mistake 2: Editing grub.cfg directly
Direct edits to grub.cfg are lost on regeneration. The correct procedure is to edit /etc/default/grub and then apply with grub-mkconfig (or update-grub).
Mistake 3: Confusing enable and start
enable configures autostart and does not start now, while start starts immediately and reverts after reboot. For both, use enable --now.
Mistake 4: Getting shutdown time scheduling wrong
shutdown -h +10 means "in 10 minutes", not "at 10 o'clock". To specify a clock time, use the shutdown -h 22:00 form. shutdown with no time depends on the environment and may behave like +1 rather than an immediate halt, so add now explicitly for immediate.
Mistake 5: Confusing set-default and isolate
set-default changes the default target for the next boot (persistent). isolate switches now but is not persistent. Distinguish persistent changes from temporary ones.
Troubleshooting
Symptom: enabled but the service is not running after reboot
Cause: Only enable was run and it is not wanted-by a dependent target, or the setting is correct and you simply did not start it
Check:
systemctl is-enabled sshd systemctl status sshd
Fix: If is-enabled shows enabled, the setting is fine. If you also need it to start now, use systemctl enable --now sshd. If disabled, rerun enable.
Symptom: It boots into the GUI (you want CLI)
Cause: The default target is set to graphical.target
Check:
systemctl get-default
Fix: Make CLI the default with sudo systemctl set-default multi-user.target. To switch right now, also use sudo systemctl isolate multi-user.target.
Symptom: Kernel parameter changes are not applied
Cause: You edited /etc/default/grub only and did not regenerate grub.cfg
Check:
cat /proc/cmdline
Fix: Run sudo grub-mkconfig -o /boot/grub/grub.cfg (Debian family: update-grub, RHEL family: grub2-mkconfig) and reboot. You can verify the current boot parameters with /proc/cmdline.
Completion Checklist
- [ ] Can explain the four boot stages in order
- [ ] Regenerated with
grub-mkconfigafter editing/etc/default/grub - [ ] Distinguished autostart and immediate start with
systemctl enable --now - [ ] Can answer the runlevel-to-target mapping table
- [ ] Ran a time-scheduled reboot with
shutdown -r +10 - [ ] Checked boot logs with
journalctl -b
Summary
| Scenario | Command | Purpose |
|---|---|---|
| Service control | systemctl start/enable --now |
Start and autostart |
| Status check | systemctl status / is-enabled |
Check running and autostart |
| Default target | systemctl get-default/set-default |
State at next boot |
| Temporary switch | systemctl isolate <target> |
Switch without rebooting |
| GRUB config | /etc/default/grub then grub-mkconfig |
Change boot options |
| Halt / reboot | shutdown -h/-r |
Safely with a schedule |
| Log investigation | dmesg / journalctl -b |
Isolate boot-time problems |
System boot and systemd are the starting point of all server operations. Combined with log management and process control, they raise your fault-isolation ability another level.
Next Reading
- System Logging - journalctl and rsyslog
- Process Priorities: How nice and renice Work
- Command Line Basics