Progress pill
Kernel level

Basic input output system (BIOS) and boot process

System Programming Fundamentals

Basic input output system (BIOS) and boot process

Modern software can operate on two levels: kernel level or user level.
Most of the applications you use exist in user level, and can only access the hardware by making requests to kernel-level software.
Kernel-level software has direct control over the hardware, which makes it more powerful and performant, but also harder and riskier to write.
In this section we're gonna explore how the kernel works and how it interacts with other components. Booting a Linux system is a chain of small programs handing control to the next one, each preparing the machine a bit more until you end up in a full multi-user environment.
When you press the power button, the first code that runs is the firmware on the motherboard. On older machines this is usually the BIOS (Basic Input/Output System); on newer ones it is often UEFI firmware (Unified Extensible Firmware Interface).
This first program performs a test (a quick hardware check often called POST), initializes basic hardware such as the CPU, RAM and some buses, and then looks at its configuration to decide which device to try to boot from (an internal disk, a USB stick, or maybe the network).
From the chosen boot device, the firmware loads a small piece of code into memory and jumps to it. This piece of code is the bootloader.
On Linux systems, common bootloaders are GRUB or systemd-boot. The bootloader’s role is to present possible kernels and boot options, load the chosen Linux kernel image into memory, and then transfer control to the kernel. Once the bootloader jumps into it, the Linux kernel takes over. As mentioned before, the kernel is the privileged part of the operating system that talks directly to the hardware.
Once loaded, the kernel:
  • Decompresses itself (most kernels are compressed on disk).
  • Sets up low-level CPU state, interrupt handling, basic memory management, and core subsystems.
  • Initializes built-in drivers so it can access RAM, CPU, and at least one storage or bus.
At this point everything is still happening entirely in kernel space; there is no user-space process yet. To move beyond this minimal environment, the kernel uses an initial RAM filesystem called initramfs.
An initramfs (initial RAM filesystem) is a small, compressed archive that the bootloader loaded into memory alongside the kernel. The kernel unpacks this archive into RAM and treats it as a tiny, temporary filesystem.
It usually contains a minimal user space: a few binaries, a basic shell, configuration files and sometimes extra kernel modules. Inside the initramfs there is also a small user-space program, usually located at /init, which orchestrates these early steps.
The job of this initramfs environment is to prepare the real root filesystem that the system will use for normal operation. That preparation can include loading additional drivers, scanning for disks, unlocking encrypted volumes etc.
In other words, the initramfs bridges the gap between the very generic kernel and whatever complex storage setup your system actually uses. Once the initramfs code has located the real root filesystem and mounted it somewhere, it performs a root switch. A root switch means telling the kernel that from now on "/" should refer to this real, persistent filesystem instead of the temporary one in RAM.
The "real" root filesystem is the main on-disk filesystem that Linux will use long-term. It might be an ext4, XFS, Btrfs or another supported filesystem type, living on a physical disk, SSD or even over the network.
This filesystem contains the normal Linux directory hierarchy: binaries, libraries, configuration files, and so on. Crucially, it also contains the system’s main init program, such as /sbin/init or systemd. After switching the root, the initramfs environment executes this real init program from the new root, and then its work is done.
From this point on, the boot process is handled by the init system. The init system is the first long-lived user-space process and is responsible for starting and supervising all other services. It mounts any remaining filesystems listed in configuration files, brings up networking, starts background services, and eventually spawns one or more login processes so that users can log in.
Once you reach a login prompt or graphical desktop, the chain that started with the firmware has completed: firmware handed control to the bootloader, the bootloader to the kernel, the kernel to the initramfs, the initramfs to the real root filesystem and init, and init to all the user-space processes that make up a running Linux system.
At that point the boot process is considered complete and the system is running in its normal user-space environment.