-partitioned hard drive; stage 1 (boot.img) can alternatively be written into one of the
partition boot sectors. -partitioned hard drive, booting on
BIOS firmware, or
UEFI compatibility mode (CSM) Booting When an
IBM PC compatible computer with a
BIOS is turned on, the BIOS finds the primary bootable device (usually the computer's hard disk) and runs the initial
bootstrap program from the
master boot record (MBR). The MBR is the first
sector of the hard disk. This bootstrap program must be small because it has to fit in a single sector. For a long time, the size of a sector has been 512 bytes. Since 2009 there are hard disks available with a sector size of 4096 bytes, called
Advanced Format disks, but such hard disks are still accessed in 512-byte sectors, using the
512e emulation. The legacy
MBR partition table supports a maximum of four partitions and occupies 64 bytes, combined. Together with the optional
disk signature (four bytes) and
disk timestamp (six bytes), this leaves between 434 and 446 bytes available for the
machine code of a boot loader. Although such a small space can be sufficient for very simple boot loaders, it is not big enough to contain a boot loader supporting complex and multiple
file systems, menu-driven selection of boot choices, etc. Boot loaders with bigger footprints are therefore split into pieces, where the smallest piece fits in the MBR, while one or more larger pieces are stored in other locations such as empty sectors between the MBR and the first partition. The code in the MBR then does little more than starting the second part. The purpose of the remaining part(s) of the boot loader is to actually boot an operating system by configuring it and starting the
kernel. Kernels are in most cases stored as files residing on appropriate file systems, but the concept of a file system is unknown to the BIOS. Thus, in BIOS-based systems, the duty of a boot loader is to access the content of those files, so it can be loaded into the
RAM and executed. One possible approach for boot loaders is to load kernel images by directly accessing hard disk sectors without understanding the underlying file system. Usually, an additional level of
indirection is required, in form of
maps or
map files auxiliary files that contain a list of physical sectors occupied by kernel images. Such maps need to be updated each time a kernel image changes its physical location on disk, due to installing new kernel images, file system defragmentation, etc. Also, in case of the maps changing their physical location, their locations need to be updated within the boot loader's MBR code, so the sectors indirection mechanism continues to work. This is not only cumbersome, but it also leaves the system in need of manual repairs in case something goes wrong during system updates. Another approach is to make a boot loader aware of the underlying file systems, so kernel images are configured and accessed using their actual
file paths. That requires a boot loader to contain a driver for each of the supported file systems, so they can be understood and accessed by the boot loader itself. This approach eliminates the need for hardcoded locations of hard disk sectors and existence of map files, and does not require MBR updates after kernel images are added or moved around. The configuration of a boot loader is stored in a regular file, which is also accessed in a file system-aware way to obtain boot configurations before the actual booting of any kernel images. Thus, fewer things can go wrong during system updates. As a downside, such boot loaders are larger and more complex. • boot.img (
stage 1) is written to the first 440 bytes of the
Master Boot Record (MBR boot code in sector 0), or optionally in a
partition boot sector (PBR). It addresses diskboot.img by a 64-bit
LBA address. The actual sector number is written by grub-install. diskboot.img is the first sector of core.img with the sole purpose to load the rest of core.img identified by LBA sector numbers also written by grub-install. • On MBR partitioned disks, core.img (
stage 1.5) is stored in the empty sectors (if available) between the MBR and the first partition. Recent operating systems suggest a 1 MiB gap here for alignment (2047 512-byte, or 255 4KiB, sectors). This gap used to be 62 sectors (31 KiB) as a reminder of the sector number limit of
Cylinder-Head-Sector (C/H/S) addressing used by
BIOS before 1996, therefore core.img is designed to be smaller than 32 KiB. • On GPT partitioned disks core.img is written to its own partition which must be flagged "BIOS_grub", must not be
formatted and can be as tiny as 1 MiB. •
stage 2: core.img loads /boot/grub/i386-pc/normal.mod from the partition configured by grub-install. If the partition index has changed, GRUB will be unable to find the normal.mod, and presents the user with the GRUB Rescue prompt. • Depending on how GRUB2 was installed, the /boot/grub/ is either in the
root partition of the Linux distribution, or in the separate
/boot partition. •
after normal.mod loaded: normal.mod parses /boot/grub/grub.cfg, optionally loads modules (eg. for graphical UI and file system support) and shows the menu. ==== Startup on systems using
UEFI firmware ==== • /efi//grubx64.efi (for
x64 UEFI systems) is installed as a file in the
EFI System Partition, and booted by the firmware directly, without a boot.img in MBR sector 0. This file is like stage1 and stage1.5. • /boot/grub/ can be installed on the EFI System Partition or the separate
/boot partition, among others. • For x64 UEFI systems, stage2 are the /boot/grub/x86_64-efi/normal.mod file and other /boot/grub/ files.
After startup GRUB presents a menu where the user can choose from operating systems (OS) found by grub-install. GRUB can be configured to automatically load a specified OS after a user-defined timeout. If the timeout is set to zero seconds, pressing and holding , or in some modern GRUB versions loaded using UEFI, pressing rapidly while the computer is booting makes it possible to access the boot menu. In the operating system selection menu GRUB accepts a couple of commands: • By pressing , it is possible to edit kernel parameters of the selected menu item
before the operating system is started. The reason for doing this in GRUB (i.e. not editing the parameters in an already booted system) can be an emergency case: the system has failed to boot. Using the kernel parameters line it is possible, among other things, to specify a module to be disabled (blacklisted) for the kernel. This could be required if the specific kernel module is broken and thus prevents boot-up. For example, to blacklist the kernel module nvidia-current, one could append modprobe.blacklist=nvidia-current at the end of the kernel parameters. • By pressing , the user enters the GRUB command line. The GRUB command line resembles GNU Bash, but only implements a subset of the line editing functions and GRUB-specific commands. Once boot options have been selected, GRUB loads the selected kernel into memory and passes control to the kernel. Alternatively, GRUB can pass control of the boot process to another boot loader, using
chain loading. This is the method used to load operating systems that do not support the
Multiboot Specification or are not supported directly by GRUB.
Identifying partitions (UUID workaround) A computer can have multiple hard disks connected to it. These could be identified via their SATA port. Each time the computer
POSTs, the hard disk connected to a specific motherboard port
could be assigned the same identifier, for example . But what if such consistency cannot be guaranteed? What if the constellation of connected hard disks changed from one start up to another? What if a hard disk will be connected to another computer? By entering into either the
GRUB rescue console (available after loading core.img ) or the
GRUB console (available after loading normal.mod) a list of all available hard disks and partitions can be obtained. For example, ) will show numbers that can be assigned to actual hard disks and partitions. As it cannot be guaranteed that the "hd0"style numbering of hard disks via device numbers is consistent, GNU GRUB can use a
Universally Unique Identifier (UUID) to identify partitions (actually file system instances). The file systems ext2, ext3, ext4 and xfs use a UUID to uniquely identify an instance. The UUID is created when a partition is formatted. The UUID is part of the file system and written to the
superblock. All operations other than formatting should leave the UUID unaltered. It is possible to change the UUID or duplicate it by using
dd to clone an entire partition. The file is used to configure GRUB. It contains commands to be executed during each start-up. Without an existing and valid , GRUB will present a prompt. An absolute minimal might contain only the following two commands (cf.
initial ramdisk): linux (hd0,1)/kernel/vmlinuz-3.20.1-4 ro # use the file named "vmlinuz-…" located in the directory /kernel on the first partition of the first hard disk as linux kernel image initrd (hd0,1)/boot/initrd.img-3.20.1-4 # use the file named "initrd.img–…" located in the directory /boot on the first partition of the first hard disk as initial ramdisk A fancier will describe a menu to be presented, use multiple colors, and may specify a background picture. ==History==