Table of Contents
Introduction
GRUB2 is the default bootloader on most modern Linux distributions. It is the program that starts immediately after the firmware has finished its work and before your Linux kernel runs. Understanding GRUB2 helps you troubleshoot boot problems, manage multiple operating systems, and customize how your system starts.
This chapter focuses specifically on GRUB2, its structure, configuration, and practical usage during boot. The general boot flow, firmware concepts, and kernel loading are covered elsewhere and will not be repeated here.
What GRUB2 Does
GRUB2, the GNU GRand Unified Bootloader, provides a small operating environment before Linux starts. In this environment, GRUB2 can read filesystems, present menus, load kernels and initramfs images, and pass parameters to the kernel. It can also chainload other bootloaders, which is often used when dual booting.
GRUB2 is modular and script driven. Instead of a single monolithic binary with hard coded behavior, it uses separate modules and configuration scripts. This design makes GRUB2 more flexible than earlier bootloaders and than the older GRUB legacy.
Components and Layout of GRUB2
GRUB2 is usually made of several parts stored in different locations. The exact layout depends on whether your system uses BIOS or UEFI firmware, but the conceptual pieces are the same.
On a typical Linux system, you will encounter:
The core image and boot sector code. At BIOS time, a small piece of code in the MBR or partition boot sector loads a larger GRUB core image. On UEFI systems, an executable such as grubx64.efi is stored in the EFI System Partition. This core knows how to read your filesystem and load further modules.
The modules. GRUB2 modules live under /boot/grub or /boot/grub2, with names similar to normal.mod, linux.mod, ext2.mod, lvm.mod and many others. Only a minimal subset is part of the core image. Additional capabilities are added via these modules as needed.
The configuration. Human readable configuration fragments live in /etc/default/grub and /etc/grub.d/, and from these, the generated master configuration file /boot/grub/grub.cfg (or /boot/grub2/grub.cfg) is produced.
The environment block. GRUB2 can store persistent variables in a small environment file, often /boot/grub/grubenv. This allows features such as booting a different menu entry only on the next reboot.
The main point for administrators is that /etc/default/grub and /etc/grub.d/ are for editing, while grub.cfg and the core image are generated artifacts.
GRUB2 Configuration Files
GRUB2 uses a layered configuration system. You almost never edit grub.cfg directly. Instead, you work on higher level configuration pieces and then regenerate the main file.
The most frequently modified file is /etc/default/grub. This file holds general settings in the form of shell style variable assignments. For example:
GRUB_TIMEOUT=5
GRUB_DEFAULT=0
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
This file does not contain complete menu entries. Instead, it defines options used by scripts under /etc/grub.d/ when they generate entries inside grub.cfg.
Under /etc/grub.d/ you will typically find numbered scripts and fragments. For example:
00_header prepares common settings and loads needed modules.
10_linux generates menu entries for the Linux kernels found in /boot.
30_os-prober creates entries for other detected operating systems.
40_custom is a place where you can add your own custom menu entries.
Scripts in /etc/grub.d/ are executed in numeric order when you regenerate the main configuration. Their output is concatenated into grub.cfg.
The generated configuration file, /boot/grub/grub.cfg or /boot/grub2/grub.cfg, contains the complete set of GRUB2 commands for booting your system. It is usually marked as auto generated, and manual edits to it will be overwritten the next time you run the configuration generation command.
Never rely on manual changes to grub.cfg. Always edit /etc/default/grub or files in /etc/grub.d/ and then regenerate grub.cfg with the appropriate grub-mkconfig or grub2-mkconfig command for your distribution.
The GRUB2 Menu and Entries
When you boot, GRUB2 usually displays a menu that lists one or more boot options. Each option is a menu entry that defines how to boot a kernel or another system. The visual appearance and the presence of a menu depend on your configuration, timeout, and default entry.
Internally, a menu entry in grub.cfg looks similar to the following:
menuentry 'Linux Example' --class gnu-linux --class gnu {
insmod ext2
set root='hd0,1'
linux /vmlinuz-6.0.0 root=/dev/sda1 ro quiet
initrd /initrd.img-6.0.0
}
The menuentry command opens a block where GRUB2 commands define what to do when this entry is chosen. Typical steps are:
Ensure required filesystem modules are loaded with insmod.
Set the root device for GRUB2 using set root.
Load the kernel image with linux or linuxefi and pass kernel parameters such as root device and mode flags.
Load the initial RAM filesystem with initrd or initrdefi.
Each menu entry has an index number starting at 0. These indices are used with certain configuration variables to define which entry is the default.
Key GRUB2 Configuration Variables
Most general behavior is controlled by variables in /etc/default/grub. Understanding a small set of these gives you practical control over the boot menu.
GRUB_DEFAULT defines the menu entry to boot automatically. It can be an index such as 0, or a string that matches a menu entry title. On many systems, you can also use saved, which tells GRUB2 to boot the entry stored in the environment block.
GRUB_TIMEOUT defines how many seconds GRUB2 waits before booting the default entry. A positive integer means the menu is shown for that many seconds. A value of 0 usually boots the default entry immediately without showing the menu.
GRUB_TIMEOUT_STYLE influences how the menu is displayed. Common values include menu for always showing the menu or hidden with a countdown that may be displayed only when a key is pressed.
GRUB_CMDLINE_LINUX and GRUB_CMDLINE_LINUX_DEFAULT control which parameters GRUB2 passes to the Linux kernel. They are split so that entries defined by your distribution can add one group of options and you can add your own defaults in another.
For example:
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
GRUB_CMDLINE_LINUX="loglevel=3"The exact combination rules depend on the distribution scripts, but these variables are the standard place for specifying persistent kernel parameters.
When you change any of these, they only take effect after you regenerate grub.cfg.
Generating and Installing GRUB2
On most systems you do not install or reconstruct GRUB2 manually very often. However, it is important to understand the commands used when you need to regenerate configuration or repair a bootloader.
To generate or update grub.cfg, distributions provide one of the following commands, typically run as root:
On Debian and Ubuntu based systems:
grub-mkconfig -o /boot/grub/grub.cfgOn Fedora, CentOS Stream, and RHEL family:
grub2-mkconfig -o /boot/grub2/grub.cfg
The command scans available kernels and operating systems, reads /etc/default/grub and /etc/grub.d/, then writes a complete grub.cfg.
The installation of the core bootloader code is done with the grub-install or grub2-install command, typically specifying the target disk. This is more invasive than regenerating grub.cfg and is mainly used when first setting up GRUB2 or repairing a damaged boot sector.
When repairing GRUB2, a common sequence is to chroot into your installed system from a live environment, mount the necessary filesystems, run grub-install, then run grub-mkconfig. The exact chroot procedure and partition mounting belong to broader boot troubleshooting topics.
GRUB2 Command Line and Interactive Use
GRUB2 includes its own command line interface that you can access at boot time. If GRUB2 cannot find a valid configuration, or if you press a specific key combination depending on your distribution, you may be dropped into the GRUB prompt.
There are two main interactive modes.
The command line prompt, which appears as grub> and accepts individual GRUB commands.
The normal mode menu that you normally see at boot, from which you can press keys such as c to get to the command line or e to edit the selected menu entry temporarily.
At the grub> prompt, you can list devices and partitions using commands such as ls, specify the root device, and try to manually load a kernel and initrd. For example:
grub> ls
grub> set root=(hd0,1)
grub> linux /vmlinuz root=/dev/sda1 ro
grub> initrd /initrd.img
grub> boot
This is particularly useful when grub.cfg is missing or incorrect. Changes made in this interactive environment are temporary and affect only the current boot.
Temporarily Editing GRUB2 Entries
A very common and practical task is to modify kernel parameters for a single boot, usually to help diagnose a problem. You can do this without rewriting any configuration files.
At the GRUB menu, select the entry you want to modify but do not press Enter yet. Press e to edit the entry. This opens a simple editor showing the commands GRUB will execute for this entry.
Within this editor, find the line that begins with linux or linuxefi. Kernel parameters appear on this line after the path to the kernel image. You can move the cursor with the arrow keys and modify or append parameters. For example, you might remove quiet splash and append systemd.unit=multi-user.target for a more verbose, text based boot.
Once you have made your changes, press the key indicated at the bottom of the screen, commonly Ctrl + x or F10, to boot with the edited configuration. These edits are not saved permanently. They only apply to the current boot. If you want to make the change permanent, you must modify /etc/default/grub or a relevant script and regenerate grub.cfg.
GRUB2, Multiple Kernels, and Multiple Systems
GRUB2 handles multiple Linux kernels and multiple operating systems through its menu entry mechanism. When your distribution installs a new kernel, it typically also updates GRUB2 configuration so that both the new and older kernels are listed in the boot menu.
If you have several kernels, the one with the highest version is usually placed at the top. By setting GRUB_DEFAULT to 0, you boot the first one, but you can also specify a named entry if you want to default to an older kernel.
For multi boot systems, the os-prober tool, when enabled, scans other disks and partitions for operating systems. Its results are used by scripts such as /etc/grub.d/30_os-prober to add menu entries that chainload other bootloaders, for example to start Windows. Some distributions disable automatic use of os-prober by default for security reasons, and you may need to explicitly enable it in configuration.
If os-prober is not used, you can define your own additional entries in /etc/grub.d/40_custom using menuentry blocks. These custom entries can boot other Linux installations, chainload other boot sectors, or pass different parameters to the same kernel.
GRUB2 Environment and Saved Entries
GRUB2 supports a small persistent environment separate from your normal filesystem configuration files. This environment is stored in a special file, often /boot/grub/grubenv, that GRUB2 can read and update at boot time.
Two important commands in this context are grub-set-default and grub-reboot. They interact with configurations that use GRUB_DEFAULT=saved.
When GRUB_DEFAULT=saved, GRUB2 reads which entry to boot from its environment block. You can then run:
grub-set-default "Linux Example"
to permanently set the default entry to the one whose title is Linux Example, or you can choose an index. Future boots will use that entry until it is changed again.
The grub-reboot command sets the entry only for the next boot. This is useful when you want to schedule a one time boot into a different kernel or an alternative system, for example before a maintenance window.
Internally, GRUB2 uses its save_env and load_env commands in grub.cfg to read and write environment variables in grubenv. You typically do not modify these commands directly, but they make features such as saved default entries possible.
Security Considerations with GRUB2
Although GRUB2 itself is not a full operating system, it can be used to gain elevated access if not configured carefully. From the GRUB command line or editor, an attacker with physical access can sometimes pass parameters to the kernel that drop them into a root shell or disable security features.
GRUB2 provides two main mechanisms to mitigate this.
You can set a password for GRUB2 and restrict editing or certain menu entries. This uses GRUB2 specific user accounts defined in configuration, allowing some entries to be locked so that they cannot be edited or booted without a password.
In secure boot environments, the UEFI firmware verifies the signature of the GRUB2 binary, and GRUB2 in turn can validate the signatures of kernel images. This forms a trust chain from firmware to kernel. The specific signing and key management processes are handled by your distribution and by system level security policies.
Security configuration inside GRUB2 is a specialized topic, but it is important to be aware that controlling who can interact with GRUB2 is part of overall system security, especially on physical machines.
Summary
GRUB2 sits between the firmware and the Linux kernel and provides a flexible, modular bootloader environment. It reads a generated configuration file, presents a menu of boot entries, loads kernels and initramfs images, and passes parameters to the kernel. You make persistent changes by editing /etc/default/grub or fragments in /etc/grub.d/, then regenerating grub.cfg. Interactive editing at boot allows temporary modifications, and the environment block enables saved defaults and one time boots. A solid understanding of these GRUB2 concepts gives you practical control over the boot phase and prepares you for more advanced boot troubleshooting.