Linux Grub/UEFI boot system - introduction / howto for Ubuntu 19.04


Better read: Data Consistency in Distributed System - CAP, PACELC

This blog is mainly focused on my Philosophical and theoretical ideas.

From time to time I have practical posts that are too few to deserve a blog by themselves. I still hope my other work (like above) is even more valuable than such practical article as below.

* * *


On short: in order to Boot Linux in UEFI mode:

  1. UEFI loads Grub and a minimal grub.cfg from a fat32/EFI partition. Ubuntu uses 2 directories: EFI/Boot and EFI/ubuntu
  2. Grub detects the root partition (via UUID) and loads the kernel and initrd from that Linux/ext4 partition. In Ubuntu, the minimal grub.cfg calls another grub.cfg from the ext4 partition - containing boot menu.
More details



Linux booting with Grub

In order to boot Linux you need to load into memory the 'kernel' file and an 'initrd' file (a small starting filesystem). Usually the kernel also receives as parameter the real "root" partition (like root=/dev/sda1) and some other starting parameters like the starting point (init=/bin/bash).

In order to load kernel and initrd, Ubuntu uses the 'Grub' system, that has a version for legacy Boot system and one for the new (U)EFI boot system. Here we will only cover the UEFI boot.

Grub is able to read kernel and initrd from multiple partition types, including ext4. Grub is also responsible to identify the right partition, for example based on filesystem's UUID - even if the disk order changes. You can still use root=/dev/sdb2 directly, however the disk letter can change once you change the boot order or you add another USB drive.

In order to load the Grub system in UEFI boot mode, you need a small fat32 'EFI' partition ('esp' and 'boot' flags). The "UEFI bios" cannot read from the Linux/ext4 partition.

Once the Grub is loaded from the EFI/fat32 partition, it can read kernel and initrd from the Linux ext4 partitions (like '/' or '/boot') or from other partition types, even from the EFI partition.

Usually the grub.cfg from the EFI partition is minimal and only loads the /boot/grub/grub.cfg from the Linux ext4 root partition. This second grub.cfg contains the actual grub menu that allows to choose from multiple kernels and even boot the Windows partition. This approach requires minimum space and updates on the EFI partition. Still, Ubuntu Linux will mount this fat32 partition as "/boot/efi", to be able to make updates if needed.

If you want, the EFI/ubuntu/grub.cfg from the EFI partition can be also configured with multiple menu options. It can directly load the kernel and initrd from the ext4 partition without the need of the second grub.cfg. However, such configuration is fragile and will not be kept in sync when you update Ubuntu Linux.

A minimum EFI config file that calls the ext4 grub.cfg looks like this:
# more EFI/ubuntu/grub.cfg
search --set=root --fs-uuid <blkid uuid> --hint-efi hd0,gpt2 --no-floppy
set prefix=(root)'/boot/grub'
configfile $prefix/grub.cfg



UEFI

UEFI is the new boot system replacing the old BIOS boot system. While we still call it 'Bios', this new bootstrap system is more correctly named 'UEFI'. The new 'UEFI' can boot in the new '(U)EFI' mode or in the legacy 'Bios' mode. You need to choose 'UEFI/EFI' boot mode for this tutorial.

UEFI boot mode can read a fat32 partition, named 'EFI', and load/start *.efi files that bootstraps the OS boot system (Grub for Linux). The EFI partition contains an 'EFI' directory, that can host multiple boot systems (like Win10 and Ubuntu). Each boot system is placed in a sub-directory of the EFI main directory.

Multiple disks (even USB thumb-drives) can each have an EFI partition, and you can choose the order in the "Boot" setting. At start, the "Bios" will enumerate all the boot systems in the EFI partitions and you can change their order.

Officially the UEFI partition should be created using the new GPT partition table (instead of BIOS/msdos). The efi partition must be formatted fat32 and it should have the flag "efi" (includes 'bootable'). However some systems might also boot from EFI partitions that are created in a non-GPT partition table. The msdos partition should be marked active/bootable. Better use GPT to stay on the safe side.


Grub options

Grub contains various modules. EFI grub usually comes with support for ext4 filesystem included. Then you can load by grub.cfg and even manually the kernel and initrd files from the ext4 partition.

You can stop the grub automatic boot by pressing <shift> or moving arrows in the menu.
Then you can enter command prompt pressing 'c'
In command prompt you can boot manually, even if the boot.cfg is wrong
- ls #shows disks like (hd1,msdos1), (hd2,gpt1); You can often guess the disk and partition
- cat (hd1,gpt1)/EFI/ubuntu/grub.cfg #show the file
- kernel (hd1, gpt2)/boot/vmlinuz
- initrd (hd1, gpt2)/boot/initrd
- set root=/dev/sda2 #this partition will be mounted by linux kernel
- boot #should boot that system

To load the grub menu from the ext4 partition you can do manually something like in the small grub.cfg above. Normally you need to detect root, prefix, however you can skip this and put the (disk,partition) directly. Autocomplete will tell you if your guess was right.


Conclusion

Grub is very powerful and versatile, however many howtos are too complicated to grasp the basics. Hopefully this article can help to faster ramp up in understanding Linux booting using grub in UEFI mode, even if the howto might be less rigorous than official documentation.


Dear reader, please leave a message if you exist! ;) Also, please share this article if you find it interesting. Thank you.

Comments