UEFI Introduction

From PCLinuxOSHelp Knowledge Base
Revision as of 03:23, 24 January 2023 by Terryn (talk | contribs) (Added info about partitioning.)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

The old BIOS

Until recently, the way PCs start up had remained unchanged since the PC was invented back in the 1980s. A chip on the motherboard contains special program code known as the BIOS (an acronym of Basic Input/Output System). When power is applied the CPU begins executing this code which is responsible for starting the computer.

The BIOS was originally devised as an interface between the Operating System and the hardware devices. It was (and still is) 16bit real mode code whereas Operating Systems have moved on through the years to 32bit and now 64bit protected mode code. For this reason Operating Systems no longer use the BIOS interface to control hardware devices but have their own device drivers instead. So today the role of the BIOS is reduced to carrying out a series of Power On Self Tests (POST) before trying to locate bootloader code on some connected storage media, usually a disk drive. It is the bootloader code which then loads the Operating System which in our case begins with the Linux kernel.

Space in the BIOS chip was very limited and so the code for locating the bootloader had to be very simple and work for every kind of disk drive that could be connected to the system. This meant the bootloader code had to be placed somewhere the BIOS code could easily find it. The location chosen was the first sector (sector 0) since every type of drive has one! This is called the Master Boot Record or MBR.

The MBR serves two purposes: it contains the bootloader code that the BIOS executes to start the boot process, and also the partition table that defines the location of the filesystems on the disk. All of this information has to be stored in the first sector of the disk and is therefore limited to 512 bytes. 446 bytes for the bootloader code and a partition table containing up to four 16-byte records. The last two bytes contain a signature that the BIOS uses to recognize a valid MBR. Having the MBR in the first sector means that there can be only 1 per disk and this is why we can run into problems when dual-booting Linux and Windows (or multiple Linux distros) on a single disk drive. The Operating Systems can compete for control of the MBR and we can suddenly find we are unable to boot one of the Operating Systems because another has taken control and overwritten the MBR. The partition table uses 32bit sector address fields which means it can only address up to 2TB and hard disk sizes have now increased beyond that.

The new UEFI

So the 30+ year old BIOS has several limitations: We are limited to one bootloader per drive, 4 primary partitions per drive and a drive size of <2TB. Two new technologies have been introduced to remove these limitations. The BIOS has been superseded by UEFI (Unified Extensible Firmware Interface) and the MBR concept has been replaced with a GPT (GUID Partition Table) partitioning scheme. The two technologies are related but separate. You don’t have to have both but it is much easier if you have both or neither! The new GPT partitioning scheme supports up to 128 partitions and uses 64bit sector addresses which allows storage of 2^64 sectors or 9.4ZB which is more than all the storage currently existing in the world!

UEFI does not look in sector 0 for a bootloader but instead allows multiple bootloaders to exist on a single disk by using a special partition on the disk instead of a single absolute sector. This special partition is called the EFI System Partition (ESP) and is formatted with a FAT filesystem (usually FAT32). Where BIOS can only read single sectors, UEFI firmware can read partition tables and FAT filesystems. This means that bootloader programs can be built in the same way as other programs on the system and stored in the filesystem on the ESP. The specification suggests that bootloader programs are stored in vendor specific sub directories under a top level directory called EFI. The GRUB2 bootloader program created by the installer can be found in the /EFI/pclinuxos directory and is called grubx64.efi. So if we were to mount the ESP at /boot/EFI, the full path to the bootloader program would be /boot/EFI/EFI/pclinuxos/grubx64.efi.

The UEFI firmware contains boot manager code which is responsible for locating and launching bootloader programs. This boot manager is configurable via a number of EFI “variables” that are stored in NVRAM. These variables are used by the boot manager to present a menu of possible bootloaders and is usually accessed by pressing a function key as the system is powering up but before it tries to boot an Operating System. This is similar to the process that was used for changing BIOS settings but UEFI has an added advantage that it also allows us to access these variables from the Operating System once booted. This is done with the efibootmgr command which needs to be run as root. Running efibootmgr without any arguments displays the current values of the EFI variables:

[root@localhost ~]# efibootmgr  
BootCurrent: 0000 
Timeout: 0 seconds 
BootOrder: 0000,0001,2001,2002,2003 
Boot0000* pclinuxos 
Boot0001* Windows Boot Manager 
Boot2001* EFI USB Device 
Boot2002* EFI DVD/CDROM 
Boot2003* EFI Network

The first variable of interest is BootOrder which, as the name implies, determines the order in which the firmware tries bootloader programs. Following that are the Bootnnnn variables which represent the actual bootloader entries. The values for nnnn match up with the BootOrder entry which means in the example above that the firmware will first try to boot the pclinuxos entry, if that fails then it will move on to the Windows Boot Manager entry and so on. If none of the entries result in a successful boot then as a last resort the firmware will look for /EFI/BOOT/bootx64.efi on the ESP and attempt to boot with that.

Nowadays nearly all motherboards come with UEFI firmware instead of BIOS. Fortunately, PCLinuxOS supports the new UEFI way of booting (UEFI/GPT) as well as the old BIOS way (BIOS/MBR) on both the installation ISOs and the systems installed from them. Not all Operating Systems can though and so UEFI firmware usually has a way of emulating the old BIOS so that these Operating Systems can still be booted. This can create confusion for a number of reasons. Firstly, different manufacturers call it different things. You may see it referred to as legacy boot, legacy BIOS or CSM (Compatibility Support Module). Secondly, the way manufacturers give the user access to control which type of boot is used varies between manufacturers as well so it is not easy to give instructions that are universally applicable.

Implications for partitioning

As stated above the introduction of UEFI firmware also brought with it a new partitioning scheme called GPT. The two are separate but related. You don’t have to have both but it is much easier if you have both or neither!

If you intend to boot in UEFI mode you should partition your drive with the new GPT scheme. When you install the OS you will need the usual root and swap partitions and in addition you will need to create an EFI System Partition (ESP) to hold the bootloader files. The PCLinuxOS installer has a specific type for this and will insist that you create one before you can proceed with the install.

The ESP is also added to the /etc/fstab file so that the partition is mounted when the newly installed OS boots. This isn't a requirement for booting the system but if you want to run any bootloader query or configuration tools while booted then the ESP needs to be available.

Sometimes you will want the option to boot in BIOS/Legacy mode even when you have partitioned your drive with the GPT scheme. This creates a problem for GRUB2 because when booting in BIOS/Legacy mode the motherboard firmware will try to use the old MBR scheme of booting (i.e getting the bootloader from sector 0 of the drive). Having one sector (512 bytes) of code is not enough to boot a complex Operating System. This was not a problem with MBR partitioning because there were unused "spare" sectors after sector 0 (but before the first partition) where GRUB2 could store (embed) more code to complete the loading. These spare sectors are not available with GPT partitioning because the partition table starts immediately after the first sector of the drive. The solution is to create a special partition which just allocates some spare sectors for GRUB2 to store the stage2 code. Such a partition is called a BIOS Boot Partition. Very often on GPT drives sectors 34 thru 2047 are not used due to alignment and so provide an ideal location for this. Use your favorite partitioning tool to create a partition giving it type EF02 or "BIOS Boot".

For example, using fdisk:

Command (m for help): n
Partition number (4-128, default 4): 
First sector (34-50563071, default 3801088): 34
Last sector, +sectors or +size{K,M,G,T,P} (34-2047, default 2047): 
Created a new partition 4 of type 'Linux filesystem' and of size 1007 KiB.
Command (m for help): t
Partition number (1-4, default 4): 
Hex code (type L to list all codes): 4
Changed type of partition 'Linux filesystem' to 'BIOS boot'.

The BIOS Boot Partition should not be formatted with any filesystem as it is just a bunch of sectors for GRUB2 to use. Having both a BIOS Boot Partition and an ESP will allow you switch between BIOS/Legacy and UEFI booting from the same drive.