rEFInd has a built-in kernel discovery capability, and will automatically generate a config file stored in /boot
with the kernels which allows for a boot entry to be created without the nuisance of setting up a manual boot stanza.
So why bother setting up a manual boot stanza?
The automatic setup does not handle booting with multiple kernels well without additional configuration. When there are multiple kernels and multiple initramfs images in /boot
it will sometimes pair a kernel with an incorrect image, and the system won’t boot unless you pull up the extra boot options menu and select an entry that has a valid configuration. To address this, a value in refind.conf
called extra_kernel_version_strings
has to be set up with a comma-delimited list of strings to fascilitate the kernel detection process.
rEFInd does not look in non-standard root subvolumes (i.e. the root subvolume is named something other than @
) by default. In the case of a boot directory in a non-standard root subvolume, the subvolume holding the kernel and initramfs image must be explicitly stated in refind.conf
(uncomment the also_scan_dirs
line and specify all subvolumes to look for kernels in as name_of_subvolume/boot
).
The process for adding a custom icon to an auto-generated boot entry involves adding a .png to /boot
which is has the same name as the kernel but with the .png extension (for example vmlinuz-linux-zen.png
). This works fine, except if you are continuing to use Grub in addition to rEFInd. Grub picks up the .png as a bootable entry for some reason, and may even set the .png as the default boot option. When booting to Grub, you need to either avoid selecting the default option (because the .png obviously will not boot), or you have to change the default option in your Grub configuration. There may be some way to correct this, but the workaround is unlikely to be simpler than just creating a manual boot stanza.
Booting to Grub needs to be a separate menu option with the automatic setup. Being able to have the Grub option in the submenu is much cleaner (especially if you have many boot entries in the rEFInd menu), and makes it easier to access the correct Grub menu when you need it.
Dealing with the above examples does not represent any great hardship, but with certain configurations there can end up being so many little gotchas and extra steps needed to preserve the “easy, automatic setup” method that it isn’t really that easy or automatic anymore.
By contrast, manual boot stanzas are very straightforward. They are also more deeply configurable than the automatic method, allowing a more fine-grained control over the boot process.
Getting the boot stanza set up is a little tricky, but not overwhelmingly so. Additionally, if you are multibooting off of a single partition you can copy some of the values (volume
and root
, for example) from one stanza to the next as you set them up because they will be the same on every installation.
Here, I’ll explain what the needed components of the stanza are and how you can find them. Additional resources for writing the stanzas can be found on the ArchWiki here, the rEFInd website here, or in refind.conf
itself–there are plenty of example stanzas and documentation about all the different available options written into the file.
Open refind.conf
in your editor. Since it is on the EFI partition, you will have to open it with sudo or as root.
sudo micro /boot/efi/EFI/refind/refind.conf
Scroll all the way down to the bottom of the file. You will see many boot stanza examples on the way down, with disabled
written in as the last option–this is a simple way to disable a boot stanza, instead of commenting out the whole thing.
Find some space in the file to set up your stanza. It can be before or after the example stanzas–it doesn’t really matter, except that whatever order the boot stanzas are in will be the same order the entries appear in the rEFInd menu.
The basic layout of the stanza looks like this (my comments are CAPITALIZED and enclosed in square brackets, the curly brackets are part of the stanza):
menuentry [NAME] {
icon [PATH TO ICON RELATIVE TO EFI PARTITION]
volume [FILESYSTEM LABEL OR PARTUUID OF THE PARTITION YOU ARE BOOTING TO]
loader [PATH TO THE KERNEL, STARTING WITH SUBVOLUME]
initrd [PATH TO THE INITRAMFS IMAGE]
graphics on
options [MUST INCLUDE "root=UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx rw rootflags=subvol=SUBVOLUME" FOLLOWED BY ANY NEEDED KERNEL PARAMETERS]
}
The menuentry
can be named whatever you like, however if it contains a space (more than one word) you must enclose it in quotes (for example, “Garuda Gnome”).
A menuentry
value with no space:
menuentry Garuda {
...
A menuentry
value with a space:
menuentry "Garuda Gnome" {
...
The icon
entry is the path to the icon relative to the EFI partition (i.e. /boot/efi
). So to use the Arch icon at /boot/efi/EFI/refind/icons/os_arch.png
, you write in the stanza /EFI/refind/icons/os_arch.png
.
There is a default icons directory at /boot/efi/EFI/refind/icons
, which has an assortment of .pngs for some popular Linux distros, or you can use a custom icon.
The easiest way to set up your custom icon is to save it on the EFI partition. I recommend not saving it in /boot/efi/EFI/refind/icons
because the directory gets overwritten (rather, saved to a backup file) when the refind-install
script is run. You will have to restore the directory to get your icons back in that case.
Instead, either make your own directory or just store them in /boot/efi/EFI/refind
. For the latter case, you would describe the path in your stanza like so:
icon /EFI/refind/MY_CUSTOM_ICON.png
Again, the path is relative to the EFI partition (i.e. relative to /boot/efi/
in a default Garuda setup).
Alternatively, if you put the icon
entry after the volume
entry then it will be relative to the volume
entry instead of the EFI partition (if, for example, you wanted to store your icon on the Btrfs partition instead of the EFI partition.)
For example, this points to a .png in the boot directory (in this example, the root subvolume is named “@
”):
menuentry Garuda {
volume xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
icon /@/boot/MY_CUSTOM_ICON.png
...
The volume
entry is the partition where the kernels and images are stored (i.e. the Btrfs partiton). You must describe the volume with either the filesystem label, the partition label, or the PARTUUID–not the filesystem UUID.
Run sudo blkid -s PARTUUID -o value /dev/sdXY
, where sdXY
is the Btrfs partition.
sudo blkid -s PARTUUID -o value /dev/nvme0n1p2
e798748f-c287-43e6-b675-cf376345f211
Or, just run sudo blkid
and find the PARTUUID=
value for the Btrfs partition in the output.
Add that value to the volume
entry:
menuentry "Garuda Gnome" {
icon icon /EFI/refind/gnome_logo.png
volume e798748f-c287-43e6-b675-cf376345f211
...
If you labeled your filesystem in the installer (in the step where you set up the mount points for /boot/efi
and /
), you can use the label in the stanza instead of the PARTUUID if you want to.
The loader
points to the kernel and the initrd
entry points to the initial ramdisk. The path is relative to the root of the volume
entry, and needs to be preceded by the subvolume.
Look in your /boot
directory and find the kernel and the initial ramdisk files:
Write the path to each file starting with the root subvolume. In this example, the root subvolume is named “gnome
”:
menuentry "Garuda Gnome" {
icon /EFI/refind/gnome_logo.png
volume e798748f-c287-43e6-b675-cf376345f211
loader /gnome/boot/vmlinuz-linux-zen
initrd /gnome/boot/initramfs-linux-zen.img
...
The graphics
option needs to be set to on
if you wish for rEFInd to boot in graphics-mode, instead of just using a console. This will be needed if you want to use a Plymouth splash screen, and I recommend setting it if you want to boot to Grub as well. If you don’t, Grub will still load but it will be in a low-resolution mode that can make it difficult to see all the options in the menu on certain displays.
If you have set graphics on
in your stanza but you are still not seeing your Plymouth splash screen, you may need to enable early kernel mode setting as well. See here for how to set that up on a dracut system, or here for a mkinitcpio system.
This one is a little tricky because there are a few components you need to put together to get the line right.
/etc/fstab
or lsblk -f
) and specify read-write access (rw
), for example:root=UUID=5fa54f34-b5fc-40be-8092-8ba34ced9eba rw
rootflags=subvol=*root_subvolume*
(as described here), for example:rootflags=subvol=gnome
GRUB_CMDLINE_LINUX_DEFAULT=
line in /etc/default/grub
), for example:quiet quiet splash rd.udev.log_priority=3 vt.global_cursor_default=0 loglevel=3 nvme.noacpi=1 nowatchdog
Combine these three components on one line enclosed in quotation marks (“…”), and that is your options
entry:
menuentry "Garuda Gnome" {
icon /EFI/refind/gnome_logo.png
volume e798748f-c287-43e6-b675-cf376345f211
loader /gnome/boot/vmlinuz-linux-zen
initrd /gnome/boot/initramfs-linux-zen.img
graphics on
options "root=UUID=5fa54f34-b5fc-40be-8092-8ba34ced9eba rw rootflags=subvol=gnome quiet quiet splash rd.udev.log_priority=3 vt.global_cursor_default=0 loglevel=3 nvme.noacpi=1 nowatchdog"
...
If you are using mkinitcpio to build your initramfs instead of dracut, you need to add
initrd=boot\cpu_manufacturer-ucode.img
to the options line as well in order to get your microcode loaded, see here: https://wiki.archlinux.org/title/microcode#rEFInd
refind_linux.conf
to write the options
entryAn easy way to get a pre-made options
entry is to grab it out of the auto-generated refind_linux.conf
file. When you run refind-install
, the script will generate a configuration file that can serve as a pre-made boot entry. Even if you are not planning to boot with the auto-generated boot config, you can still use this file to your advantage.
If you did not run refind-install
on the installation you are booted into, you can generate this file by running mkrlconf
.
Print the contents of the file:
cat /boot/refind_linux.conf
File: /boot/refind_linux.conf
"Boot with standard options" "root=UUID=5fa54f34-b5fc-40be-8092-8ba34ced9eba rw rootflags=subvol=gnome quiet quiet splash rd.udev.log_priority=3 vt.global_cursor_default=0 loglevel=3 nvme.noacpi=1 nowatchdog"
"Boot to single-user mode" "root=UUID=5fa54f34-b5fc-40be-8092-8ba34ced9eba rw rootflags=subvol=gnome quiet quiet splash rd.udev.log_priority=3 vt.global_cursor_default=0 loglevel=3 single nvme.noacpi=1 nowatchdog"
"Boot with minimal options" "ro root=/dev/nvme0n1p2"
That part after “Boot with standard options” is your whole options
line written out, based on whatever kernel parameters you are booted with when the refind-install
or mkrlconf
script generates the file.
To be clear, I am talking about this part of the file:
Copy the whole line, including the quotes, and paste into your boot stanza.
Submenu entries are a special option that can be added to a manual boot stanza. When a menu entry is highlighted on the rEFInd boot screen and you press Enter, it will boot the main entry in the stanza. If you press Tab instead, it will bring up a menu with all of the submenu entries you have set up.
Here is an example of a submenu:
This is a quick and easy way to access different boot options like alternate kernels or a fallback image, or even booting to the Grub bootloader for booting directly into Btrfs snapshots.
Setting up the submenu entries is pretty simple once you have the boot stanza finished. Basically you just need override any lines in the stanza that are different for the submenu option.
To add a submenu entry for booting with the fallback image, the only line that needs to change is the initrd
line:
...
submenuentry "Zen fallback" {
initrd /gnome/boot/initramfs-linux-zen-fallback.img
}
...
If all of the other lines in the stanza (volume
, loader
, and options
) are going to remain the same for this boot option, then you are done! No need to specify any additional lines unless they deviate from the main stanza.
If you wanted your fallback boot entry to have different kernel parameters, you can add a new options line as well. For example, if you want your fallback entry to boot without the quiet boot kernel parameters (quiet quiet splash rd.udev.log_priority=3 vt.global_cursor_default=0 loglevel=3
) so you can see the journal output at startup, simply re-do the options
line with those options omitted.
...
submenuentry "Zen fallback" {
initrd /gnome/boot/initramfs-linux-zen-fallback.img
options "root=UUID=5fa54f34-b5fc-40be-8092-8ba34ced9eba rw rootflags=subvol=gnome nvme.noacpi=1 nowatchdog"
}
...
To create a submenu entry for an alternate kernel, specify override values for loader
and initrd
:
...
submenuentry "LTS kernel" {
loader /gnome/boot/vmlinuz-linux-lts
initrd /gnome/boot/initramfs-linux-lts.img
}
...
And finally, to create an entry to boot to Grub you need to override the volume
entry (since the target in this case is on the EFI partition, not the Btrfs partition which is the volume
specified in the main stanza) and also the loader
entry.
In the case of booting to Grub, the loader
does not point to a kernel, but rather it points to the grubx64.efi
file for that Grub installation. If you recall, back in the “Update Grub” section earlier in the topic, we renamed /boot/efi/EFI/Garuda
to something else (in the example it was changed to /boot/efi/EFI/Gnome
). That is the directory we need to point to in this submenu entry.
...
submenuentry Grub {
volume 15a71d3d-f2ef-4513-8e6b-a65458ffbb75
loader /EFI/Gnome/grubx64.efi
}
...
The volume
in the example is the PARTUUID of the EFI partition (or you may use a filesystem label if you made one). Check sudo blkid
to find the PARTUUID or the label if you have one.
The boot stanza is complete!
menuentry "Garuda Gnome" {
icon /EFI/refind/gnome_logo.png
volume e798748f-c287-43e6-b675-cf376345f211
loader /gnome/boot/vmlinuz-linux-zen
initrd /gnome/boot/initramfs-linux-zen.img
graphics on
options "root=UUID=5fa54f34-b5fc-40be-8092-8ba34ced9eba rw rootflags=subvol=gnome quiet quiet splash rd.udev.log_priority=3 vt.global_cursor_default=0 loglevel=3 nvme.noacpi=1 nowatchdog"
submenuentry "Zen fallback" {
initrd /gnome/boot/initramfs-linux-zen-fallback.img
options "root=UUID=5fa54f34-b5fc-40be-8092-8ba34ced9eba rw rootflags=subvol=gnome nvme.noacpi=1 nowatchdog"
}
submenuentry "LTS kernel" {
loader /gnome/boot/vmlinuz-linux-lts
initrd /gnome/boot/initramfs-linux-lts.img
}
submenuentry "LTS fallback" {
loader /gnome/boot/vmlinuz-linux-lts
initrd /gnome/boot/initramfs-linux-lts-fallback.img
options "root=UUID=5fa54f34-b5fc-40be-8092-8ba34ced9eba rw rootflags=subvol=gnome nvme.noacpi=1 nowatchdog"
}
submenuentry Grub {
volume 15a71d3d-f2ef-4513-8e6b-a65458ffbb75
loader /EFI/Gnome/grubx64.efi
}
}