1. Overview

GRUB is a widespread boot and system loading manager. With its help, we can use different operating systems on the same computer. Also, we may start the same system in various ways, e.g., Linux in graphical, text, or recovery mode.

In this tutorial, we’ll learn how to configure the GRUB menu and set the default entry.

2. GRUB’s Configuration

Let’s take a look at how GRUB is configured. First, we have the GRUB settings in the /etc/default/grub file. Then come scripts to define menus, located in the /etc/grub.d folder. Finally, with sudo update-grub we create an effective configuration in the /boot/grub/grub.cfg file.

Throughout this article, we’ll be working on Ubuntu 20.04. Now, let’s check the GRUB version:

$ grub-install --version
grub-install (GRUB) 2.04-1ubuntu26.15

3. Adding New Menu Entry

Now, let’s list the menu configuration scripts:

$ ls -1 /etc/grub.d
00_header
05_debian_theme
10_linux
10_linux_zfs
20_linux_xen
20_memtest86+
30_os-prober
30_uefi-firmware
35_fwupd
40_custom
41_custom
README

As per convention, the scripts’ names start with numbers because they’re applied in alphabetical order. Consequently, the order of menu positions depends on in which file the menu entry is stored.

Furthermore, for a customized position, we should use 40_custom file, as the name suggests. This file initially doesn’t contain any configuration.

4. Ubuntu Text Terminal

So, let’s create a minimalistic setup for an Ubuntu text terminal:

$ cat /etc/grub.d/40_custom
#!/bin/sh
exec tail -n +3 $0
# This file provides an easy way to add custom menu entries.  Simply type the
# menu entries you want to add after this comment.  Be careful not to change
# the 'exec tail' line above.

menuentry 'Ubuntu text terminal' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux_text_terminal' {
        recordfail
        savedefault
        insmod gzio
        if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
        insmod part_msdos
        insmod ext2
        set root='hd0,msdos1'
        linux   /boot/vmlinuz-5.15.0-46-generic root=UUID=62bbd82f-ed3e-4860-bf8a-d8e11ac0b288 ro $vt_handoff 2
        initrd  /boot/initrd.img-5.15.0-46-generic
}

Let’s notice that we set the menu’s ID to gnulinux_text_terminal with $menuentry_id_option. Next, we set the savedefault feature, which allows saving the menu as a default choice.

Furthermore, we switch to the text mode by adding 2 at the end of the linux line. Finally, the UUID of the boot partition is only an example, we should find the real one with, e.g., blkid.

Now, let’s update GRUB:

$ sudo update-grub

Then let’s reboot, and check the results:

2022-09-08_17h08_58

5. Setting Default Entry Statically

Now, let’s make the text terminal the default choice by editing the /etc/default/grub file. Then, we’re going to change GRUB_DEFAULT:

$ cat /etc/default/grub
# ...
#   info -f grub -n 'Simple configuration'

GRUB_DEFAULT="gnulinux_text_terminal"

# ...

Let’s notice that we’ve used the menu’s ID, but the zero-based index of the entry is allowed as well. Now, let’s reboot to find:

2022-09-08_16h48_39

6. Setting the Default Entry From Menu

Now, let’s configure GRUB to remember our decision and to set the picked-up entry as default. To do so, we need to set GRUB_DEFAULT to saved and also add GRUB_SAVEDEFAULT=true:

$ cat /etc/default/grub
# ...

GRUB_DEFAULT=saved
GRUB_SAVEDEFAULT=true

# ...

Afterward, we need to update GRUB.

7. Command Line Control

We can interact with the GRUB menu from the command line. First, we can set the default boot entry with the grub-set-default command:

$ sudo grub-set-default 0

The command takes the zero-based index of the menu position. So, in this case, we’re going to find the topmost Ubuntu entry highlighted. *Let’s emphasize that we need to set GRUB_DEFAULT=saved for the command to work.*

In a similar manner, we can choose the entry solely for the next boot with the grub-reboot command:

$ sudo grub-reboot 4

So we’re going to end up in the text terminal. For both grub-set-default and grub-reboot, we don’t need to update GRUB for the effect to take place. Finally, the commands come with the grub2-common package.

8. GRUB’s Environment File

Now let’s examine the /boot/grub/grubenv file, which stores GRUB’s information between boots:

$ cat /boot/grub/grubenv
# GRUB Environment Block
saved_entry=gnulinux-simple-62bbd82f-ed3e-4860-bf8a-d8e11ac0b288
next_entry=4

# ...

Hence, we’ve found the ID of the saved entry. In detail, now it corresponds to the first Ubuntu position. Then, next_entry holds the index of the entry, which will be automatically chosen during the next boot. As it has value 4, it’ll be our text terminal.

Consequently, for a quick check, we can grep:

$ grep saved_entry /boot/grub/grubenv
saved_entry=gnulinux-simple-62bbd82f-ed3e-4860-bf8a-d8e11ac0b288

$ grep next_entry /boot/grub/grubenv
next_entry=4

9. Conclusion

In this article, we learned how to customize the GRUB menu. First, we added a new position to the menu with an Ubuntu running text mode. Then, we examined ways to set the default menu entry. First, we did it statically in the GRUB settings. Then, we configured GRUB to remember our choice.

Finally, we learned how to choose the default and next boot entries from the bash command line.