BIOS/MBR to UEFI/GPT

Greetings everyone! I’ve come to a situation where I need my system running in UEFI mode, and I was wondering what’s the correct way to switch NixOS - and it’s partitions - to GPT. I’ve done some research on the topic before and I saw that the partition/drive can be changed with sgdisk -g, however this just causes sgdisk to hang. I’ve also read that the device should be “nodev” and efiSupport has to be true, but obviously it doesn’t rebuild since there’s no /boot. How can I go about this? Wouldn’t want to format my drives if possible… Thanks in advance!

Your are mixing two things here: Partition tables and BIOS/UEFI firmware to load the os.

If you want your system to be booted as an UEFI system you need to setup a FAT32 partition where your ESP can be placed (could even be a USB-Stick, but wouldn’t recommend). Probably the easiest way to crate one would be to shrink your root partiton by 256-512MiB and creating a new partiton in the free space (IIRC the ESP does not have to be the first partition) where you would then create a FAT32 fs and point your boot-loader to it (ie. mounting as /boot and setting the configuration options depending on your bootloader)

2 Likes

And you don’t need grub, the nodev thing is specific to grub on NixOS.

1 Like

To add a little bit of detail, with UEFI you need a GPT-formatted disk with a FAT32 partition using the special ESP type code. With gdisk / sgdisk, that means a partition with the ef00 type code. Then, you need to have that partition mounted at /boot (of course meaning you need to update hardware-configuration.nix to account for the new file system).

Finally, you need to configure the boot loader to use this boot partition, and there’s two main options.

  • You can continue to use grub, in which case you should set boot.loader.grub.device = "nodev"; and boot.loader.grub.efiSupport = true;.
    • And you should set one of boot.loader.grub.efiInstallAsRemovable = true; or boot.loader.efi.canTouchEfiVariables = true;. The former tells it to install grub to the fallback file path on the ESP, and the latter tells it to set EFI variables on the system’s NVRAM to point the system at grub.
  • Personally, I recommend enabling systemd-boot instead, which I find to be a much simpler and more reliable boot loader. Remove any grub configuration and replace it with boot.loader.systemd-boot.enable = true; and boot.loader.efi.canTouchEfiVariables = true;. systemd-boot will always install itself to the fallback file path if another OS isn’t already using it, and it will install itself somewhere that it points EFI variables to with boot.loader.efi.canTouchEfiVariables.

Do note that if you have a boot loader already installed on your ESP, switching boot loaders in NixOS won’t automatically remove the old one, which can lead to confusing behavior, such as new generations not being added to the boot menu because you’re actually booting a stale boot loader config from before the switch. You can delete all files relating to that boot loader from the ESP.

3 Likes

Thank you guys so much for the quick replies, and sorry it took me a while to get back at y’all. So basically: Create the FAT32 /boot partition with the special code; Apply changes to the hardware-configuration.nix; Configure the bootloader and rebuild the system configuration? In this order? @zimward mentioned that the ESP doesn’t have to be the first partition, so it shouldn’t matter if I use the unallocated 1GB I have at the end of my drive, right? Just want to be sure. Thanks again for taking your time to help me out!

I’ve lost track a little - is the disk already GPT? If not, remember you will need 2048 sectors (I think) for the back-up partition table at the end of the disk. But yeah, the ESP shouldn’t in theory need to be the first partition, though if somebody told me there was the odd buggy BIOS/firmware out there I wouldn’t be totally shocked.