102.2 Install a boot manager¶
Boot overview¶
Most systems use BIOS or UEFI. When on BIOS, the system performs a self-test called POST (Power-On Self-Test). Then it hands over the boot process to the first sector of the Master Boot Record (MBR), which is track (Cylinder) 0, side (Head) 0 and Sector 1 of the first disk.
MBR is only 512 bytes and contains both a partition table and bootstrap code (the bootloader). Because of the size limit, a smart bootloader is needed to handle larger boot managers and even multiple systems. Some of these bootloaders are LILO, GRUB and GRUB2.
On an MBR-partitioned disk, the boot code for GRUB is installed to the MBR. This loads and passes control to a "core" image installed in the 32 KB space between the MBR and the first partition. From this point, GRUB can load the rest of its resources (menu definitions, configuration files and extra modules) from disk.
If the system is using UEFI, the hardware follows the UEFI stages. They start with a security phase and continue until the end phase where the UEFI looks for an EFI System Partition, which is a FAT-based partition (usually the first one, but that is implementation-defined) containing PE executables, and runs them. On UEFI systems, GRUB is loaded from files like grubia32.efi (32-bit) or grubx64.efi (64-bit) from the ESP.
In both cases, the binary starts the boot loader. It might be a complete bootloader on /boot/efi/ of your computer, a small loader for the main GRUB on the MBR, a Windows loader, or even a chainloader.
Chain Loading is when a boot loader loads another boot loader. This is done when a Linux bootloader needs to start a Windows system.
BIOS path:
Power on --> POST --> MBR (512 bytes) --> GRUB core image (32 KB gap) --> /boot/grub/ --> kernel
[sector 0] [between MBR & 1st partition]
UEFI path:
Power on --> Security phase --> ESP (FAT partition) --> grubx64.efi --> /boot/grub/ --> kernel
[/boot/efi/]
Chainloading (dual boot):
GRUB --> chainloader +1 --> Windows bootloader --> Windows
GRUB¶
GRUB (GRand Unified Bootloader) started to replace the older LILO. The first version (1) is called GRUB Legacy and started in 1999. The 2nd version started in 2005 and is a complete rewrite of version 1. GRUB Legacy is no longer under active development (the last release was 0.97, in 2005), and today most major Linux distributions install GRUB 2 as the default boot loader.
It is a menu-based system where you can choose which kernel or chainloader to boot. It is also possible to edit the menus on the fly or give direct commands from a command line.
GRUB Legacy vs GRUB2 at a glance:
GRUB Legacy (v1, 0.9x) GRUB2 (v2)
-------------------------- --------------------------
Config: /boot/grub/menu.lst Config: /boot/grub/grub.cfg
(or grub.conf on Red Hat) (auto-generated, don't edit)
Edit: directly by hand Edit: /etc/default/grub
+ /etc/grub.d/ scripts
then run grub-mkconfig
Numbering: (hd0,0) = 1st disk, 1st part Numbering: (hd0,1) = 1st disk, 1st part
Install: grub-install /dev/sda Install: grub-install /dev/sda
Shell: press 'c', boot with 'boot' Shell: press 'c', boot with 'boot'
Edit: press 'e', boot with 'b' Edit: press 'e', boot with Ctrl+X
GRUB Legacy¶
GRUB v1 (actually version 0.9x) is installed in /boot/grub. Its main configuration file is /boot/grub/menu.lst, but some distros (including Red Hat based ones) symlink this to /boot/grub/grub.conf.
A sample menu.lst / grub.conf file has two sections. The first section contains global configs, the second defines kernel/initramfs or chainloader boot entries.
Global configuration options:
| Config | Description |
|---|---|
# |
Comment |
color |
Foreground and background colors for normal and active items |
default |
Which boot menu item is the default, numbered from zero. E.g. default=1 boots the second entry |
fallback |
If the default entry fails to boot, try this one instead |
hiddenmenu |
Don't show the menu at all, just boot the default silently. Press a key during timeout to reveal it |
splashimage |
Background image behind the menu |
timeout |
Seconds to wait before auto-booting the default. 0 boots immediately, no chance to choose |
password |
Require this password before anyone can edit menu entries. Prevents unauthorized kernel parameter changes (like adding init=/bin/bash to bypass login) |
savedefault |
Remember whichever entry was booted last, use it as default next time |
Boot entry options:
| Config | Description |
|---|---|
title |
Defines the section name (what you see on the menu) |
root |
Disk and partition where /boot is, in the form (hd0,0). This tells GRUB where to find files, NOT where Linux will mount / |
kernel |
Kernel image file name in /boot |
initrd |
Initramfs file in /boot |
rootnoverify |
Same as root, but skips checking the filesystem. Used for non-Linux partitions (like Windows) where GRUB can't read the filesystem anyway |
chainloader |
Load the first sector of another partition's bootloader. +1 means "first sector." Used for dual-boot: GRUB hands off to Windows' own bootloader instead of trying to boot Windows directly |
Sample GRUB Legacy config:
# grub.conf generated by anaconda
default=1
timeout=10
splashimage=(hd0,5)/boot/grub/splash.xpm.gz
#hiddenmenu
password --md5 $1$RW1VW/$4XGAklxB7/GJk0uO47Srx1
title Upgrade to Fedora 11 (Leonidas)
kernel /boot/upgrade/vmlinuz preupgrade \
repo=hd::/var/cache/yum/preupgrade stage2=\
hd:UUID=8b4c62e7-2022-4288-8995-5eda92cd149b:/boot/upgrade/install.img \
ks=hd:UUID=8b4c62e7-2022-4288-8995-5eda92cd149b:/boot/upgrade/ks.cfg
initrd /boot/upgrade/initrd.img
title Fedora (2.6.26.8-57.fc8)
root (hd0,5)
kernel /boot/vmlinuz-2.6.26.8-57.fc8 ro root=LABEL=FEDORA8 rhgb quiet
initrd /boot/initrd-2.6.26.8-57.fc8.img
title GRUB Menu
rootnoverify (hd0,1)
chainloader +1
title Windows
rootnoverify (hd0,0)
chainloader +1
Important: in GRUB Legacy, both disks AND partitions are numbered from zero. So (hd0,0) means the first partition on the first disk.
GRUB Legacy commands¶
After creating the configuration, install GRUB on a disk MBR:
GRUB can be installed on a CD, floppy, MBR (/dev/sda, /dev/sdb, etc.) or a partition (/dev/sdb2, /dev/sda6, etc.). If you install it on anything other than the MBR, use a chainloader to point your boot sequence toward it.
To install from the GRUB shell itself (if the system can't boot normally):
Use find /boot/grub/stage1 to locate which partition contains the boot files.
Interacting with GRUB Legacy¶
If you press c on the GRUB menu, you enter the GRUB Command Line (GRUB shell). There you can type commands like root, kernel, initrd and boot the system with boot, or press Esc to return to the menu.
If you need to edit an entry on the fly, press e on that item to get an interactive editing environment. Press Enter when done and b to boot.
GRUB2¶
This is the most common boot loader today. On BIOS systems it is installed in /boot/grub/ or /boot/grub2/. Under UEFI it goes in /boot/efi/EFI/distro-name/ (e.g. /boot/efi/EFI/fedora/). GRUB2's configuration file is called grub.cfg.
The default configuration file is /boot/grub/grub.cfg. This file is automatically generated and manual editing is not recommended. To make changes, edit /etc/default/grub and then run update-grub (or grub-mkconfig) to regenerate a compliant grub.cfg.
Simplified grub.cfg:
set default="0"
menuentry "Fedora" {
set root=(hd0,1)
linux /boot/vmlinuz-5.10.0-9-arm64 ro quiet
initrd /boot/initrd.img-5.10.0-9-arm64
}
menuentry "Windows" {
chainloader (hd1,msdos2)+1
}
Important: in GRUB2, disks are still numbered from zero, but partitions are numbered from one. So the first partition on the first disk is (hd0,1) or (hd0,msdos1) for MBR partitions or (hd0,gpt1) for GPT drives. This is different from GRUB Legacy where it would be (hd0,0).
GRUB2 menu entry options:
| Option | Description |
|---|---|
menuentry |
Defines a new menu entry |
set root |
Defines the root where /boot is located |
linux, linux16 |
Defines the location of the Linux kernel on BIOS systems |
linuxefi |
Defines the Linux kernel on UEFI systems |
initrd |
Defines the initramfs image for BIOS systems |
initrdefi |
Defines the initramfs image for UEFI systems |
Key settings in /etc/default/grub:
| Setting | Description |
|---|---|
GRUB_DEFAULT= |
Default menu entry. 0 = first entry, saved = whatever was booted last (needs GRUB_SAVEDEFAULT=true). Can also be a name like "Fedora" |
GRUB_SAVEDEFAULT= |
If true with GRUB_DEFAULT=saved, remembers last selection across reboots |
GRUB_TIMEOUT= |
Seconds before auto-booting default. 0 boots instantly (press Shift to catch the menu), -1 waits forever |
GRUB_CMDLINE_LINUX= |
Kernel parameters added to ALL entries (including recovery). E.g. "net.ifnames=0" to use old-style network names on every boot |
GRUB_CMDLINE_LINUX_DEFAULT= |
Extra parameters for the default entry only, NOT recovery. E.g. "quiet splash" hides boot messages on normal boot, but recovery mode still shows them |
GRUB_ENABLE_CRYPTODISK= |
If y, allows booting from an encrypted disk. GRUB will ask for the encryption passphrase before loading the kernel |
Menu entries can also be added manually by editing scripts inside /etc/grub.d/. These files are processed in numerical order (05_debian_theme before 10_linux, etc.). Custom entries go in 40_custom.
Instead of specifying a device and partition directly with set root, you can also have GRUB2 search for a filesystem by UUID or label:
search --set=root --fs-uuid ae71b214-0aec-48e8-80b2-090b6986b625
search --set=root --label MY_PARTITION
Add --no-floppy so GRUB does not waste time searching floppy drives.
GRUB2 commands¶
Installation is done with:
If installing from a rescue environment to a mounted boot partition:
After changing config files, regenerate grub.cfg:
There is also update-grub, which is a frontend that runs grub-mkconfig -o /boot/grub/grub.cfg.
On some modern distros, both
grubandgrub2prefixed commands exist for compatibility reasons, and one links to the other.
GRUB2 configuration workflow:
/etc/default/grub (settings: timeout, default, kernel params)
|
+--- /etc/grub.d/ (scripts processed in order)
| 00_header
| 05_debian_theme
| 10_linux (auto-detects installed kernels)
| 30_os-prober (auto-detects other OSes)
| 40_custom (your manual entries go here)
|
v
grub-mkconfig / update-grub (reads all the above)
|
v
/boot/grub/grub.cfg (generated output - NEVER edit directly)
Interacting with GRUB2¶
Press c on the GRUB menu (or Ctrl+C from the editing window) to enter the GRUB shell (grub>). Type help to see available commands, or Esc to return to the menu.
To edit an entry, select it and press e. After editing, type Ctrl+X or F10 to boot, or Esc to return.
If you see just a countdown but not a menu, press
Shiftto bring it up. The menu will not appear at all ifGRUB_TIMEOUTis set to0in/etc/default/grub.
Booting from the GRUB2 shell (when a menu entry is broken):
grub> ls # list disks and partitions
grub> ls (hd0,msdos1)/ # browse a partition's contents
grub> set root=(hd0,msdos1) # set the boot partition
grub> linux /vmlinuz root=/dev/sda1 # load the kernel
grub> initrd /initrd.img # load the initramfs
grub> boot # boot the system
Booting from the rescue shell (grub rescue>): same process, but you must first load modules manually:
Then proceed with set root, linux, initrd, and boot as above.
GRUB2 interactive recovery:
GRUB menu appears
|
+-- press 'e' --> edit entry --> Ctrl+X to boot (quick fix)
|
+-- press 'c' --> grub> shell
| ls --> set root --> linux /vmlinuz --> initrd --> boot
|
+-- boot fails badly --> grub rescue> shell
set prefix --> insmod normal --> insmod linux
--> then same as grub> shell above
GRUB Legacy (for comparison):
press 'e' --> edit --> Enter --> 'b' to boot
press 'c' --> grub> shell --> root, kernel, initrd, boot
Partition numbering - the key exam trap:
GRUB Legacy: (hd0,0) = first disk, first partition (both from zero)
GRUB2: (hd0,1) = first disk, first partition (disk from zero, partition from one)
(hd0,msdos1) = same, MBR explicit
(hd0,gpt1) = same, GPT explicit
Kernel boot parameters¶
Parameters can be passed to the kernel on the linux line:
| Option | Description |
|---|---|
console= |
Redirect boot output to a specific device. E.g. console=ttyS0,115200 sends output to the serial port at 115200 baud - used on headless servers where you connect via serial cable instead of a monitor |
debug |
Show detailed kernel messages during boot - useful when a driver fails silently and you need to see where it stopped |
init= |
Run something else instead of the normal init. E.g. init=/bin/bash drops you directly into a root shell with no login prompt - used to recover a system when even init is broken or you forgot the root password |
initrd= |
Specify a different initramfs file than the default |
ro |
Mount root read-only at first. This is the normal default - the system runs fsck (filesystem check) while it's read-only, then remounts it read-write once the check passes |
rw |
Mount root read-write immediately, skipping the read-only check phase |
root= |
Tell the kernel which partition is /. E.g. root=/dev/sda2 or root=LABEL=FEDORA8 or root=UUID=... |
selinux=0 |
Disable SELinux entirely on boot. Used when SELinux is blocking something and you need to get in to fix the policy |
single, S, 1, Single |
Boot into single-user mode (SysV) - root shell, no network, no other users. Used for emergency maintenance like fixing /etc/fstab or resetting a password |
systemd.unit= |
Boot into a specific systemd target instead of the default. E.g. systemd.unit=rescue.target is the systemd equivalent of single-user mode |
Summary¶
I have a Linux system that needs a boot manager to load the kernel after the firmware (BIOS or UEFI) finishes its initial hardware checks. On BIOS systems, the bootloader code lives in the 512-byte MBR of the first disk and loads a larger "core" image from the gap between the MBR and the first partition. On UEFI systems, the firmware loads a .efi file directly from the EFI System Partition. If one bootloader needs to start a different OS (like Windows), it uses chainloading to hand off to that OS's own bootloader.
The exam covers two versions of GRUB. GRUB Legacy stores its configuration directly in /boot/grub/menu.lst (or grub.conf on Red Hat), which you edit by hand. It numbers both disks and partitions from zero, so the first partition on the first disk is (hd0,0). GRUB2, the current standard, stores its generated config in /boot/grub/grub.cfg, but you never edit that file directly. Instead, you change settings in /etc/default/grub and add custom entries in /etc/grub.d/40_custom, then regenerate with grub-mkconfig or update-grub. GRUB2 numbers disks from zero but partitions from one, so the same first partition becomes (hd0,1).
Both versions provide an interactive shell (press c at the menu) where I can manually specify a root device, load a kernel and initramfs, and boot the system. This is the key recovery tool when a menu entry is broken or a kernel upgrade fails. In GRUB2, pressing e to edit an entry and Ctrl+X to boot is the most common live-troubleshooting workflow. The GRUB2 rescue shell (grub rescue>) requires manually loading the normal and linux modules with insmod before any of the usual commands work.