UEFI – Chainloading GRUB from GRUB

boot-loaderdual-bootgrub2uefi

Terminology: ESP = my FAT32 EFI partition.

I want to:

  • Have a self-contained GRUB install on my ESP that chainloads another GRUB bootloader on my distro root filesystem (/). I currently have several distros without GRUB installed on my partitions. Each is installed completely on their own ext4 /. I want them all to have their own secondary bootloader.
  • Also acceptable is for the primary ESP GRUB to restart/reload with a grub.cfg from the OS. Effectively chainloading itself.

What I've tried:

  • Examples I've found include booting GRUB legacy from GRUB2 and vice versa but they don't use UEFI and .efi files. The GNU GRUB documentation doesn't even mention UEFI, and the Arch/Ubuntu/Gentoo wikis provide the bare minimal info to set up a basic (non-chainloading) install.

So far:

  • I've installed GRUB onto my ESP using grub-install and
    grub-mkconfig.Test boot works. This means my /boot/grub folder is empty, and my ESP doesn't need to be mounted during/after boot.
  • I've tried installing a second grub into /boot/efi/ and /boot/grub/, but the EFI part won't install, grub-install complains the target is not an EFI partition. But since I already have a primary GRUB installed, it shouldn't matter that my secondary GRUB is on the ext4 rootfs right? Grub can read ext4. I tried the --force option too.

So it seems I need to find some way of convincing the installer that it is OK to install grubx64.efi under /boot/EFI

If anyone is curious about how I installed the primary GRUB, it was just a matter of using the right options in grub-install with respect to my ESP.

Best Answer

There's another way: you can create a menu entry that tells GRUB to load another secondary grub.cfg, such as one from another Linux distro.

For example, I started with Gentoo Linux from which I installed GRUB2 into the MBR (the machine is too old for EFI).

I then installed NixOS, which I configured to generate grub.cfg in it's own /boot (separate from Gentoo's /boot) but without installing GRUB.

To clarify, grub-install was executed from Gentoo but not from NixOS.

Next, to be able to boot NixOS, I added this to /etc/grub.d/40_custom in Gentoo:

#!/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 'NixOS' --class gnu-linux --class gnu --class os $menuentry_id_option 'nixos-0aca58bc-8fdb-4a07-aa2f-56406bcf19b7' {
        set root='hd0,msdos4'
        configfile /nixos/root/boot/grub/grub.cfg
}

The key is the configfile /nixos/root/boot/grub/grub.cfg line. It tells GRUB to load another grub.cfg. I then ran grub-mkconfig from Gentoo to apply the changes.

Now, when I boot and select NixOS the entire GRUB interface refreshes to reflect the NixOS grub.cfg, from which I can boot the OS. Unlike chainloading, this configuration utilizes a single installation of GRUB; it simply uses a second configuration.

Related Question