BIOS/MBR to UEFI/GPT with Systemd-boot
Converting NixOS from BIOS/MBR to UEFI/GPT with systemd-boot
Problem Summary
- System was using Legacy BIOS boot with MBR partition table
- Wanted to switch to UEFI boot with systemd-boot
- systemd-boot requires GPT partition table and UEFI mode
Prerequisites
- Backup important data
- NixOS Live USB for recovery
- Access to motherboard BIOS/UEFI settings
Process
1. Create EFI Partition
If no EFI partition exists, create one:
- Boot from Live USB
- Use GParted to shrink root partition by ~1GB
- Create new FAT32 partition
- Set
bootandespflags
2. Convert MBR to GPT
sudo gdisk /dev/nvme1n1
# When prompted about MBR vs corrupt GPT, choose: 2 (MBR)
# Then:
r # Recovery menu
f # Convert MBR to GPT (preserves partitions)
p # Preview - verify partitions are correct
w # Write changes
Y # Confirm
3. Enable UEFI Boot
- Reboot and enter motherboard BIOS (F2/Del/F12)
- Change from Legacy/BIOS to UEFI mode
- Disable CSM (Compatibility Support Module)
- Save and exit
4. Install systemd-boot
Boot from Live USB if needed:
# Mount system
sudo mount /dev/nvme1n1p1 /mnt
sudo mount /dev/nvme1n1p3 /mnt/boot
# Enter chroot
sudo nixos-enter --root /mnt
# Install bootloader
bootctl --path=/boot install
# Generate boot entries
/nix/var/nix/profiles/system/bin/switch-to-configuration boot
# Verify entries exist
ls -la /boot/loader/entries/
5. Get Device UUID for Configuration
Find the UUID of your boot partition:
# Method 1: Using blkid
sudo blkid /dev/nvme1n1p3
# Output: /dev/nvme1n1p3: UUID="XXXX-XXXX" TYPE="vfat"
# Method 2: List all UUIDs
ls -la /dev/disk/by-uuid/ | grep nvme1n1p3
# Method 3: Using lsblk
lsblk -f | grep nvme1n1p3
6. Update NixOS Configuration
Ensure /etc/nixos/configuration.nix has:
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
Update /etc/nixos/hardware-configuration.nix with the UUID from step 5:
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/XXXX-XXXX"; # Replace with your UUID
fsType = "vfat";
options = [ "umask=0077" ];
};
Note: Using UUID is preferred over /dev/nvme1n1p3 because:
- UUIDs persist across reboots
- UUIDs don't change if drive order changes
- More reliable for boot partitions
Common Issues
"efiSysMountPoint = '/boot' is not mounted"
- Mount the EFI partition:
sudo mount /dev/nvme1n1p3 /boot - Ensure it's in hardware-configuration.nix with correct UUID
"Found valid MBR and corrupt GPT"
- Choose option 2 (MBR) to preserve existing partitions
No boot entries in systemd-boot menu
- Use activation script:
/nix/var/nix/profiles/system/bin/switch-to-configuration boot
Stuck at GRUB prompt after conversion
- Boot from Live USB and install systemd-boot as shown above
Verification
- Check boot mode:
[ -d /sys/firmware/efi ] && echo "UEFI" || echo "BIOS" - Check partition table:
sudo parted /dev/nvme1n1 print | grep "Partition Table" - Should show "gpt" and boot in UEFI mode