paulgorman.org

Linux booting

BIOS booting

In BIOS booting, there's a boot sector known as a master boot record (MBR) on disk that the BIOS reads into RAM. BIOS expects to find this boot record at the start of the disk, wedged in before the start of the first partition. The MBR may also contain information about the disk's partitions. The BIOS boot record runs a second-stage boot loader (e.g. GRUB), and that second boot loader starts the OS.

This chain boot loading is necessary because a modern boot loader, like GRUB, is too much for BIOS to load directly.

BIOS only knows about the MBR; it doesn't know about the OS. The OS, once loaded, knows little about the BIOS.

BIOS is a de-facto standard of IBM PC-compatible lineage. BIOS is going away. The PC world is moving to the type of more advanced firmware long used on Mac's and *nix workstations.

On linux, grub-install can write a master boot record.

BIOS boot failure

If BIOS fails to find a bootable device, on most devices it throws an error message like "No bootable device found" and/or automatically enters the BIOS config utility.

UEFI

UEFI (unified extensible firmware interface) is a new, formal standard for PC firmware.

UEFI doesn't need to cram a boot record into the gap between the start of the disk and the first partition.

UEFI boot devices start with an EFI system partition (ESP). This partition is relatively large (the UEFI spec recommends 512 MB), and can contain a much more robust boot loader than the BIOS first-stage boot loader. The EFI partition must be formatted as FAT32. (The spec also allows FAT16 or FAT12 for removable media.)

Most UEFI firmware has a BIOS compatibility mode capable of simulating BIOS-style MBR booting.

GUID partition table (GPT) arrived along with UEFI. It provides a number of advantages over the MBR partition scheme, including the elimination of restrictions of primary and extended partition counts, the ability to provide a unique GUID (UUID) for physical disks and partitions independent of filesystems, vastly larger maximum partition sizes (upt to 2 ZiB), and checksums for partition tables.

Linux can manipulate the UEFI boot menu with efibootmgr.

UEFI boot failure

If UEFI fails to find a bootable device, it should drop the user into a UEFI shell, where we have a chance to take some action, like finding a boot device manually. Available options in the UEFI shell vary somewhat depending on the version.

GRUB

GRUB is the linux boot loader.

Note that everything these days uses GRUB 2 rather than the old version of GRUB (i.e. GRUB Legacy), and that the two differ significantly in configuration. We will look only at GRUB 2.

GRUB config

The GRUB config file is /etc/default/grub. Any changes we might be tempted to make by hand will almost certainly be made in this file.

Running update-grub reads '/etc/default/grub' and a number of other files (notably the shell scripts in '/etc/grub.d/') to generate the file /boot/grub/grub.cfg. We never edit 'grub.cfg' manually, because it's dangerous and any changes would get overwritten by future runs of `update-grub`.

(/usr/sbin/update-grub is a little shell script that wraps grub-mkconfig. Unfortunately, much of the grub documentation is in 'info' rather than man pages. See info grub.)

Then, run grub-install --recheck --bootloader-id foo /dev/sdX. This generates the grub boot image. It also, on a BIOS system, writes the MRB; on a UEFI system, it adds an entry to the firmware boot menu.

GRUB boot failure

GRUB has a command shell, and it will dump us in its shell if boot fails. The prompt may give us a clue about the problem. If the prompt reads "grub>", GRUB probably started normally, and was able to read its modules in '/boot/grub/i386-pc/'. If the prompt reads "rescue>", GRUB couldn't find its modules, and our options will be more limited.

grub> set pager=1
grub> ls
(hd0) (hd0,gpt2) (hd0,gpt1) (vg0-lv0)
grub> ls (hd0,1)/
lost+found/ bin/ boot/ cdrom/ dev/ etc/ home/  lib/
lib64/ media/ mnt/ opt/ proc/ root/ run/ sbin/
[...snip...]
grub> set root=(hd0,1)
grub> linux /boot/vmlinuz-3.16.0-4-amd root=/dev/sda1
grub> initrd /boot/initrd.img-3.16.0-4-amd
grub> boot

...and we should boot.

If we're at the rescue prompt, we'll need to (minimally) load GRUB's normal.mod and linux.mod first.

grub rescue> set prefix=(hd0,1)/boot/grub
grub rescue> set root=(hd0,1)
grub rescue> insmod normal
grub rescue> normal
grub rescue> insmod linux
grub rescue> linux /boot/vmlinuz-3.16.0-4-amd root=/dev/sda1
grub rescue> initrd /boot/initrd.img-3.16.0-49-amd
grub rescue> boot

Once booted, we may want to run update-grub to make permanent repairs. If the system boots with BIOS, something like grub-install /dev/sda will fix the MBR.

On UEFI systems, grub-install tries to do three things: generate a grub image (e.g. grubx64.efi), install the grub image to "/boot/efi/EFI/debian/", and it attempts to add an appropriate entry to the UEFI boot menu.

Software RAID

With software RAID, where you might have a two-disk mirror for example, you may want to install GRUB to both disks like grub-install --recheck --bootloader-id linux-sdb /dev/sdb and grub-install --recheck --bootloader-id linux-sda /dev/sda.

N.B. — if we make multiple devices bootable (sda and sdb), the device against which we run `grub-install` last/finally will become the first/default boot device.

Links