Thursday, January 24, 2013

gummiboot

Maybe it's not obvious, but boot loader could be pretty simple. It's really not necessary to use turing-complete language in config files or extra filesystem drivers -- all this is overkill with UEFI firmware.

If you have a machine with UEFI, then I have good news for you:
  • the firmware is able to read GPT partition table (by the way, it's the best partition table format at all)
  • it's able to read data from FAT32 filesystem from you system partition (GPT uses partition type specific UUIDs to identify partitions)
  • it's possible to use more then one boot loader (it means that you can try another boot loader and your original boot method won't be affected)
  • you can modify your UEFI boot setting from Linux command line (reboot -> bios -> reboot is unnecessary)
  • all your configured boot loaders are visible in your bios boot menu (e.g. F12 for ThinkPad)
I guess that for Fedora 19 we will have rpm packages and some nice way how to integrate gummiboot to the distribution (don't forget that with UEFI you can use more boot loaders, so the official distribution boot loader as well as alternative methods maybe be supported).

My How-to:

Install gnu-efi library and EFI boot manager (for example for Fedora):
  # yum install gnu-efi efibootmgr
compile gummiboot:
  $ git clone git://anongit.freedesktop.org/gummiboot
  $ cd gummiboot
  $ make
check your partition table, /dev/sda1 is usually the system partition (from EFI point of view), use partx(8) to see more details:
  # partx -n 1 /dev/sda
  NR START     END SECTORS  SIZE NAME                 UUID
   1  2048 2050047 2048000 1000M EFI System Partition 623b2882-c50b-48af-b3f8-f19e8639b02b
the partition with FAT filesystem is mounted on /boot/efi, use findmnt(8) to see more details:
  # findmnt /dev/sda1
  TARGET    SOURCE    FSTYPE OPTIONS
  /boot/efi /dev/sda1 vfat   rw,relatime
if you have UEFI machine than the partition is probably already initialized by your distribution.

Now install the boot loader:
   # mkdir -p /boot/efi/EFI/gummiboot
   # cp gummiboot.efi /boot/efi/EFI/gummiboot/
inform your UEFI about the new boot loader:
   # efibootmgr -c -L "Gummiboot" -l '\EFI\gummiboot\gummiboot.efi'
now in your bios boot menu will be a new entry "Gummiboot". Note that UEFI uses windows-like paths, so '\' is correct. The efibootmgr(8) is a command line util to manipulate with boot EFI variables, you need kernel with /sys/firmware/efi/vars support (for example standard Fedora kernel).

Use
   # efibootmgr -v
to see more details, you can also change boot order and another things by efibootmgr.

The last step is to add entry (kernel) to gummiboot, there is a nice script in gummiboot in repository:
  loader-postinst.sh kernel-version path-to-kernel  
you can run this script manually or you can add the script into /etc/kernel/postinst.d (this directory does not exist by default on Fedora, mkdir -p is your friend...), then the script will be automatically executed after new kernel install.

The script copies the kernel to /boot/efi/distroname/machine-id where distroname is /etc/os-release and machine-id is is /etc/machine-id.

The script also creates /boot/efi/loader/entries/*.conf file with kernel command line from /etc/kernel/cmdline, paths to kernel, initrd. etc.

The result:

  • we have kernel in boot loader independent directory, you can use another boot loader (UEFI Shell, elilo, etc.) to read the kernel images
  • all is accessible for UEFI firmware on FAT filesystem (boot loader does not have to support ext4 filesystem for example)
  • separate config files for each kernel in /boot/efi/loader/entries/ directory
  • /etc/kernel/postinst.d based solution is extendable and open for alternative boot loaders.
Yes, gummiboot does not provide console to resolve possible boot problems. It seems unnecessary, you can install UEFI Shell. For more details see Arch Wiki.

Reboot :-)