1. Introduction

The Grand Unified Bootloader (GRUB) is a common tool for performing the boot process in most Linux distributions. Despite the intended similarity in the way it’s used, the method of managing it may vary from one Linux distribution to another.

In this tutorial, we’ll learn about the GRUB configuration in Fedora Linux and other RHEL-based distributions.

2. Fedora Distro GRUB Modifications

Let’s take as an example the Fedora distribution, which is a member of the Red Hat Linux family. Since releases 29 and 30, it has been featuring specific GRUB improvements.

First, we should look at how the GRUB menu entries are stored. The usual way is to keep definitions of entries in the /boot/grub2/grub.cfg file in the menuentry blocks. However, Fedora 30 adopted the BootLoaderSpec (BLS) specification, which demands keeping each entry definition in a separate file. We can find these files in the /boot/loader/entries folder. After a fresh installation, it contains our system’s GRUB configuration as well as a rescue configuration:

$ sudo ls /boot/loader/entries
aa2fe2e4c83744f98664b52388fba883-0-rescue.conf
aa2fe2e4c83744f98664b52388fba883-6.2.9-300.fc38.x86_64.conf

In addition, Fedora 29 introduced the menu auto-hide function, which hides the GRUB menu when only one kernel is available. The older kernel versions — preserved for the purpose of rescue, for example — don’t count here. Of course, if we’ve set the GRUB menu timeout properly, we can still get to the menu by pressing the F8 key.

We can disable this behavior using the grub2-editenv command:

$ sudo grub2-editenv - unset menu_auto_hide

Consequently, the GRUB menu shows right away.

3. The GRUB Configuration File

The GRUB parameters are stored in the /etc/default/grub file. This is the proper place to make any user modification. Let’s check its content:

$ cat /etc/default/grub
GRUB_TIMEOUT="5"
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT="saved"
GRUB_DISABLE_SUBMENU="true"
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX=""
GRUB_DISABLE_RECOVERY="true"
GRUB_ENABLE_BLSCFG="true"

Note that the GRUB_ENABLE_BLSCFG parameter is set to true, which informs us that the configuration sticks to the BLS specification.

4. The grub2-mkconfig Command

To change the GRUB configuration, we first edit the /etc/default/grub file. Then, we use the grub2-mkconfig command to generate a new /boot/grub2/grub.cfg file using the contents of/etc/default/grub.

By default, the GRUB menu is visible for four seconds. If this period is too short for us, we can extend it in the GRUB configuration. As an example, let’s set the timeout to 10 seconds. Thus, we need to change the value of the GRUB_TIMEOUT entry:

$ sudo nano /etc/default/grub
# ...
GRUB_TIMEOUT="10"

Subsequently, let’s update the grub.cfg file:

$ sudo grub2-mkconfig -o /boot/grub2/grub.cfg

The -o option provides the name of the output file.

5. Setting the Default Kernel

Let’s take a look at the GRUB_DEFAULT=”saved” entry. This value says that the default kernel is the latest one to be installed. Additionally, we can change the kernel referred to as “saved” using the grub2-set-default command. We need to enter the zero-based index, which is 1 for the second entry:

$ sudo grub2-set-default 1

We can override this default by providing the desired entry name with the GRUB_DEFAULT key in /etc/default/grub:

GRUB_DEFAULT="Fedora Linux (6.2.9-300.fc38.x86_64) 38 (Workstation Edition)"

To find the entry name within the BLS framework, let’s grep the configuration files in the /boot/loader/entries folder for the title key:

$ sudo sh -c 'grep title /boot/loader/entries/* | cut -d " " -f2-'
Fedora Linux (0-rescue-aa2fe2e4c83744f98664b52388fba883) 38 (Workstation Edition)
Fedora Linux (6.2.9-300.fc38.x86_64) 38 (Workstation Edition)

For the changes to take effect, let’s generate the new GRUB configuration file:

$ sudo grub2-mkconfig -o /boot/grub2/grub.cfg

6. The grubby Command Line Tool

The grubby command comes with the Fedora distribution, so we don’t need to install it. With grubby, we can modify, add, and remove GRUB menu entries. The command accepts a bunch of options to perform various tasks. grubby makes persistent changes to the GRUB configuration.

Let’s list all GRUB entries together with their parameters by employing the –info=ALL option:

$ sudo grubby --info=ALL
index=0
kernel="/boot/vmlinuz-6.2.9-300.fc38.x86_64"
args="ro rootflags=subvol=root rhgb quiet"
root="UUID=f9a12274-d915-4f46-860e-08b3b8f0ea35"
initrd="/boot/initramfs-6.2.9-300.fc38.x86_64.img"
title="Fedora Linux (6.2.9-300.fc38.x86_64) 38 (Workstation Edition)"
id="aa2fe2e4c83744f98664b52388fba883-6.2.9-300.fc38.x86_64"
index=1
kernel="/boot/vmlinuz-0-rescue-aa2fe2e4c83744f98664b52388fba883"
args="ro rootflags=subvol=root rhgb quiet"
root="UUID=f9a12274-d915-4f46-860e-08b3b8f0ea35"
initrd="/boot/initramfs-0-rescue-aa2fe2e4c83744f98664b52388fba883.img"
title="Fedora Linux (0-rescue-aa2fe2e4c83744f98664b52388fba883) 38 (Workstation Edition)"
id="aa2fe2e4c83744f98664b52388fba883-0-rescue"

First, note that we’re provided with the kernel’s index. Next, we see our system’s kernel entry. vmlinuz-6.2.9-300.fc38.x86_64, and the rescue entry with the vmlinuz-0-rescue-aa2fe2e4c83744f98664b52388fba883 kernel. Both kernels are in the same /boot directory.

Next, the id key provides the name of the entry’s configuration file in the /boot/loader/entries folder.

Now let’s check which entry is the default one with the –default-index option:

$ sudo grubby --default-index
0

Next, let’s find the corresponding kernel with the –default-kernel switch:

$ sudo grubby --default-kernel
/boot/vmlinuz-6.2.9-300.fc38.x86_64

Finally, we can obtain the default kernel’s title with –default-title:

$ sudo grubby --default-title
Fedora Linux (6.2.9-300.fc38.x86_64) 38 (Workstation Edition)

7. More Actions With grubby

The grubby actions are fired by passing the appropriate options to the command. If we need to specify the entry we want to print, modify, or delete, we can use the kernel name or entry index. In addition, the keywords DEFAULT and ALL refer to the default kernel and all kernels, respectively.

7.1. Adding and Removing Kernel Arguments

With the –args and –remove-arg options, we can respectively add and remove kernel arguments. Subsequently, we need the –update-kernel switch to point to the target kernel. As an example, let’s allow the boot messages on the screen. So, we need to remove the rhgb quiet combination to hide the splash screen:

$ sudo grubby --remove-args="rhgb quiet" --update-kernel /boot/vmlinuz-6.2.9-300.fc38.x86_64

Afterward, let’s review the changes:

$ sudo grubby --info vmlinuz-6.2.9-300.fc38.x86_64
index=0
kernel="/boot/vmlinuz-6.2.9-300.fc38.x86_64"
args="ro rootflags=subvol=root"
# ...

As this kernel is the default one, we can achieve the same effect using DEFAULT:

$ sudo grubby --remove-args="rhgb quiet" --update-kernel DEFAULT

Finally, let’s use the entry’s index as well:

$ sudo grubby --remove-args="rhgb quiet" --update-kernel 0

7.2. Bulk Changes

We can modify the arguments of all available kernels with –arg and –remove-arg options combined with –update-kernel=ALL. So, let’s disable Fedora’s splash screen for all kernels:

$ sudo grubby --remove-args="rhgb quiet" --update-kernel=ALL

Now, let’s check all kernels:

$ sudo grubby --info=ALL
index=0
kernel="/boot/vmlinuz-6.2.9-300.fc38.x86_64"
args="ro rootflags=subvol=root"
# ...
index=1
kernel="/boot/vmlinuz-0-rescue-aa2fe2e4c83744f98664b52388fba883"
args="ro rootflags=subvol=root"
# ...

Finally, let’s restore the splash screen with –args:

$ sudo grubby --args="rhgb quiet" --update-kernel=ALL

7.3. Changing the Default Kernel

To set the default kernel, we can use the –set-default switch. As a reference, we can use the kernel name or index as well. So, let’s set the rescue kernel as the default one:

$ sudo grubby --set-default=/boot/vmlinuz-0-rescue-aa2fe2e4c83744f98664b52388fba883
The default is /boot/loader/entries/aa2fe2e4c83744f98664b52388fba883-0-rescue.conf with index 1 and kernel /boot/vmlinuz-0-rescue-aa2fe2e4c83744f98664b52388fba883

Next, let’s make the entry of index 0 the default one with –set-default-index:

$ sudo grubby --set-default-index=0
The default is /boot/loader/entries/aa2fe2e4c83744f98664b52388fba883-6.2.9-300.fc38.x86_64.conf with index 0 and kernel /boot/vmlinuz-6.2.9-300.fc38.x86_64

7.4. Booting Into Text Mode

A typical case when we’re working with GRUB is enabling text mode. Thus, we need to add 3 to the argument list. Let’s do that for the rescue kernel:

$ sudo grubby --args="3" --update-kernel /boot/vmlinuz-0-rescue-aa2fe2e4c83744f98664b52388fba883

As usual, let’s check the result:

$ sudo grubby --info /boot/vmlinuz-0-rescue-aa2fe2e4c83744f98664b52388fba883
index=1
kernel="/boot/vmlinuz-0-rescue-aa2fe2e4c83744f98664b52388fba883"
args="ro rootflags=subvol=root rhgb quiet 3"
# ...

In this example, we have the splash screen, but we end up in the text console.

7.5. Adding New Entries

With the grubby command, we can add or remove entries in the GRUB menu. So, let’s add the text mode entry permanently with the –add-kernel option:

$ sudo sh -c 'grubby --add-kernel $(grubby --default-kernel) --copy-default --args="3" --title "The text-mode kernel"'
An entry for kernel 6.2.9-300.fc38.x86_64 already exists, adding /boot/loader/entries/aa2fe2e4c83744f98664b52388fba883-6.2.9-300.fc38.x86_64.0~custom.conf

First, let’s take a close look at the command construction. The argument to –add-kernel is the path to the kernel, to which we want to add a new entry. We obtained it with the grubby –default-kernel invocation. Of course, we can do it explicitly with –add-kernel vmlinuz-6.2.9-300.fc38.x86_64.

Next comes the –copy-defaults option, which copies as many settings as possible from the current default kernel. Then, we’re adding the 3 text mode argument to the new kernel. Finally, we set the title for the new entry.

Additionally, we could make the new entry the default one by means of the –make-default switch.

Then, let’s examine the results of this command by listing all kernels:

$ sudo grubby --info=ALL
index=0
kernel="/boot/vmlinuz-6.2.9-300.fc38.x86_64"
args="ro rootflags=subvol=root rhgb quiet 3"
root="UUID=f9a12274-d915-4f46-860e-08b3b8f0ea35"
initrd="/boot/initramfs-6.2.9-300.fc38.x86_64.img"
title="The text-mode kernel"
id="aa2fe2e4c83744f98664b52388fba883-6.2.9-300.fc38.x86_64.0~custom"
index=1
kernel="/boot/vmlinuz-6.2.9-300.fc38.x86_64"
args="ro rootflags=subvol=root rhgb quiet"
root="UUID=f9a12274-d915-4f46-860e-08b3b8f0ea35"
initrd="/boot/initramfs-6.2.9-300.fc38.x86_64.img"
title="Fedora Linux (6.2.9-300.fc38.x86_64) 38 (Workstation Edition)"
id="aa2fe2e4c83744f98664b52388fba883-6.2.9-300.fc38.x86_64"
# ...

Let’s observe that the new kernel has been added at the first position of the list. We’re going to check if it has automatically become the default one. Let’s recall that, so far, the default one was the kernel with the index 0:

$ grubby --default-index
1

So, the default kernel’s index has been updated accordingly and points to the correct entry.

7.6. Removing Kernel Entries

By passing the index to the –remove-kernel option, we can remove the corresponding entry. So, let’s get rid of the text mode entry of index 0:

$ sudo grubby --remove-kernel=0

Then, let’s verify that the entries have been reindexed:

$ sudo grubby --info=ALL
index=0
kernel="/boot/vmlinuz-6.2.9-300.fc38.x86_64"
args="ro rootflags=subvol=root rhgb quiet"
# ...
index=1
kernel="/boot/vmlinuz-0-rescue-aa2fe2e4c83744f98664b52388fba883"
# ...

Therefore, if we’re about to remove more entries, we should always check new indices.

The –remove-kernel option accepts the kernel name as an argument, too. However, we should be extremely cautious when using this approach because all entries that use the same kernel would be removed.

8. Conclusion

In this article, we reviewed Fedora’s and other RHEL-based distributions’ way of maintaining the GRUB menu. First, we talked about the specifics of GRUB configuration in RHEL-based Linux. Next, we learned the grub2-mkconfig command, which applies custom changes to the GRUB configuration.

Next, we focused on the grubby command, designed to fully manage the GRUB menu. We used it to modify kernel arguments, set the default kernel, and create custom configurations.

2 Comments
Oldest
Newest
Inline Feedbacks
View all comments
Comments are closed on this article!