All about Linux Booting!! BIOS vs. UEFI

What is Booting?

Linux Booting” is the standard term for “starting up a computer.” It’s a shortened form of the word “bootstrapping,” which derives from the notion that the computer has to “pull itself up by its own bootstrap’s

The boot process consists of a few broadly defined tasks:

  • Finding, loading, and running bootstrapping code
  • Finding, loading, and running the OS kernel
  • Running startup scripts and system daemons
  • Maintaining process hygiene and managing system state transitions

The activities included in that last bullet point continue as long as the system remains up, so the line between bootstrapping and normal operation is inherently a bit blurry


Startup procedures have changed a lot in last years. The advent of modern (UEFI) BIOSs has simplified the early stages of booting, at least from a conceptual standpoint. In later stages, most Linux distributions now use a system manager daemon called systemd instead of the traditional UNIX init. systemd streamlines the boot process by adding dependency management, support for concurrent startup processes, and a comprehensive approach to logging, among other features.

Boot management has also changed as systems have migrated into the cloud. The drift toward virtualization, cloud instances, and containerization has reduced the need for administrators to touch physical hardware. Instead, we now have image management, APIs, and control panels.

During bootstrapping, the kernel is loaded into memory and begins to execute. A variety of initialization tasks are performed, and the system is then available to end users. The general overview of this process is shown in picture below

linux boot decryptinfo

Administrators have little direct, interactive control over most of the steps required to boot a system. Instead, admins can modify bootstrap configurations by editing config files for the system start-up scripts or by changing the arguments the boot loader passes to the kernel.

Before the system is fully booted, filesystems must be checked and mounted and system daemons started. These procedures are managed by a series of shell scripts (sometimes called “init scripts”) or unit files that are run in sequence by init or parsed by systemd. The exact layout of the startup scripts and the manner in which they are executed varies among systems.


When a machine is powered on, the CPU is hardwired to execute boot code stored in ROM. On virtualized systems, this “ROM” may be imaginary, but the concept remains the same.

The system firmware typically knows about all the devices that live on the motherboard, such as SATA controllers, network interfaces, USB controllers, and sensors for power and temperature. In addition to allowing hardware-level configuration of these devices, the firmware lets you either expose them to the operating system or disable and hide them.

On physical hardware, most firmware offers a user interface. However, it’s generally crude and a bit tricky to access. You need control of the computer and console, and must press a particular key immediately after powering on the system. Unfortunately, the identity of the magic key varies by manufacturer; see if you can glimpse a cryptic line of instructions at the instant the system first powers on. Barring that, try Delete, Control, F6, F8, F10, or F11. For the best chance of success, tap the key several times, then hold it down.

During normal bootstrapping, the system firmware probes for hardware and disks, runs a simple set of health checks, and then looks for the next stage of bootstrapping code.

In most cases, the system’s disk drives populate a secondary priority list. To boot from a particular drive, you must both set it as the highest-priority disk and make sure that “hard disk” is enabled as a boot medium.


Earlier PC firmware was called the BIOS ” Basic Input/Output System”. Over the last decade, however, BIOS has been supplanted by a more formalized and modern standard, the Unified Extensible Firmware Interface (UEFI). You’ll often see UEFI referred to as “UEFI BIOS,” but for clarity, we’ll reserve the term BIOS for the legacy standard in this chapter. Most systems that implement UEFI can fall back to a legacy BIOS implementation if the operating system they’re booting doesn’t support UEFI.

UEFI is the current revision of an earlier standard, EFI. References to the name EFI persist in some older documentation and even in some standard terms, such as “EFI system partition.” In all but the most technically explicit situations, you can treat these terms as equivalent.

UEFI support is pretty much universal on new PC hardware these days, but plenty of BIOS systems remain in the field. Moreover, virtualized environments often adopt BIOS as their underlying boot mechanism, so the BIOS world isn’t in danger of extinction just yet.

As much as we’d prefer to ignore BIOS and just talk about UEFI, it’s likely that you’ll encounter both types of systems for years to come. UEFI also builds-in several accommodations to the old BIOS regime, so a working knowledge of BIOS can be quite helpful for deciphering the UEFI documentation.

Legacy BIOS

Traditional BIOS assumes that the boot device starts with a record called the MBR (Master Boot Record). The MBR includes both a first-stage boot loader (aka “boot block”) and a primitive disk partitioning table. The amount of space available for the boot loader is so small (less than 512 bytes) that it’s not able to do much other than load and run a second-stage boot loader.

Neither the boot block nor the BIOS is sophisticated enough to read any type of standard filesystem, so the second-stage boot loader must be kept somewhere easy to find. In one typical scenario, the boot block reads the partitioning information from the MBR and identifies the disk partition marked as “active.” It then reads and executes the second-stage boot loader from the beginning of that partition. This scheme is known as a volume boot record.’

Alternatively, the second-stage boot loader can live in the dead zone that lies between the MBR and the beginning of the first disk partition. For historical reasons, the first partition doesn’t start until the 64th disk block, so this zone normally contains at least 32KB of storage: still not a lot, but enough to store a filesystem driver.

To effect a successful boot, all components of the boot chain must be properly installed and compatible with one another. The MBR boot block is OS-agnostic, but because it assumes a particular location for the second stage, there may be multiple versions that can be installed. The second-stage loader is generally knowledgeable about operating systems and filesystems (it may support several of each), and usually has configuration options of its own.


The UEFI specification includes a modern disk partitioning scheme known as GPT (GUID Partition Table, where GUID stands for “globally unique identifier”). UEFI also understands FAT (File Allocation Table) filesystems, a simple but functional layout that originated in MSDOS. These features combine to define the concept of an EFI System Partition (ESP). At boot time, the firmware consults the GPT partition table to identify the ESP. It then reads the configured target application directly from a file in the ESP and executes it.

Because the ESP is just a generic FAT filesystem, it can be mounted, read, written, and maintained by any operating system. No “mystery meat” boot blocks are required anywhere on the disk. (Truth be told, UEFI does maintain an MBR-compatible record at the beginning of each disk to facilitate interoperability with BIOS systems. BIOS systems can’t see the full GPT-style partition table, but they at least recognize the disk as having been formatted. Be careful not to run MBR-specific administrative tools on GPT disks. They may think they understand the disk layout, but they do not.)

In the UEFI system, no boot loader at all is technically required. The UEFI boot target can be a UNIX or Linux kernel that has been configured for direct UEFI loading, thus effecting a loaderless bootstrap. In practice, though, most systems still use a boot loader, partly because that makes it easier to maintain compatibility with legacy BIOSes.

Also Read:

UEFI saves the pathname to load from the ESP as a configuration parameter. With no configuration, it looks for a standard path, usually /efi/boot/bootx64.efi on modern Intel systems. A more typical path on a configured system (this one for Ubuntu and the GRUB boot loader) would be /efi/ubuntu/grubx64.efi. Other distributions follow a similar convention.

UEFI defines standard APIs for accessing the system’s hardware. In this respect, it’s something of a miniature operating system in its own right. It even provides for UEFI-level add-on device drivers, which are written in a processor-independent language and stored in the ESP. Operating systems can use the UEFI interface, or they can take over direct control of the hardware.

Because UEFI has a formal API, you can examine and modify UEFI variables (including boot menu entries) on a running system. For example, efibootmgr -v shows the following summary of the boot configuration:


Most bootstrapping procedures include the execution of a boot loader that is distinct from both the BIOS/UEFI code and the OS kernel. It’s also separate from the initial boot block on a BIOS system, if you’re counting steps.

The boot loader’s main job is to identify and load an appropriate operating system kernel. Most boot loaders can also present a boot-time user interface that lets you select which of several possible kernels or operating systems to invoke.

Another task that falls to the boot loader is the marshaling of configuration arguments for the kernel. The kernel doesn’t have a command line per se, but its startup option handling will seem eerily similar from the shell. For example, the argument single or -s usually tells the kernel to enter single-user mode instead of completing the normal boot process.

Such options can be hard-wired into the boot loader’s configuration if you want them used on every boot, or they can be provided on the fly through the boot loader’s UI.

Also Read:


GRUB, developed by the GNU Project, is the default boot loader on most Linux distributions. The GRUB lineage has two main branches: the original GRUB, now called GRUB Legacy, and the newer, extra-crispy GRUB 2, which is the current standard. Make sure you know which GRUB you’re dealing with, as the two versions are quite different.

GRUB 2 has been the default boot manager for Ubuntu since version 9.10, and it recently became the default for Red Hat Enterprise Linux 7. All our example Linux distributions use it as their default. In this book we discuss only GRUB 2, and we refer to it simply as GRUB.FreeBSD has its own boot loader (covered in more detail in The FreeBSD boot process). However, GRUB is perfectly happy to boot FreeBSD, too. This might be an advantageous configuration if you’re planning to boot multiple operating systems on a single computer. Otherwise, the FreeBSD boot loader is more than adequate.

GRUB configuration

GRUB lets you specify parameters such as the kernel to boot (specified as a GRUB “menu entry”) and the operating mode to boot into.

Since this configuration information is needed at boot time, you might imagine that it would be stored somewhere strange, such as the system’s NVRAM or the disk blocks reserved for the boot loader. In fact, GRUB understands most of the filesystems in common use and can usually find its way to the root filesystem on its own. This feat lets GRUB read its configuration from a regular text file.

The config file is called grub.cfg, and it’s usually kept in /boot/grub (/boot/grub2 in Red Hat and CentOS) along with a selection of other resources and code modules that GRUB might need to access at boot time. Changing the boot configuration is a simple matter of updating the grub.cfg file.

Although you can create the grub.cfg file yourself, it’s more common to generate it with the grub-mkconfig utility, which is called grub2-mkconfig on Red Hat and CentOS and wrapped as update-grub on Debian and Ubuntu. In fact, most distributions assume that grub.cfg can be regenerated at will, and they do so automatically after updates. If you don’t take steps to prevent this, your handcrafted grub.cfg file will get clobbered.

As with all things Linux, distributions configure grub-mkconfig in a variety of ways. Most commonly, the configuration is specified in /etc/default/grub in the form of sh variable assignments. 


After editing /etc/default/grub, run update-grub or grub2-mkconfig to translate your configuration into a proper grub.cfg file. As part of the configuration-building process, these commands inventory the system’s bootable kernels, so they can be useful to run after you make kernel changes even if you haven’t explicitly changed the GRUB configuration.

You may need to edit the /etc/grub.d/40_custom file to change the order in which kernels are listed in the boot menu (after you create a custom kernel, for example), set a boot password, or change the names of boot menu items. As usual, run update-grub or grub2-mkconfig after making changes.

As an example, here’s a 40_custom file that invokes a custom kernel on an Ubuntu system:

linux grub2 decryptinfo

GRUB loads the kernel from /awesome_kernel. Kernel paths are relative to the boot partition, which historically was mounted as /boot but with the advent of UEFI now is likely an unmounted EFI System Partition. Use gpart show and mount to examine your disk and determine the state of the boot partition

The GRUB command line

GRUB supports a command-line interface for editing config file entries on the fly at boot time. To enter command-line mode, type c at the GRUB boot screen.From the command line, you can boot operating systems that aren’t listed in the grub.cfg file, display system information, and perform rudimentary filesystem testing. Anything that can be done through grub.cfg can also be done through the command line.

linux grub commands decryptinfo



, , , , , , , , , , , , , , , , , , ,

Leave a Reply