New Grub option GRUB_TOP_LEVEL

The latest grub update introduces new options, to explicitly select an entry of the installation (among linux, linux-lts, linux-zen etc) being at the top level of the menu. In case you use submenus, the selected entry is the one in the front/main page, while it is also at the top in the Advanced menu entries page.

A user may wish to use an image that is not sorted as the “latest”
version as the top-level entry. For example, in Arch Linux, if a user
has the LTS and regular kernels installed, “/boot/vmlinuz-linux-lts”
gets sorted as the “latest” compared to “/boot/vmlinuz-linux”, meaning
the LTS kernel becomes the top-level entry. However, a user may wish to
use the regular kernel as the top-level default with the LTS only
existing as a backup.

This need can be seen in Arch Linux’s AUR with two user-submitted packages (grub-linux-default-hook, grub-linux-rt-default-hook) providing an update hook which patches /etc/grub.d/10_linux to move the desired kernel to the top-level. This patch serves to solve this in a more generic way.

Introduce the GRUB_TOP_LEVEL, GRUB_TOP_LEVEL_XEN and GRUB_TOP_LEVEL_OS_PROBER variables to allow users to specify the top-level entry.

Create grub_move_to_front() as a helper function which moves entries to the front of a list. This function does the heavy lifting of moving the menu entry to the front in each script.

In 10_netbsd, since there isn’t an explicit list variable, extract the items that are being iterated through into a list so that we can optionally apply grub_move_to_front() to the list before the loop.


The online grub manual is not updated with these options (as we are following grub git master branch :wink: )
The relevant change in the manual is this:

GRUB_TOP_LEVEL
GRUB_TOP_LEVEL_XEN

This option should be an absolute path to a kernel image. If provided, the image specified will be made the top-level entry if it is found in the scan.

GRUB_TOP_LEVEL_OS_PROBER

This option should be a line of output from os-prober. As GRUB_TOP_LEVEL, if provided, the image specified will be made the top-level entry if it is found in the scan.


For example (as tested), you can add this line in /etc/default/grub, to set Linux main kernel at the top of the menu list:

GRUB_TOP_LEVEL="/boot/vmlinuz-linux"

Re-create grub configuration to apply the changes:

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

I haven’t tested the os-prober option, but I assume it would be something like this (it’s copied from sudo os-prober output):

GRUB_TOP_LEVEL_OS_PROBER="/dev/sda8:Archcraft (rolling):archcraft:linux"
12 Likes

This seems to be working with btrfs as well. :smile:

Why shouldn’t it? There is no writing from grub itself.

Yeah, and it works around the problem of not being able to use GRUB_SAVEDEFAULT with btrfs.

1 Like

Should I put the line first, or does it matter:

# GRUB boot loader configuration

GRUB_TOP_LEVEL="/boot/vmlinuz-linux"
GRUB_DEFAULT=0
GRUB_TIMEOUT=3
GRUB_DISTRIBUTOR="EndeavourOS"
GRUB_CMDLINE_LINUX_DEFAULT="resume=UUID=48bae162-f72c-460e-b78e-dc2999154904 loglevel=3 nowatchdog nvme_load=YES"
GRUB_CMDLINE_LINUX=""

And what would be the entry for the latest LTS kernel then?

GRUB_TOP_LEVEL="/boot/vmlinuz-linux-lts"

?

I tested very shortly, added GRUB_TOP_LEVEL as you wrote. That worked.
Then I also commented out GRUB_DEFAULT. It worked too.

So simply testing will tell what works and what not.
Tip: better do this testing in a virtual machine first. :wink:

1 Like

It doesn’t matter. /etc/default/grub is just a list of environment variables. The order is irrelevant. If the same variable is entered more than once, the last one is in effect.

Looks OK.

In case of a misunderstanding, the new setting is not replacing or affecting the behavior of GRUB_DEFAULT, AFAIK and IIUC.

GRUB_DEFAULT selects/sets the default boot entry (highlighted).
GRUB_TOP_LEVEL re-orders the list of entries in the menu.

On a non-BTRFS system, if GRUB_DEFAULT=saved, the default (highlighted) boot entry would be the previously booted one.

On BTRFS, the grub environment file is not writable on boot, so the last booted entry cannot be saved. That’s why GRUB_DEFAULT is always used, no matter which entry was previously booted in.

5 Likes

Thanks for the detailed explanation.

What I meant with GRUB_DEFAULT is that obviously its default value is 0 if not set in /etc/default/grub.

And the new GRUB_TOP_LEVEL is a great feature. Helps making easy to set the default entry also on btrfs.

4 Likes

Had to bookmark this post for my Fedora Rawhide installation (daily new kernels).

Thanks a bunch, petros_mou! :+1:

1 Like