Understand the Linux boot process, systemd, sysvinit and the runlevel modes.
UNDERSTANDING THE SUBJECT MATTER
Every Operating systems have a process of booting, but before I talk about the boot process of the Linux Operating System, I will first talk on the basic boot process of the most operating systems we have.
Generally, most operating systems follow the boot steps below.
1. The system is powered on
2. CPU starts (and passes the next process to BIOS)
3. BIOS is loaded (inclusive of UEFI for a modern system, i.e, the newest version of BIOS if there is any)
4. BIOS starts the POST. (POST scans), If the test is passed, the next process is passed to the boot sector.
5. Boot sector launches the boot loader
6. The boot loader is executed. (depending on the operating system’s boot loader)
7. The boot loader loads the Operating System.
For further understanding, let’s talk about some of these terms.
BIOS stands for Basic Input/Output Process. BIOS is a firmware (software on a chip). The first software that runs when the system is powered on.
The BIOS initializes POST (Power On Self Test). POST will scan or rather initializes and run a test on the basic components that makes the system start up, like the processor, RAM, drives, adapters, Video cards and other important components that are needed only to start the system.
If the test fails, the system refuses to boot, but if the test is passed, POST launches the boot loader. How? Also part of the test is to scan the hard drive for a boot sector (which mostly contains MBR), i.e, the dedicated part of the hard disk that contains data to boot the computer. usually the first 512 bytes of the drive.
If MBR is found, POST launches the boot loader.
BIOS is used for boot order settings, storage device settings, virtualization settings (i.e if you want your system to be virtualized or not), CPU speed settings, system security settings, etc.
BIOS memory is stored in the CMOS, which makes BIOS and CMOS communicate with each other to make sure every component is actually in the right place.
Having understood the basic boot process of most operating systems, let’s look at how a Linux Operating system boots.
The Linux Operating System follows the boot process below.
1. The system is powered on
2. CPU starts (and passes the next process to BIOS)
3. BIOS is loaded (inclusive of UEFI for a modern system, i.e, newest version of BIOS if there is any)
4. BIOS starts the POST. (POST scans), If the test is passed, the next process is passed to the Boot sector.
5. The boot sector launches the Boot loader.
6. The boot loader is executed. [could be LILO, GRUB or GRUB2]
part of the boot loader process may include USER INPUT
USER Input : (Depending on the configuration, you can choose what OS or kernel version to boot from the boot menu. Note, this menu can also be turned off and if it is, the set default kernel will be executed.)
7. Linux Kernel is executed
8. Devices initialize (modules and initial RAM disk are loaded)
9. The boot loader loads the Operating System.
10. Root filesystem mounts
FOR A MODERN LINUX SYSTEM RUNNING “SYSTEMD”
11. Systemd runs along with its dependencies. (becomes the first PID)
12. Default Runtargets/runlevels starts (along with its dependencies)
13. The root filesystem is checked
14. Remaining local filesystems are mounted
15. Network devices start
16. Remote filesystem starts if it is configured.
17. Login prompt displays
FOR THE OLD LINUX SYSTEMS RUNNING “SYSVINIT”, AFTER THE 10th STEP,
11. The init program loads (becomes the first PID), /sbin/init.
11 b. The /etc/inittab is read and runlevel scripts run
12. Default runlevel starts
13. The root filesystem is checked
Process 14, 15, 16 and 17 are the same as the Linux system running with systemd
In the steps above, you will notice that, from the 10th step, systemd and sysvinit was mentioned.
In the old Linux system, sysvinit was part of the Linux system but in the modern Linux system, sysvinit has been replaced with systemd.
What are these sysvinit and systemd?
init commonly known as “system V init” or “sysvinit” is a daemon process, a system management daemon, a process manager that starts as soon as the system is powered on.
It is the very first process that is started by the kernel, as such, the parent process of other running processes on the system and it has a PID of 1.
If the init daemon has issues starting, no other processes will be started, as I said, it is the parent process for other processes, so other processes depend on it. If by anyway, the sysvinit process doesn’t start, “kernel panic” will be initialized
As tech evolves, sysvinit shortcomings became obvious, and as such was replaced with other system management daemon such as Upstart, Epoch, Mudar and Systemd,
systemd which is our focus in this subject matter because systemd is currently the default initialization and service management process of almost all modern Linux systems.
However, some developers don’t see the need to replace sysvinit, hence why it has become a controversial discussion which I won’t discuss in this article so as not to go out of the scope.
systemd, like sysvinit is a system management daemon, the first process when the system is booted that handles how other processes run
An advantage of the systemd over the sysvinit system is that it prioritizes services and reduces startup time compared to sysvinit
As I mentioned in the boot process, step 12, that a default run level will start after systemd or sysvinit has been initiated. So what is this run level?
runlevel is the system mode that controls the operations of the system in accordance with the services that are available by the mode.
Hey, don’t stress your head, you will understand better as we go on.
The system can run in different modes(runlevels) depending on the preset mode. The mode that is set as default is what the system will boot with and becomes the system’s state.
So, it is safe to simply say that runlevels are the modes the system runs in.
I think the next question would be,” what are these system modes (runlevels)? but before then, let’s talk about runtarget.
runtarget is also runlevel. lol. Don’t get it twisted. I mean that sysvinit systems uses runlevel while systemd systems uses runtargets. so you see that runlevel is also runtarget.
Hence, take the runlevel defination or meaning as the same as runtarget. The only difference here is that sysvinit system has different runlevels from the systemd system. Let’s look at their different runlevels.
The sysvinit runlevels are
0 – halt (shutdown)
1 – single user mode (rescue)
2 – Multiuser (without NFS/remote filesystems or Network)
3 – Full multisuer mode (including remote filesystems and network)
4 – unused
5 – X11 (Full multi-user with GUI)
6 – reboot
If the system’s default runlevel is set to 0, it means that as soon as the boot process gets to the systemd or sysvinit stage, the system halts(shuts down). Hence, you wouldn’t want to set the default runlevel to be 0.
If the default runlevel is set to 1, it means that the system will go into the single-user mode when the system is booted.
If the default runlevel is set to 2, it means that the system will boot into multi-user mode but with no access to the network, remote filesystems, and GUI.
If the default runlevel is set to 3, it means that the system will boot into full multi-user mode with access to network and remote file system but no GUI
If the default runlevel is set to 4, it is unused. This runlevel is unused.
If the default runlevel is set to 5, it means that the system will boot into full multi-user mode with GUI if it is installed.
If the default runlevel is set to 6, it means that the system will be in a restart loop, the system will keep rebooting when it gets to the sysvinit/systemd boot process stage. Hence, you wouldn’t also want to set the default runlevel to 6.
To verify this, in a sysvinit system, run the command below,
# cat /etc/inittab
you will see the different runlevels that are available.
The systemd runtargets are
0 – poweroff.target (shutdown)
1 – rescue.target (rescue shell/single user)
2 – multi-user.target (non-graphical, full network, multi-user)
3 – multi-user.target (non-graphical, full network, multi-user)
4 – multi-user.target (non-graphical, full network, multi-user)
5 – graphical.target (graphical desktop, multi-user)
6 – reboot.target (reboot)
For systemd, you can see that runtarget 2, 3 and 4 have the same function, unlike sysvinit system that is different.
Going forward, the file, etc/inittab, though still exists on a systemd system, but not in use anymore. Let’s take a look
[root@HQEBPRD ~]# cat /etc/inittab
# inittab is no longer used.
#
# ADDING CONFIGURATION HERE WILL HAVE NO EFFECT ON YO UR SYSTEM.
#
# Ctrl-Alt-Delete is handled by /usr/lib/systemd/syst em/ctrl-alt-del.target
#
# systemd uses 'targets' instead of runlevels. By def ault, there are two main targets:
#
# multi-user.target: analogous to runlevel 3
# graphical.target: analogous to runlevel 5
#
# To view current default target, run:
# systemctl get-default
#
# To set a default target, run:
# systemctl set-default TARGET.target
[root@HQEBPRD ~]#
As you can see, this path has been deprecated.
Systemd uses what is called unit files for its management and these unit files can be found in two directories. One which is “/usr/lib/systemd/system”.
This directory contains the systemd’s default unit files and the second which is “/etc/systemd/system”. This directory is the directory administrators can define their unit files.
You can click on this link to learn more on how systemd manages services with unit file and how systemd manages mount and automount with unit files.
To verify the runlevels for systemd system, use the command,
[root@HQEBPRD ~]# ls -al /usr/lib/systemd/system/*.target
-rw-r--r--. 1 root root 415 Nov 8 2018 /usr/lib/systemd/system/anaconda.target
-rw-r--r--. 1 root root 956 Aug 30 2019 /usr/lib/systemd/system/basic.target
-rw-r--r--. 1 root root 419 Jun 22 2018 /usr/lib/systemd/system/bluetooth.target
lrwxrwxrwx. 1 root root 15 Aug 30 2019 /usr/lib/systemd/system/runlevel0.target -> poweroff.target
lrwxrwxrwx. 1 root root 13 Aug 30 2019 /usr/lib/systemd/system/runlevel1.target -> rescue.target
lrwxrwxrwx. 1 root root 17 Aug 30 2019 /usr/lib/systemd/system/runlevel2.target -> multi-user.target
lrwxrwxrwx. 1 root root 17 Aug 30 2019 /usr/lib/systemd/system/runlevel3.target -> multi-user.target
lrwxrwxrwx. 1 root root 17 Aug 30 2019 /usr/lib/systemd/system/runlevel4.target -> multi-user.target
lrwxrwxrwx. 1 root root 16 Aug 30 2019 /usr/lib/systemd/system/runlevel5.target -> graphical.target
lrwxrwxrwx. 1 root root 13 Aug 30 2019 /usr/lib/systemd/system/runlevel6.target -> reboot.target
From the screenshot above, you can see the main 6 runtargets (runlevels.target). You can also see other runtargets like sound.target, sleep.target, e.t.c.
So does this mean that a systemd system can be running on more than one target? The answer is a big YES BUT other targets are dependencies of the main target.
In the Linux boot process, step 12, the default runtarget starts along with its dependencies which of course may include other targets as its dependencies. Let’s look at the default target my system is running on and its dependencies.
To get the default target, use the command,
[root@HQEBPRD ~]# systemctl get-default
graphical.target
Now let’s look at other dependencies (targets) that is associated with this target.
[root@HQEBPRD ~]# cat /usr/lib/systemd/system/graphical.target
# SPDX-License-Identifier: LGPL-2.1+
#
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=Graphical Interface
Documentation=man:systemd.special(7)
Requires=multi-user.target
Wants=display-manager.service
Conflicts=rescue.service rescue.target
After=multi-user.target rescue.service rescue.target display-manager.service
AllowIsolate=yes
you can see that the graphical.target requires multi-user.target as well and it conflicts with rescue.target.
Let’s also see the dependencies of multi-user.target,
[root@HQEBPRD ~]# cat /usr/lib/systemd/system/multi-user.target
# SPDX-License-Identifier: LGPL-2.1+
#
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=Multi-User System
Documentation=man:systemd.special(7)
Requires=basic.target
Conflicts=rescue.service rescue.target
After=basic.target rescue.service rescue.target
AllowIsolate=yes
[root@HQEBPRD ~]#
You can see also that basic.target is required for multi-user.target to function which means that graphical.target will run along with multi-user.target, basic.target, and other targets as its target dependencies.
Don’t forget that basic.target still has its requirements and dependencies as well.
Having understood the Linux boot process and systemd, Let’s roll down to some of the tasks that required from an administrator. You can also click on the Link below to understand how systemd manages it’s services.
ACTION TIME
How To View The Current Runlevel Of A Linux System
To know the current runlevel of your system, be it sysvinit or systemd, use the command,
[root@HQEBPRD ~]# runlevel
N 5
[root@HQEBPRD ~]#
you can see that the system is running on runlevel 5. Please note that the N value is the previous runlevel of the system before it was changed. In my case, it was never in a previous runlevel, hence the value N (Not available)
How To Change The Runlevel Of A Linux System
To change the runlevel of a Linux system in an operational mode, be it sysvinit or systemd, use the command,
init <runlevel-No>
OR
systemctl isolate <runlevel-name>
For example, to change the system to runlevel 3, use the command,
[root@HQEBPRD ~]# init 3
OR
[root@HQEBPRD ~]# systemctl isolate multi-user.target
NOTE: This settings is not persistent, to make it persistent, you will have to set the default runlevel as it is done below.
How To Get The Default Runlevel Of A Linux System
To verify the default runlevel of a Linux system, use the command,
[root@HQEBPRD ~]# systemctl get-default
graphical.target
How To Set The Default Runlevel of A Linux System
To set the default runlevl of a Linux system, use the command,
systemctl set-default <runlevel>
For example, to set the default runlevel of the system to 5, i.e (graphical.target), use the command,
[root@HQEBPRD ~]# systemctl set-default graphical.target
Removed /etc/systemd/system/default.target.
Created symlink /etc/systemd/system/default.target → /usr/lib/systemd/system/graphical.target.
[root@HQEBPRD ~]#
Your feedback is welcomed. If you love others, you will share with others.
Leave a Reply