Boot Process, System Calls & Init Implementations in Linux For Beginners

Boot Process, System Calls & Init Implementations in Linux For Beginners

This is the fifth blog in the Linux Masterclass Series

Boot Process

When you start your computer, the booting of a Linux System goes through multiple stages.

BIOS (Basic Input/Output System)

BIOS initializes the hardware and ensures it is ready by running some self-tests. It checks if the memory, hard disk, and all the connected devices are good, whether the keyboard is connected, and many other similar checks. After this, BIOS does its main job of running the bootloader.

Bootloader

The Bootloader loads the Kernel into the memory based on the Kernel parameters. In the previous blogs, we understood that different config files help configure applications and processes existing in our system. Similarly, the Kernel has some parameters based on which the bootloader would initialize its code in the memory.
The Grub Bootloader is the universal Linux standard and is also very efficient if you want to dual boot your system with some other OS like Windows.

Kernel

Once the bootloader loads the Kernel into the memory, the third stage is the Kernel itself. The Kernel immediately initializes the memory and the devices present in the system. Then comes the main job of the Kernel, loading the ‘init’ or Mother Process.

init (Mother Process)

The mother process ‘init’ starts and stops all the essential processes that run our system.

Three Levels of Abstraction in Linux OS

A Linux Operating System can be classified into three levels of abstraction.

Hardware

It includes CPU, memory, ports, HDD/SSD, etc. Hardware is the physical layer that computes what we do on our system.

Kernel

In the previous Linux Masterclass Series blogs, we understood that the Kernel is responsible for handling the processes, the memory management between the processes, device communication, setting up the filesystem and system calls, etc.

User Space

All screen-related things we run, like the shell, the graphics we see, the chrome browser, etc., come under the User Space level of the Operating System.

Privilege Levels

The three abstraction levels we understood above also have three different privilege levels. A Kernel operates in a Kernel mode, and the User operates in User mode.

In the Kernel mode, the Kernel has complete access to the hardware and controls everything in the system. On the other hand, a user mode allows access to only a small amount of safe memory and the CPU.

Whenever we do anything related to the hardware, like reading/writing data and controlling network ports, we do it in the Kernel mode. And the reason behind that is simple. Imagine a scenario where spyware has infected your system. In such a situation, you wouldn’t want to access your hardware directly as the spyware can access your data, webcam and many other sensitive things. The two modes we talked about are also called Protection rings. Let us understand this in greater detail.

Understanding how Privilege levels work

Imagine there is a celebrity who is partying in a club surrounded by multiple layers of the crowd. The first layer is of the friends & family that he trusts the most. The second is of their bodyguards, the third is of the club bouncers, and the last fifth layer is of the general club crowd.

You exist in this fifth layer, and you want to get an autograph of the celebrity or a selfie with him. To achieve this, you might need a VVIP pass, Special Permission or something like that.

This is precisely how the protection rings/layers around the hardware work. The hardware is the celebrity. The layer/ring it trusts the most is the Kernel (friends & family). It is the ring ‘0’. And the last layer is ring 3 of the ‘user’. If the user wants to access the hardware and its resources, the VVIP pass here is a ‘System Call’.

ls -la etc  less (6) (1).png

System Call

System Call allows us to perform privileged instructions in the ‘Kernel mode’. The VVIP pass helps us get a similar treatment as a friend as we can talk to the celebrity, get a photo clicked etc. In the same way, a system call helps us perform some privileged instructions in the Kernel mode and then you can switch back to the User mode.

System calls are also known as Syscalls. The Syscalls provide the user-space applications/processes with a way for Kernel to do something for us. They make certain services available to users through System Call API.

All the System calls, like the weight system call where the Parent process wants an update on the child process termination status (Read more about it here) are just APIs that allow us to request Kernel to do something on behalf of us.

The Kernel offers us a fixed number of services through these APIs, and we cannot add more. Our System has a table of system calls where each has a unique ID.

Three Implementations of init, the mother process

System V

System V is the traditional implementation of the init process. It starts and stops processes sequentially. One of the advantages of using this implementation is that it is easier to resolve dependency issues.

Let us assume we have two processes: Process A and B, where B needs A to run itself. If Process A is not running, B cannot run. In such scenarios System V comes in handy as it ensures that the processes run sequentially. It will start Process A, and only then will start Process B.

But there is a disadvantage of System V implementation as well. Its performance is not good. The reason is that the processes start and stop one at a time instead of parallelly/simultaneously. That hinders the performance.

Runlevels

The status of System V is defined by ‘Runlevels’ that vary between 0 to 6.

  • 0 -> Shutdown. If the system is shutting down, the runlevel will be 0.
  • 1 -> Single User. If only a single user uses the machine, the runlevel will be 1.
  • 2 -> Multiple users without networking. Multiple users are not connected through the network but locally.
  • 3 -> Multiple users with networking.
  • 4 -> Unused. When no one is using the system, and it is idle, the runlevel will be 4.
  • 5 -> Multiple users with networking and GUI (Graphical User Interface). This is the state we are familiar with since we use GUI.
  • 6 -> System is rebooting.

When the system starts up, it checks what runlevel you are currently in and executes all the scripts inside that particular runlevel config.

The runlevel config exists in the /etc directory. You can access it by running the command ls /etc/rc or if it says no such file or directory exists. Run ls /etc | grep rc. Here you are feeding the output of ls to the grep command and searching files starting with rc.

Screenshot from 2022-11-14 16-24-05.png

Now let us search the first one, rc0.d (runlevel 0 config) by running the command ls /etc/rc0.d

Screenshot from 2022-11-15 16-44-48.png

This is the list of all the scripts that will run at runlevel 0 or at the time of shutdown.

Screenshot from 2022-11-14 16-30-31.png

This is the list of all the config scripts that will run at runlevel 5, which we are familiar with. Today, the System V implementation is somewhat getting replaced. But these runlevels will still be there in other implementations, as they are fundamental to how the init works and not easily replaceable. The config files we saw above are only to support those services that start and stop through the System V scripts. System V has a lot of services, and there are many commands that you can use to manage them.

You can run the command service –status-all to check the status of all the services running through the System V init scripts.

Screenshot from 2022-11-14 16-48-02.png

To change their status, you can run the command sudo service [service name] [start/stop/restart]. The service name can be any from the list shown above. Write start to start the service, stop to stop it, and restart to restart it. This command system to change the status of a service is common among all init implementations. Since Linux is still in the middle of transitioning from System V implementation, this common command style is what is helping the transition.

Upstart

Upstart was used in the earlier implementations of Ubuntu, but today Ubuntu uses the Systemd implementation. Upstart was created to improve on the System V implementation.
It uses an events & jobs model that helps it to respond to an event as soon as it happens. Jobs are the actions it performs, and Events are the messages received from other processes that trigger the jobs.

To see a list of all the jobs along with their config, you can run ls /etc/init.

Screenshot from 2022-11-15 16-49-19.png

Now let us check one of these config files and run cat /etc/init/whoopsie.conf

Screenshot from 2022-11-15 16-50-52.png

As you can see, Whoopsie is a crash report submission daemon. If our system crashes, this daemon process reports it. start on runlevel [2345] means that the system needs to start the whoopsie daemon when the runlevels are either 2, 3, 4, or 5. And stop on runlevel [!2345] means that the system needs to stop the whoopsie daemon when the runlevels are not 2, 3, 4, or 5.

How does the Upstart Implementation work?

First, Upstart loads up all the configs from /etc/init. Then, when the startup event occurs, it will run all the jobs meant to be triggered by that event. The jobs that run through the startup event will trigger even more events. These events will run more jobs which might trigger even more events. So, this process keeps happening until all the jobs have run.

Systemd

Systemd is the latest, most emerging and adapted standard for init implementations. It uses goals to get your system up and running, where goals are the targets that you need to achieve. It is flexible and robust and does not do things sequentially to get the processes started.

How does the Systemd Implementation work?

It also loads up all the config files in the /etc/systemd and /lib/systemd/system directories.

Screenshot from 2022-11-14 17-40-06.png

Now let us go through the output of the second directory by running ls /lib/systemd/system | less. As the output will be quite long, we are using less with pipe (|). To understand less and pipe commands in deep detail with examples, click here

Screenshot from 2022-11-14 17-46-40.png

You can notice that there are a lot of files ending with .target. Let us understand the default.target file. Earlier, we understood in the Upstart implementation that the startup event triggered a lot of jobs, that in return triggered a lot of events, which again triggered a lot of jobs.

Now, in the Systemd init implementation, it first looks at all the configs and then all the goals it has when a system is booted. All those goals are inside the default.target file.
Run the command cat /lib/systemd/system/default.target for more information about this file.

Screenshot from 2022-11-14 17-54-06.png

It first tells us that this file is a part of systemd, followed by some information on systemd. Then, it tells us what this file requires, wants, conflicts, and what happens after. In short, it has everything a system needs to do on bootup. This file says it requires a multi-user.target file. Let us check that one out by running cat /lib/systemd/system/multi-user.target.

Screenshot from 2022-11-14 18-04-12.png

Now, this file says it requires a basic.target file. This is how the whole process happens on boot up led by default.target. They check each other’s dependencies, load each other and make our system work.

Systemd Targets

Similar to how System V has runlevels, Systemd has 'targets'.

  • poweroff.target -> As the name suggests, it is for the shutdown.
  • rescue.target -> It is for a single user.
  • multi-user.target -> It is for multiple users with networking.
  • graphical.target -> It is for multiple users with networking and GUI.
  • reboot.target -> It is for reboot/restart.

The default.target is usually for graphical.target because GUI is the first thing we see. Managing Power States of the System

To shut down your system, you can run sudo shutdown –h now where the –h flag is equivalent to poweroff.

To reboot the system you can run the command sudo reboot. It simply changes the state of the system.

Since we are using the Systemd init implementation, these above two commands will be directed to the target file. And then, it will start completing those targets and their dependencies to complete the goal. That goal could be to shut down or reboot your system.

Thanks for reading :)

To read the previous blogs of this Linux Series, go to blog.gauranggaur.com

To see the video lecture of this blog, go to this youtube video

Follow me on Twitter

Do comment your thoughts, questions or anything unique you learned below!

Did you find this article valuable?

Support Kshitij Sharma by becoming a sponsor. Any amount is appreciated!