The system startup process is everything that happens between pressing the power button and reaching a usable login prompt or graphical desktop.
At a high level, startup moves through several layers:
Power on
|
v
Firmware: BIOS or UEFI
|
v
Boot device selection
|
v
Bootloader
|
v
Linux kernel
|
v
initramfs
|
v
real root filesystem
|
v
PID 1: systemd or init
|
v
services, login prompts, network, GUI
A more detailed boot flow looks like this:
[1] Power On
|
v
+----------------------------------+
| [2] BIOS / UEFI |
| - Run POST |
| - Initialize firmware settings |
| - Detect basic hardware |
+----------------------------------+
|
v
+----------------------------------+
| [3] Device Detection |
| - CPU, RAM, disks |
| - Bus controllers |
| - Bootable devices |
+----------------------------------+
|
v
+----------------------------------+
| [4] Boot Device Selection |
| - BIOS reads MBR |
| - UEFI loads EFI executable |
+----------------------------------+
|
v
+----------------------------------+
| [5] Bootloader |
| - GRUB, systemd-boot, rEFInd |
| - Select kernel |
| - Load kernel and initramfs |
| - Pass kernel command line |
+----------------------------------+
|
v
+----------------------------------+
| [6] Linux Kernel + Initramfs |
| - Decompress kernel |
| - Initialize memory and drivers |
| - Mount initramfs |
| - Find real root filesystem |
| - switch_root to real system |
+----------------------------------+
|
v
+----------------------------------+
| [7] PID 1 |
| - systemd or init |
| - Start targets/runlevels |
| - Start services |
+----------------------------------+
|
v
+----------------------------------+
| [8] User Space Ready |
| - login prompt |
| - SSH |
| - graphical login manager |
| - user sessions |
+----------------------------------+
The important idea is:
Startup is a chain.
If one stage fails, the next stage may never begin.
The bootup process is the ordered set of steps a computer follows after power-on until the operating system is running.
The major stages are:
Each stage has a different responsibility.
POST stands for Power-On Self-Test.
It is performed by system firmware, either BIOS or UEFI.
POST checks basic hardware before the operating system starts.
Common checks include:
If POST fails, the operating system usually never starts.
Symptoms of POST failure may include:
Common causes include:
BIOS and UEFI are firmware interfaces.
They both start the boot process, but they work differently.
On BIOS systems, the firmware reads the first sector of the selected disk.
That first sector is the Master Boot Record, or MBR.
BIOS
|
v
Read first 512 bytes of disk
|
v
Execute first-stage boot code
|
v
Load second-stage bootloader
The first-stage code is tiny, so it usually only knows how to find and load a larger bootloader.
On UEFI systems, the firmware reads boot entries from NVRAM.
It then loads an EFI executable from the EFI System Partition, also called ESP.
UEFI firmware
|
v
Read NVRAM boot entry
|
v
Open EFI System Partition
|
v
Load .efi boot program
|
v
Run GRUB, systemd-boot, rEFInd, shim, or another loader
Common EFI boot files include:
\EFI\debian\grubx64.efi\EFI\ubuntu\shimx64.efi\EFI\Microsoft\Boot\bootmgfw.efiWith Secure Boot, the firmware may load a signed shim first. The shim then validates and loads the next bootloader.
MBR stands for Master Boot Record.
It is the first sector of a traditional BIOS disk.
It is usually 512 bytes.
+--------------------------------------+
| Master Boot Record, 512 bytes |
+----------------------+---------------+
| 446 bytes | boot code |
| 64 bytes | partition tbl |
| 2 bytes | 0x55AA sig |
+----------------------+---------------+
The MBR contains:
On GPT disks, a protective MBR may still exist, but the real partition information is stored in GPT structures.
Modern systems usually use GPT with UEFI.
GPT stands for GUID Partition Table.
UEFI systems usually boot from an EFI System Partition.
The ESP is typically:
Check EFI partition:
lsblk -f
Example output:
NAME FSTYPE LABEL UUID MOUNTPOINTS
sda
ββsda1 vfat 1111-2222 /boot/efi
ββsda2 ext4 aaaa-bbbb /boot
ββsda3 ext4 cccc-dddd /
Interpretation:
sda1 is a vfat partition mounted at /boot/efi.
This is likely the EFI System Partition.
Firmware chooses a boot device based on boot order.
Common boot devices include:
To change the boot order, users usually press a firmware key during startup.
Common keys include:
EscF2F10F12DelThe exact key depends on the system vendor.
On UEFI systems, boot entries can often be viewed from Linux using:
sudo efibootmgr
Example output:
BootCurrent: 0002
BootOrder: 0002,0001,0000
Boot0000* Windows Boot Manager
Boot0001* UEFI USB Drive
Boot0002* debian
Interpretation:
The current boot entry is debian.
The firmware tries debian first, then USB, then Windows.
The bootloader loads the Linux kernel and initramfs into memory.
Common bootloaders include:
rEFIndLILOThe most common Linux bootloader is GRUB 2.
The bootloader usually provides:
GRUB 2 can read filesystems, display menus, load kernels, load initramfs images, and pass kernel parameters.
Important files include:
/boot/grub/grub.cfg/etc/default/grub/etc/grub.d/On some Red Hat-based systems:
/boot/grub2/grub.cfg
Important note:
Do not usually edit grub.cfg directly.
Edit /etc/default/grub or files under /etc/grub.d, then regenerate the configuration.
Common regeneration commands:
Debian/Ubuntu:
sudo update-grub
Generic GRUB command:
sudo grub-mkconfig -o /boot/grub/grub.cfg
Red Hat-style systems may use:
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
The bootloader normally loads two important files:
vmlinuz-* β compressed Linux kernel imageinitramfs-* β early userspace imageExample:
ls -lh /boot
Example output:
-rw-r--r-- 1 root root 12M vmlinuz-6.8.0
-rw-r--r-- 1 root root 45M initramfs-6.8.0.img
-rw-r--r-- 1 root root 200K config-6.8.0
Interpretation:
The kernel image is vmlinuz-6.8.0.
The initramfs image contains early boot tools and drivers.
The bootloader passes parameters to the kernel.
View the current kernel command line:
cat /proc/cmdline
Example output:
BOOT_IMAGE=/vmlinuz-6.8.0 root=UUID=abcd-1234 ro quiet splash
Important parameters:
root=UUID=... β real root filesystemro β initially mount root read-onlyquiet β reduce boot messagessystemd.unit=rescue.target β boot into rescue moderd.break β break into initramfs emergency shellsingle β single-user style bootAfter the bootloader transfers control, the kernel begins initialization.
The kernel:
A simplified flow:
Kernel image starts
|
v
Initialize CPU and memory
|
v
Initialize drivers
|
v
Mount initramfs
|
v
Find real root filesystem
|
v
switch_root or pivot_root
|
v
Start /sbin/init or systemd
Initramfs stands for initial RAM filesystem.
It is a temporary filesystem loaded into memory during early boot.
It contains tools and drivers needed before the real root filesystem is available.
Initramfs may contain:
Initramfs is especially important when the root filesystem is on:
LVMIf initramfs cannot find or mount the real root filesystem, boot may fail.
After initramfs finds and mounts the real root filesystem, the system must move from the temporary root to the real root.
This is commonly done with:
switch_root
or historically:
pivot_root
Conceptual flow:
Temporary initramfs root
|
v
Mount real root filesystem
|
v
Switch to real root
|
v
Run real /sbin/init or systemd
PID 1 is the first user-space process.
On most modern Linux systems, PID 1 is systemd.
Check PID 1:
ps -p 1 -o pid,comm,args
Example output:
PID COMMAND ARGS
1 systemd /usr/lib/systemd/systemd
Interpretation:
systemd is PID 1.
It is responsible for starting and supervising user-space services.
On older systems, PID 1 may be:
init
or alternatives such as:
OpenRCSysV init is an older initialization system.
It uses:
/etc/inittab/etc/init.d//etc/rc.d/SysV init organizes system states using runlevels.
Commands include:
runlevel
sudo telinit 3
SysV init is less common on modern mainstream distributions but still appears in older systems and compatibility layers.
systemd is the dominant init system on many modern Linux distributions.
It manages:
systemd uses unit files.
Common unit types include:
.service.target.mount.socket.timer.devicesystemd starts units according to dependencies.
A simplified target flow:
default.target
|
v
multi-user.target or graphical.target
|
+--> sysinit.target
| fsck, sysctl, modules, udev
|
+--> basic.target
| journald, sockets, basic services
|
+--> multi-user services
sshd, cron, networking, getty
If the system boots to a GUI, graphical.target includes display-manager services.
graphical.target
|
v
multi-user.target
|
v
display-manager.service
|
v
graphical login screen
Runlevels are the traditional SysV way to represent system state.
Runlevel meaning can vary between distributions.
Check runlevel:
runlevel
Example output:
N 5
Interpretation:
There was no previous runlevel.
The current runlevel is 5.
systemd replaces runlevels with targets.
Common targets:
poweroff.target β power offrescue.target β basic rescue modeemergency.target β very minimal emergency shellmulti-user.target β text-mode multi-user systemgraphical.target β graphical login and multi-user servicesreboot.target β rebootApproximate mapping:
runlevel 0 β poweroff.targetrunlevel 1 β rescue.targetrunlevel 3 β multi-user.targetrunlevel 5 β graphical.targetrunlevel 6 β reboot.targetCheck default target:
systemctl get-default
Example:
graphical.target
Set default target:
sudo systemctl set-default multi-user.target
Switch target immediately:
sudo systemctl isolate multi-user.target
Important:
set-default changes future boots.
isolate changes the current running state.
After startup reaches the appropriate target, login services become available.
Text login prompts are usually provided by:
getty@.service
Example:
systemctl status getty@tty1.service
SSH login is usually provided by:
sshd.service
Graphical login is provided by a display manager, such as:
User sessions may load shell startup files such as:
/etc/profile~/.bash_profile~/.bashrcBoot logs are essential for diagnosing startup problems.
View logs from the current boot:
journalctl -b
Show only errors from current boot:
journalctl -b -p err
Show previous boot:
journalctl -b -1
Show kernel messages:
journalctl -k -b
Example:
Jun 01 10:00:05 host systemd[1]: Started OpenSSH server daemon.
Jun 01 10:00:08 host kernel: EXT4-fs (sda3): mounted filesystem with ordered data mode.
Interpretation:
systemd started sshd.
The kernel mounted the root filesystem successfully.
systemd includes tools for measuring boot performance.
Show total boot time:
systemd-analyze
Example output:
Startup finished in 4.123s (kernel) + 12.456s (userspace) = 16.579s
graphical.target reached after 12.200s in userspace.
Interpretation:
The kernel stage took about 4.1 seconds.
User-space services took about 12.5 seconds.
The graphical target was reached after about 12.2 seconds.
Show slow services:
systemd-analyze blame
Example output:
12.000s slow-demo.service
3.500s NetworkManager-wait-online.service
1.200s sshd.service
Interpretation:
slow-demo.service took the most time.
NetworkManager wait-online also contributed to boot delay.
Show dependency chain:
systemd-analyze critical-chain
This helps identify services that delay the boot path.
A kernel panic is an unrecoverable kernel error.
When it happens, the kernel cannot safely continue.
Symptoms may include:
Common causes:
Example panic message:
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
Interpretation:
The kernel could not mount the root filesystem.
Possible causes include wrong root= parameter, missing initramfs driver, bad disk, or filesystem problem.
When diagnosing a panic:
Useful commands after booting rescue or a working kernel:
journalctl -b -1 -p err
journalctl -k -b -1
dmesg -T
lsblk -f
blkid
fsck
View hostname:
hostname
Set hostname on systemd systems:
sudo hostnamectl set-hostname server01
Verify:
hostnamectl
Example output:
Static hostname: server01
Operating System: Ubuntu
Kernel: Linux 6.8.0
Architecture: x86-64
Interpretation:
The system hostname is server01.
This name identifies the machine on the network and in logs.
Check uptime:
uptime
Example output:
15:20:10 up 3 days, 4:12, 2 users, load average: 0.10, 0.20, 0.18
Interpretation:
The system has been running for 3 days and 4 hours.
Two users are logged in.
Load average is low.
Uptime helps confirm whether a reboot happened recently.
Reboot immediately:
sudo reboot
or:
sudo systemctl reboot
Schedule reboot in 5 minutes:
sudo shutdown -r +5
Cancel scheduled shutdown or reboot:
sudo shutdown -c
Shutdown immediately:
sudo shutdown now
or:
sudo systemctl poweroff
Schedule shutdown in 30 minutes:
sudo shutdown -h +30
Broadcast message example:
sudo shutdown -h +30 "System maintenance in 30 minutes"
Show time settings:
timedatectl
List timezones:
timedatectl list-timezones
Set timezone:
sudo timedatectl set-timezone Europe/Berlin
Verify:
timedatectl
Correct timezone matters for:
Root password recovery is a sensitive administrative procedure.
Only perform it on systems you own or are authorized to administer.
A common Red Hat-style recovery method uses:
rd.break
This breaks into initramfs before the real root filesystem is fully started.
General flow:
Commands after reaching the emergency shell:
mount -o remount,rw /sysroot
chroot /sysroot
passwd root
touch /.autorelabel
exit
exit
Interpretation:
The root filesystem is remounted writable.
chroot makes /sysroot behave like /.
passwd changes the root password.
.autorelabel tells SELinux to relabel files on next boot.
On Debian/Ubuntu systems, recovery may use GRUB recovery mode or init=/bin/bash depending on setup.
Identify what slowed down the boot process.
Create a test service that sleeps during boot:
sudo tee /etc/systemd/system/slow-demo.service > /dev/null <<'EOF'
[Unit]
Description=Slow Boot Demo Service
[Service]
Type=oneshot
ExecStart=/bin/sleep 20
[Install]
WantedBy=multi-user.target
EOF
Enable it:
sudo systemctl daemon-reload
sudo systemctl enable slow-demo.service
Reboot:
sudo systemctl reboot
systemd-analyzeAfter reboot:
systemd-analyze
Example output:
Startup finished in 3.800s (kernel) + 25.400s (userspace) = 29.200s
multi-user.target reached after 25.100s in userspace.
systemd-analyze blame | head
Example output:
20.010s slow-demo.service
3.400s NetworkManager-wait-online.service
1.100s sshd.service
Interpretation:
The boot delay is mostly caused by slow-demo.service.
The kernel was not the main bottleneck.
The userspace service startup path was delayed.
sudo systemctl disable --now slow-demo.service
sudo rm -f /etc/systemd/system/slow-demo.service
sudo systemctl daemon-reload
Simulate a service that fails during boot and diagnose it.
sudo tee /etc/systemd/system/broken-boot.service > /dev/null <<'EOF'
[Unit]
Description=Broken Boot Demo Service
[Service]
Type=oneshot
ExecStart=/not/a/real/command
[Install]
WantedBy=multi-user.target
EOF
Enable and start:
sudo systemctl daemon-reload
sudo systemctl enable broken-boot.service
sudo systemctl start broken-boot.service
systemctl --failed
Example output:
UNIT LOAD ACTIVE SUB DESCRIPTION
broken-boot.service loaded failed failed Broken Boot Demo Service
systemctl status broken-boot.service
Example output:
Active: failed (Result: exit-code)
Process: 1300 ExecStart=/not/a/real/command (code=exited, status=203/EXEC)
journalctl -u broken-boot.service -b
Example output:
Failed to locate executable /not/a/real/command
Failed at step EXEC spawning /not/a/real/command: No such file or directory
Interpretation:
The service failed because ExecStart points to a missing executable.
This is not a kernel or bootloader problem.
It is a systemd unit configuration problem.
sudo systemctl disable broken-boot.service
sudo rm -f /etc/systemd/system/broken-boot.service
sudo systemctl daemon-reload
sudo systemctl reset-failed
Understand the difference between text-mode and graphical boot.
systemctl get-default
Example:
graphical.target
sudo systemctl set-default multi-user.target
Reboot:
sudo reboot
systemctl get-default
systemctl list-units --type=target --state=active
Example output:
multi-user.target
Interpretation:
The system is configured to boot into text-mode multi-user state.
A graphical login manager may not start automatically.
sudo systemctl set-default graphical.target
sudo systemctl isolate graphical.target
Practice entering a limited maintenance environment.
At GRUB, edit the kernel command line and add:
systemd.unit=rescue.target
Boot with the edited entry.
From a running system:
sudo systemctl isolate rescue.target
systemctl list-units --type=target --state=active
Example output:
rescue.target loaded active active Rescue Mode
Interpretation:
The system is in rescue mode.
Only essential services are running.
This mode is useful for maintenance and repair.
sudo systemctl isolate multi-user.target
or for GUI:
sudo systemctl isolate graphical.target
Use journal logs to find errors from the current or previous boot.
journalctl -b -p err
Example output:
Jun 01 10:05:01 host systemd[1]: failed-demo.service: Failed with result 'exit-code'.
Jun 01 10:05:01 host kernel: ata1.00: failed command: READ FPDMA QUEUED
Interpretation:
One service failed.
The kernel also reported a disk-related error.
The service failure and disk error should be investigated separately.
journalctl -b -1 -p err
Interpretation:
Previous boot logs help diagnose failures that happened before the last reboot.
Practice scheduling and canceling shutdowns safely.
sudo shutdown -h +10 "Test shutdown in 10 minutes"
Example broadcast:
Broadcast message from root:
The system is going down for poweroff in 10 minutes!
sudo shutdown -c
Interpretation:
The shutdown was scheduled.
shutdown -c canceled it before it happened.
This is useful during maintenance planning.
sudo shutdown -r +5 "Test reboot in 5 minutes"
Cancel:
sudo shutdown -c
Confirm that a system actually restarted.
uptime
Example:
up 14 days, 3:21
Reboot:
sudo systemctl reboot
After reboot:
uptime
Example:
up 2 min
Interpretation:
The uptime reset from 14 days to 2 minutes.
This confirms the system rebooted.
Understand a common boot panic pattern.
Console shows:
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
Boot from an older kernel, rescue mode, or live USB.
Check disks:
lsblk -f
blkid
Example:
NAME FSTYPE UUID MOUNTPOINTS
sda1 vfat 1111-2222 /boot/efi
sda2 ext4 aaaa-bbbb /boot
sda3 ext4 cccc-dddd /
Check kernel command line from bootloader configuration:
grep -R "root=" /boot/grub* /boot/loader 2>/dev/null
Example problem:
root=UUID=wrong-uuid
Interpretation:
The kernel was told to mount a root filesystem UUID that does not exist.
Fix GRUB configuration or filesystem UUID references.
Practice emergency administrative recovery.
At GRUB, edit the kernel entry and add:
rd.break
Boot with Ctrl-X or F10.
mount -o remount,rw /sysroot
chroot /sysroot
passwd root
touch /.autorelabel
exit
exit
Changing password for user root.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.
Interpretation:
The root password was changed.
SELinux relabeling was requested for the next boot.
The system should reboot and allow login with the new password.
This is for authorized recovery only.
Physical or console access to a machine often means administrative control is possible.
Protect servers with disk encryption, firmware passwords, and cloud access controls where appropriate.
Understand scheduled system maintenance managed by systemd.
systemctl list-timers --all
Example output:
NEXT LEFT LAST PASSED UNIT ACTIVATES
Mon 2026-06-15 00:00:00 8h Sun 2026-06-14 00:00:00 16h logrotate.timer logrotate.service
Mon 2026-06-15 06:00:00 14h Sun 2026-06-14 06:00:00 10h apt-daily.timer apt-daily.service
Interpretation:
logrotate.timer activates logrotate.service.
apt-daily.timer activates apt-daily.service.
Timers are systemd's scheduled task mechanism, similar in purpose to cron.
Ensure logs and schedules use the correct local time.
timedatectl
Example output:
Time zone: UTC (UTC, +0000)
System clock synchronized: yes
sudo timedatectl set-timezone Europe/Berlin
timedatectl
Example output:
Time zone: Europe/Berlin (CEST, +0200)
System clock synchronized: yes
Interpretation:
The system timezone is now Europe/Berlin.
Logs, cron jobs, and timers will use this timezone unless configured otherwise.
Use cron for scheduled maintenance.
mkdir -p ~/maintenance-demo
cat > ~/maintenance-demo/backup-demo.sh <<'EOF'
#!/bin/bash
mkdir -p "$HOME/maintenance-demo/backups"
tar -czf "$HOME/maintenance-demo/backups/home-backup-$(date +%F).tar.gz" "$HOME/maintenance-demo" 2>/dev/null
EOF
chmod +x ~/maintenance-demo/backup-demo.sh
Edit crontab:
crontab -e
Add:
0 0 * * * /home/user/maintenance-demo/backup-demo.sh
Interpretation:
The script runs every day at midnight.
Cron is useful for recurring maintenance tasks.
systemctl status cron
or on some systems:
systemctl status crond
Check:
systemd-analyze
systemd-analyze blame
systemd-analyze critical-chain
journalctl -b -p warning
Common causes:
Check:
systemctl --failed
systemctl status service-name
journalctl -u service-name -b
Common causes:
Check:
journalctl -xb
systemctl --failed
mount -a
cat /etc/fstab
lsblk -f
Common causes:
A common fix for optional disks is adding:
nofail
to the /etc/fstab options, if appropriate.
Try during boot:
Also check GRUB configuration:
grep GRUB_TIMEOUT /etc/default/grub
Try:
Commands:
journalctl -b -1 -p err
ls /boot
uname -r
Boot and firmware:
sudo efibootmgr
lsblk -f
cat /proc/cmdline
ls -lh /boot
systemd boot state:
ps -p 1 -o pid,comm,args
systemctl get-default
systemctl list-units --type=target --state=active
systemctl --failed
Boot performance:
systemd-analyze
systemd-analyze blame
systemd-analyze critical-chain
Logs:
journalctl -b
journalctl -b -p err
journalctl -k -b
journalctl -b -1
Targets:
sudo systemctl isolate multi-user.target
sudo systemctl isolate graphical.target
sudo systemctl set-default multi-user.target
sudo systemctl set-default graphical.target
System management:
hostname
hostnamectl
uptime
sudo reboot
sudo systemctl reboot
sudo shutdown -r +5
sudo shutdown -h +30
sudo shutdown -c
timedatectl
Timers and cron:
systemctl list-timers --all
crontab -e
crontab -l
Remove slow demo service:
sudo systemctl disable --now slow-demo.service 2>/dev/null
sudo rm -f /etc/systemd/system/slow-demo.service
Remove broken boot service:
sudo systemctl disable --now broken-boot.service 2>/dev/null
sudo rm -f /etc/systemd/system/broken-boot.service
Reload systemd:
sudo systemctl daemon-reload
sudo systemctl reset-failed
Return to graphical target if needed:
sudo systemctl set-default graphical.target
sudo systemctl isolate graphical.target
Cancel scheduled shutdown if one exists:
sudo shutdown -c
uptime to confirm that the reboot happened.hostname, change it with hostnamectl, and verify the result.systemd-analyze, systemd-analyze blame, and systemd-analyze critical-chain to identify slow boot components.systemctl --failed, read its logs, and fix or remove it.multi-user.target and graphical.target on a lab machine.shutdown -c.journalctl -b -p err to review errors from the current boot.systemctl list-timers --all to identify scheduled maintenance tasks and the services they activate.timedatectl, verify it, and explain why timezone correctness matters for logs and scheduled tasks.