AMSA

Week 1: System Booting 101

Ferran Aran Domingo
Francesc Solsona Tehàs
Oriol Agost Batalla
Pablo Fraile Alonso

Goals for today

  • Any questions from the previous session?
  • Learn how your Linux system boots, from zero to a working environment
  • Present and explain Prac-1

Booting process

Hardware

Boot steps

  • Magical Power Button: As soon as you press the magical power button on your laptop or desktop computer, it starts working. The motherboard sends a signal to the power supply device.

  • After receiving the signal, the power supply provides the proper amount of electricity to the computer. Once the motherboard receives the power good signal, it tries to start the CPU.

  • The CPU resets it’s registers, and the next instruction on the EIP is (0xfffffff0). It’s the memory location at which the CPU expects to find the first instruction to execute after reset. It contains a jump (jmp) instruction that usually points to the firmware of your pc/laptop/server entry point.

Firmware

What is the BIOS/UEFI?

  • Your pc needs a firmware for testing, initializing (and in some cases, configure) devices. Surely you have ever called it BIOS or UEFI

  • Such as Adam Williamson says:

    You’ve probably read a lot of stuff on the internet about UEFI. Here is something important you should understand: 95% of it was probably garbage.

  • Both BIOS and UEFI are types of firmware for computers. BIOS-style firmware is (mostly) only ever found on IBM PC compatible computers. UEFI is meant to be more generic, and can be found on systems which are not in the ‘IBM PC compatible’ class.

  • UEFI is a standard (you can read it here), that motherboard manufacturers follow to create firmware compatible with your specific hardware. Before UEFI, there was no standard, and booting, was WILD

How does UEFI launch the bootloader?

We have time?

Can we explain the MBR booting?

  • The UEFI spec defines an executable format and requires all UEFI firmwares be capable of executing code in this format (EFI). When you write a bootloader for native UEFI, you write in this format.

  • The UEFI spec defines something called the UEFI boot manager. (Linux distributions contain a tool called efibootmgr which is used to manipulate the configuration of the UEFI boot manager).

  • The UEFI boot manager is a firmware policy engine that can be configured by modifying architecturally defined global NVRAM variables. The boot manager will attempt to load UEFI drivers and UEFI applications (including UEFI OS boot loaders) in an order defined by the global NVRAM variables.

Playing with efibootmgr

We encourage you to play with efibootmgr, to see your boot priority, device where it boots, etc

# efibootmgr -v
BootCurrent: 0002
Timeout: 3 seconds
BootOrder: 0003,0002,0000,0004
Boot0000* CD/DVD Drive  BIOS(3,0,00)
Boot0001* Hard Drive    HD(2,0,00)
Boot0002* Fedora        HD(1,800,61800,6d98f360-cb3e-4727-8fed-5ce0c040365d)File(\EFI\fedora\grubx64.efi)
Boot0003* opensuse      HD(1,800,61800,6d98f360-cb3e-4727-8fed-5ce0c040365d)File(\EFI\opensuse\grubx64.efi)
Boot0004* Hard Drive    BIOS(2,0,00)P0: ST1500DM003-9YN16G        .

Just for curious people!

Boot0000 and Boot0004 in this example are actually BIOS compatibility mode entries, not UEFI native entries. They have not been added to the UEFI boot manager configuration by any external agency, but generated by the firmware itself and added to the nvram variables.

Recap

Software

Bootloader

It has a very simple objective, which is:

  • Show a boot menu with multiple binaries that you can boot.1
  • Load the Kernel and Initrd (if any) to memory.
  • The kernel has a boot convention that the bootloader prepares (memory layout and cpu registers).

Kernel. What the hell it is? Why we need one?

  • A kernel is just a program.

  • Really, it’s just a program

  • A difficult and big one, but after all, a program.

You don’t trust us? Let’s assert that!

TODO: Use the file command for seeing that the kernel is an ELF file, and that another “normal” program, like for example python, is another ELF file.

So, what does the kernel do?

  • Create abstractions for us (the programmers) to create easy applications.

  • Handle resources and concurrency. We can split this category in:

    • Processes/Threads (CPU, tasks, etc)

    • Memory Management

    • FileSystems

    In this course…

    We’ll talk and explore some parts of the linux kernel (not the internal ones, but the abstractions it provides to us).

Initramfs

Okey, the kernel has just started but…

  • What happens if I have my drive encrypted?

  • What happens if my drive depends on the network?

    That’s why initrd/initial ramdisk exists!

    So we can inject the necessary junk that needs user access or external resources or modules that are not inside the default kernel, while we’re loading the system.

Does our system use an initramfs?

We can see that our system uses a initramfs watching the kernel boot flags with the following command (on a freshly booted system):

$ sudo dmesg | head -n 10
initrd=\EFI\nixos\m9zbpy56cvgqgrvgkcksr8kx1qgdv6nx-initrd-linux-6.12.40-initrd.efi init=/nix/store/m4lrjsqxrwrj0j5b0l66yjv8hnz23mbr-nixos-system-legolas-25.11.20250731.94def63/i nit loglevel=4 lsm=landlock,yama,bpf

Recommended read

We strongly recommend to read some parts of the linux kernel documentation about the initrd

Are you bored and like the C programming language?

Init process

  • Init is the first process started during system boot.

  • It is a daemon process that continues running until the system is shut down. Init is the direct or indirect ancestor of all other processes, and automatically adopts all orphaned processes.

  • It is started by the kernel using a hard-coded filename (you can change the init process, like for example init=/bin/bash).

Systemd

  • In the 99% of linux distros, the init system is systemd.

  • The commands used to interact with systemd usually start with systemctl.

  • systemd saves the services, configurations, etc. under /etc/systemd/*

  • Try on your system:

$ sudo systemctl status

agetty and login

  • After systemd has

Recap

Kernel Messages with dmesg

You don’t need to worry much about the kernel (yet). The only thing we need right now is to see its log messages, which you can do with:

$ sudo dmesg

From the man page:

dmesg - print or control the kernel ring buffer

Implementing our dmesg

from collections import deque
from typing import List

MAX_KERNEL_MESSAGES = 10 # I only want to log 10 messages from my stupid kernel.
messages = deque(maxlen=MAX_KERNEL_MESSAGES)

def printk(message: str) -> None:
    messages.append(message)

def dmesg() -> List[str]:
    return messages

How It Logs

All the drivers, stuff that does the kernel under the hood, will be logged with:

printk("Initializing network driver for card intel AC3200...")

To read the logs, just call:

dmesg()

Real implementation

The real kernel implementation is more complex (concurrency, performance, real C code, etc.). If you’re curious or bored, you can read it here

Systemd Journaling

  • Very similar to the kernel dmesg, but for all the apps that systemd spawns 1

  • You can see the log from the system daemons 2 with the journalctl command.

Questions:

  • What parts of the boot process diagram could be omitted?

  • If our system shows the following and then reboots, what could be happenning?

    TODO: Add bootloader image here

  • If I put my user and password (correctly) and then the screen flashes and returns me to the login screen again, what could be happenning?

References

Additional Exercices

If you really want to understand a little bit more what happens under the hood, you can do the following exercices. BE aware that you should read the “Really Recommended References” first, and then try to do this exercices.

Prac-1

  • We’ll add a systemd unit that, when our system finishes booting, it prints on the systemd journaling our name in ASCII art style.

  • You can test if it works doing:

  • More info inside the Lab 1 page.