Linux

Configuring GRUB 2: A Complete Guide to Linux Bootloader Configuration

This guide provides a detailed explanation of how to configure the GRUB 2 bootloader in Linux. You'll learn to edit configuration files, modify the boot menu order and appearance, add kernel parameters, and secure the menu with a password.

15-30 min
Medium
Применимо к:GRUB 2 (all major distributions: Ubuntu 20.04+, Fedora 35+, Debian 11+, Arch Linux)systemd-boot (mentioned as an alternative)LVM, Btrfs, ZFS (module support)

Introduction / Why This Is Needed

GRUB (Grand Unified Bootloader) is the standard bootloader for most Linux distributions. It is responsible for selecting the operating system or kernel to boot, passing parameters to the kernel, and displaying the menu. Configuring GRUB allows you to:

  • Change the default boot order (e.g., make Windows the primary OS).
  • Set the timer for automatic boot or completely hide the menu.
  • Add kernel parameters (nomodeset, quiet splash, acpi=off) to resolve hardware issues.
  • Protect the menu from unauthorized editing with a password.
  • Manually add an entry for an OS that GRUB did not detect automatically.

This guide covers the main scenarios for configuring GRUB 2 on modern systems.

Requirements / Preparation

  1. System Access: You must have superuser (sudo) privileges.
  2. Backup: Before editing the configuration, mandatorily create a backup of key files:
    sudo cp /etc/default/grub /etc/default/grub.bak
    sudo cp -r /etc/grub.d/ /etc/grub.d.bak/
    
  3. Disk Partitioning Knowledge: Find out which partition your root (/) and /boot filesystems are on (if /boot is separate). The lsblk or sudo fdisk -l commands can help.
  4. Understanding the Structure: GRUB 2 uses two types of files:
    • Default Configuration: /etc/default/grub (main variables).
    • Generation Scripts: /etc/grub.d/ (executable scripts that generate the menu).
    • Final Config: /boot/grub/grub.cfg (DO NOT edit manually! It gets overwritten).

Step 1: Basic Settings via /etc/default/grub

Open the main configuration file in a text editor (e.g., sudo nano /etc/default/grub). Here are the key parameters:

# Delay before automatically booting the selected item (in seconds)
GRUB_TIMEOUT=5

# Hide the menu if there is only one OS? (hidden - hide, menu - show)
GRUB_TIMEOUT_STYLE=menu

# Name of the default OS (usually corresponds to the name in the menu)
GRUB_DEFAULT=0  # 0 - first entry, "saved" - last selected

# Kernel parameters added to all Linux entries
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
GRUB_CMDLINE_LINUX=""

# Enable/disable recovery after failures (e.g., after a kernel update)
GRUB_DISABLE_OS_PROBER=false

# Color scheme (optional)
GRUB_COLOR_NORMAL="light-gray/black"
GRUB_COLOR_HIGHLIGHTED="white/blue"

What to change:

  • To speed up boot, set GRUB_TIMEOUT=2 or 0.
  • To remove the menu entirely (auto-boot), set GRUB_TIMEOUT_STYLE=hidden and GRUB_TIMEOUT=0. Hold Shift during boot to invoke the menu.
  • To change the default OS, find its exact name in the future grub.cfg or set GRUB_DEFAULT="Advanced options for Ubuntu>Ubuntu, with Linux 6.5.0-27-generic" (use quotes and nesting via >).
  • For debugging, remove quiet splash from GRUB_CMDLINE_LINUX_DEFAULT to see kernel messages.

Step 2: Adding a Custom Entry (Manual Method)

If GRUB did not find the desired OS (e.g., another Linux system on a separate disk or an old Windows), add an entry manually.

  1. Create or edit the file /etc/grub.d/40_custom. It already exists and contains examples.
  2. Add a block for the new OS at the end of the file. Example for Windows on another disk:
    ### BEGIN /etc/grub.d/40_custom
    menuentry "Windows 10 (on /dev/sdb1)" {
        insmod ntfs
        set root='hd1,msdos1'  # or 'hd0,gpt1' for GPT. Confirm via `ls` in grub rescue
        chainloader +1
    }
    
    How to determine set root? Boot from a Live-USB, open the grub console (press c in the menu), and run ls. Disks will be hd0, hd1, etc., partitions (hd0,msdos1) or (hd0,gpt1).
  3. For another Linux system, it's simpler to use chainloader or configfile if it has its own GRUB.

Step 3: Applying Changes and Updating the Configuration

After any change in /etc/default/grub or /etc/grub.d/, you must run:

sudo update-grub

This command:

  1. Runs scripts from /etc/grub.d/ in alphabetical order.
  2. Detects installed kernels and OSes (if GRUB_DISABLE_OS_PROBER=true, it skips detection).
  3. Generates a new /boot/grub/grub.cfg file.
  4. Prints a list of found menu entries.

Common Error: Forgetting to run update-grub. Changes will only take effect after regenerating the config.

Step 4: Password-Protecting the GRUB Menu (Prevent Editing)

This prevents accidental or malicious changes to boot parameters.

  1. Generate a password hash:
    sudo grub-mkpasswd-pbkdf2
    
    Enter and confirm the password. You will get a string like grub.pbkdf2.sha512.....
  2. Add the hash to the configuration. Open /etc/grub.d/40_custom and at the very end (before ### END) add:
    set superusers="root"
    password_pbkdf2 root grub.pbkdf2.sha512.10000....  # paste your long string here
    
    This creates a root user with a password.
  3. Restrict editing permissions. In the same 40_custom file or a separate one (e.g., 01_users), wrap all menuentry blocks in an if statement:
    if [ "${GRUB_MENU_ENTRY}" = "root" ]; then
        # All menuentries will be accessible only after entering the password
        set superusers="root"
        password_pbkdf2 root grub.pbkdf2.sha512....
    fi
    
    A simpler (but less flexible) method: add GRUB_DISABLE_RECOVERY="true" to /etc/default/grub to hide the "Recovery" option, and use grub-setpassword (not available in all distros).
  4. Update the config: sudo update-grub.

During boot, to select an entry or access the GRUB command line, press e or c—the system will prompt for a username (root) and password.

Step 5: Alternative Tools (Use with Caution)

For those who prefer not to edit files manually, graphical utilities exist:

  • Grub Customizer (sudo apt install grub-customizer on Debian/Ubuntu).
    • Pros: Convenient GUI for changing order, timer, and hiding entries.
    • Cons: Can "break" the config during GRUB updates, stores changes in its own files, complicating debugging. Not recommended for servers and critical systems.

Conclusion: For reliability and understanding the process, manual editing via update-grub is preferable.

Step 6: Working with Kernel Boot and Parameters

Changing Kernel Parameters for a Single Session

  1. In the GRUB menu, select the desired entry and press e (edit).
  2. Find the line starting with linux or linuxefi. These are the kernel parameters.
  3. Add or modify parameters at the end of that line (e.g., nomodeset, noapic, acpi=off).
  4. Press Ctrl+X or F10 to boot with these parameters (changes are not saved).
  5. To make parameters permanent, find the GRUB_CMDLINE_LINUX_DEFAULT variable in /etc/default/grub, add the needed flags there, then run sudo update-grub.

Removing Old Kernels

Old kernels accumulate in /boot/ and can take up space. GRUB automatically shows all it finds. To clean up:

# Ubuntu/Debian
sudo apt autoremove --purge
# Fedora
sudo dnf remove $(package-cleanup --oldkernels --count=2)

After cleanup, sudo update-grub will update the menu.

Verifying the Result

  1. Reboot the computer.
  2. Ensure that:
    • The GRUB menu appears (or doesn't, if configured as hidden).
    • The timer works as set.
    • The default OS boots automatically.
    • All necessary OSes are present in the list.
    • Kernel parameters (if added) are active (check with cat /proc/cmdline after boot).
  3. If the system fails to boot but you see grub> or grub rescue>—refer to the "Possible Issues" section.

Possible Issues

Issue: After changes, the system does not boot, grub rescue> is visible.

Cause: GRUB cannot find its modules or config (e.g., after renaming the /boot partition). Solution:

  1. Determine where your /boot partition is (via ls in grub rescue).
  2. Manually set the root: set root=(hd0,gpt1) (substitute your own).
  3. Load the normal config: insmod normal; normal.
  4. If you booted, immediately fix /etc/default/grub (possibly GRUB_DISABLE_OS_PROBER or the path to /boot), then run update-grub.

Issue: update-grub does not find Windows.

Cause: Windows boots in UEFI mode while Linux uses Legacy (CSM), or vice versa. Or os-prober is disabled. Solution:

  • Ensure both OSes use the same BIOS/UEFI mode.
  • Install os-prober (sudo apt install os-prober), uncomment GRUB_DISABLE_OS_PROBER=false in /etc/default/grub, and run sudo update-grub again.

Issue: Changes in /etc/default/grub do not apply.

Cause: You edited the wrong file (e.g., from a chroot environment on another disk) or forgot update-grub. Solution: Check that the correct file was modified (cat /etc/default/grub from your loaded system). Always run sudo update-grub after making changes.

Issue: After password-protecting GRUB, it asks for a password even to boot.

Solution: This is expected behavior if you set superusers globally. To have the password requested only when attempting to edit, you need more granular if-condition settings in the /etc/grub.d/ scripts. Often it's simpler to remove the password by editing 40_custom and regenerating the config.

F.A.Q.

How to recover GRUB after installing Windows?
Can I remove the GRUB menu and boot into a single system automatically?
How to add a GRUB menu entry for another disk or OS that it didn't find?
Is it safe to use Grub Customizer?

Hints

Understanding GRUB Structure
Basic Settings in /etc/default/grub
Using Scripts in /etc/grub.d/
Applying Changes
Verification and Testing
Advanced Settings and Password Protection
FixPedia

Free encyclopedia for fixing errors. Step-by-step guides for Windows, Linux, macOS and more.

© 2026 FixPedia. All materials are available for free.

Made with for the community