Migrating Fedora from GRUB to systemd-boot
A Guide for Fedora 44
If you've been running Fedora for a while, your system almost certainly has the same partition layout the installer has been creating for years: a small FAT32 EFI partition and a separate /boot partition. This guide will walk you through replacing GRUB with systemd-boot and merging those two partitions into one clean setup.
Each step was tested on a Fedora 44 system. Follow carefully and you'll be done in about 30 minutes.
Before You Start
Who this guide is for
- Fedora users on a single-drive, single-boot system (no Windows dual boot)
- Systems with the standard Fedora partition layout: EFI partition + separate
/bootpartition - UEFI systems only (systemd-boot does not support Legacy BIOS)
Who should stop reading now
- Dual-boot Windows users
- BitLocker users
- Systems with encrypted
/boot - Legacy BIOS systems
What you'll need
- A Fedora Live USB
- Physical access to your machine
- Your BIOS key (common choices: F2, Del, ESC, F7; check your motherboard manual)
- About 30 minutes
Why bother?
GRUB has served Linux well for decades, but it is significantly more complex than most users need. It contains hundreds of thousands of lines of code, including its own filesystem drivers, all running before your OS starts, before any security protections are active. For the vast majority of users, that complexity exists purely to solve problems they don't have.
systemd-boot is simpler by design. It reads only FAT32 (the same filesystem your UEFI firmware reads natively), has a fraction of the codebase, and is straightforward to configure and maintain. Less code also means less attack surface. BootHole in 2020 demonstrated this concretely; a buffer overflow in GRUB's config parser allowed attackers to bypass Secure Boot entirely. That class of vulnerability doesn't exist in systemd-boot because the complexity that enabled it doesn't exist.
systemd-boot is also where Fedora, and the Linux ecosystem broadly, is heading. This guide gets you there now.
Understanding the Partition Problem
A standard Fedora install creates this:
/dev/nvme0n1p1 600MB vfat /boot/efi ← EFI System Partition /dev/nvme0n1p2 1GB xfs/ext4/btrfs /boot ← Boot partition (kernels live here) /dev/nvme0n1p3 64GB swap /dev/nvme0n1p4 1.8TB xfs/btrfs / ← Root partition
Fedora's installer (Anaconda) has used different filesystems for /boot over the years depending on the version and installation choices:
- XFS: common default in recent Fedora versions
- ext4: was the default for many years, common on older installations
- btrfs: increasingly common, especially when Fedora's btrfs-by-default option is selected
It doesn't matter which one you have. The problem is identical regardless: systemd-boot cannot read XFS, ext4, or btrfs. It only speaks FAT32, the same filesystem your UEFI firmware uses natively. GRUB worked with these filesystems because it carries its own filesystem drivers. systemd-boot deliberately does not, which is a feature: less code means less attack surface.
The solution is the same in every case: merge the two partitions into one larger FAT32 partition. This is the direction the Linux ecosystem is moving toward, with a single, larger EFI partition that holds both the bootloader and the kernels.
End result:
/dev/nvme0n1p1 1.7GB vfat /boot/efi ← Single merged partition /dev/nvme0n1p3 64GB swap /dev/nvme0n1p4 1.8TB xfs/btrfs / ← Root partition (unchanged)
First: Check Your Layout
lsblk -o NAME,FSTYPE,SIZE,MOUNTPOINTS
Confirm:
- A
vfatpartition mounted at/boot/efi - A partition (xfs, ext4, or btrfs) mounted at
/boot - Your root partition mounted at
/
Phase 1: Prepare Your Running System
Do these steps before you boot the Live USB.
Step 1: Install systemd-boot
Fedora doesn't install the systemd-boot binaries by default. Install the unsigned version (we're disabling Secure Boot anyway):
run0 dnf install systemd-boot-unsigned run0 bootctl install
Step 2: Set the Boot Layout
Tell Fedora's kernel management tools to use the Boot Loader Specification format instead of GRUB-specific entries:
run0 mkdir -p /etc/kernel echo "layout=bls" | run0 tee /etc/kernel/install.conf
Step 3: Capture Your Kernel Command Line
Your current boot parameters need to be preserved. This command captures them and strips the GRUB-specific prefix:
cat /proc/cmdline | sed 's/BOOT_IMAGE=[^ ]* //' | run0 tee /etc/kernel/cmdline
Verify the output looks correct. It should be a single line starting with root=UUID=... and containing your boot parameters. If you have selinux=0 or other custom flags, confirm they are present.
Step 4: Set the Boot Order
Tell your firmware to prefer systemd-boot. First check current entries:
run0 efibootmgr
Find the ID number for "Linux Boot Manager" and put it first. For example, if Linux Boot Manager is 0001 and Fedora is 0000:
run0 efibootmgr -o 0001,0000
Step 5: Prevent tuned Conflicts
Fedora's tuned service tries to inject power management parameters into your boot entries. This works with GRUB but breaks systemd-boot. Disable it proactively:
run0 sed -i 's/TUNED_BOOT_CMDLINE_PARAM=.*/TUNED_BOOT_CMDLINE_PARAM=""/' /etc/tuned-main.conf
Phase 2: The Partition Merge (Live USB)
Reboot into your Fedora Live USB. Open a terminal and switch to root:
run0
Step 6: Mount Your Root Partition
mount /dev/nvme0n1p4 /mnt
Replace nvme0n1p4 with your actual root partition if different. If unsure, run lsblk to confirm.
Step 7: Mount Your EFI Partition
mkdir -p /mnt/boot/efi mount /dev/nvme0n1p1 /mnt/boot/efi
Step 8: Back Up Your EFI Partition
cp -r /mnt/boot/efi /mnt/temp_efi_backup
Verify the backup:
ls /mnt/temp_efi_backup
You should see folders like EFI, loader, and a long machine-id string.
Step 9: Unmount the EFI Partition
umount /mnt/boot/efi
Step 10: Check the Partition Layout
parted /dev/nvme0n1 print
Note the End value of your /boot partition (p2). You'll use this in the next step. In a standard Fedora install this is typically around 1704MB, but it will vary on your system.
Step 11: Delete the Boot Partition
parted /dev/nvme0n1 rm 2
You'll see a message saying you may need to update /etc/fstab. We'll handle that shortly.
Step 12: Resize the EFI Partition
Expand p1 to fill the space left by the deleted partition. Use the End value you noted in Step 10:
parted /dev/nvme0n1 resizepart 1 1704MB
Step 13: Format the Enlarged Partition
Since we changed the size, we need to reformat. Your backup is safe in /mnt/temp_efi_backup:
mkfs.fat -F32 /dev/nvme0n1p1
Step 14: Mount the New Partition
mount /dev/nvme0n1p1 /mnt/boot/efi
Step 15: Restore Your Backup
cp -r /mnt/temp_efi_backup/* /mnt/boot/efi/
Verify the restore:
ls /mnt/boot/efi
You should see your EFI files back in place.
Step 16: Get the New UUID
Reformatting created a new UUID. Write this down, you will need it for fstab:
lsblk -o NAME,UUID /dev/nvme0n1p1
Step 17: Check and Update fstab
cat /mnt/etc/fstab
You need to make two changes:
- Update the UUID for the
/boot/efiline to the new UUID from Step 16 - Delete the line for
/bootentirely, as that partition no longer exists
Edit the file:
nano /mnt/etc/fstab
Note: In some cases Fedora's fstab may already show the correct UUID if the partition inherited it. Always verify before assuming.
Step 18: Verify the Final Partition Table
parted /dev/nvme0n1 print
You should see only three partitions: p1 (fat32, ~1.7GB), p3 (swap), p4 (your root filesystem). No p2.
Step 19: Check Boot Entries Exist
ls /mnt/boot/efi/loader/entries/
You should see .conf files here. If this folder is empty, your kernel entries didn't survive the migration. In that case run:
kernel-install add [KERNEL_VERSION] /lib/modules/[KERNEL_VERSION]/vmlinuz
Replace [KERNEL_VERSION] with your actual kernel version (e.g. 7.0.3-200.fc44.x86_64). If unsure of the version, check /mnt/lib/modules/ to see what's installed. If entries are present, skip this step.
Phase 3: First Boot into systemd-boot
Reboot the machine and immediately enter your BIOS/UEFI settings.
In the BIOS:
- Disable Secure Boot. This is required because we installed the unsigned systemd-boot binary. Without this the firmware will refuse to run it.
- Set boot order. Move "Linux Boot Manager" to position #1.
- Save and exit.
What to expect:
Instead of the Fedora GRUB menu, you'll see a simple black-and-white text menu. Use arrow keys to select your kernel and press Enter.
If you see a blank screen or "File not found" error, reboot and press your boot menu key (usually F12) to manually select an entry. If you still have the GRUB Fedora entry available, select it to get back into your system and troubleshoot.
Phase 4: Post-Boot Cleanup
These final steps clean up after the migration.
Step 20: Verify systemd-boot is Running
run0 bootctl status
You should see Product: systemd-boot under Current Boot Loader, with all features showing ✓.
Step 21: Verify Kernel Entries
run0 bootctl list
Your current kernel should appear as (default) (selected). If you have multiple kernels installed they should all be listed.
Step 22: Clean Up Stale EFI Entries
Check what's in your EFI variables:
run0 efibootmgr
Delete any remaining Fedora/GRUB entries, as they are no longer needed. For each stale entry ID (e.g. 0000, 0006):
run0 efibootmgr -b 0000 -B
Leave only "Linux Boot Manager" in the list.
Step 23: Enable Automatic Bootloader Updates
As of systemd version 250, a service exists that keeps the systemd-boot binary itself up to date automatically. Enable it:
run0 systemctl enable systemd-boot-update.service run0 systemctl start systemd-boot-update.service
Without this, the systemd-boot binary on your ESP can fall out of sync with the version installed by dnf.
Step 24: Configure the Boot Menu
Set a timeout so you have time to select a different kernel if needed:
run0 nano /boot/efi/loader/loader.conf
It should contain:
timeout 3 console-mode keep default @saved
timeout 3 gives you a 3 second window before it boots automatically. default @saved remembers whichever kernel you last booted. Without a timeout configured, systemd-boot skips the menu entirely, which means you'll have no way to select an older kernel if a bad update comes through.
Step 25: Final Verification
Run these verification checks:
run0 bootctl status run0 bootctl list systemctl is-enabled systemd-boot-update.service run0 efibootmgr run0 cat /boot/efi/loader/loader.conf
Everything should be clean: one boot entry in EFI variables, all kernels listed, service enabled, timeout configured.
Will Future Kernel Updates Work Automatically?
Yes, with one caveat. Fedora's kernel-install scripts will automatically place new kernels on your ESP when you run dnf update. However, the scripts still contain some GRUB references that generate harmless warnings like:
grub2-editenv: error: failed to get canonical path of `/boot/grub2'
This is benign. The kernel installs correctly regardless. After any kernel update, verify with:
run0 bootctl list
If the new kernel appears, everything is working. If it doesn't appear, use the emergency kernel-install add command from Step 19.
What About Secure Boot?
Secure Boot is disabled in this guide because we installed the unsigned systemd-boot binary. For most home users this is a reasonable tradeoff. The security benefit of Secure Boot is primarily protection against physical "evil maid" attacks on unattended hardware.
The path to re-enabling Secure Boot with systemd-boot involves Unified Kernel Images (UKIs), which are single signed .efi files that combine the kernel, initrd, and command line into one tamper-evident package. Fedora is actively working toward making this the default. Your current setup is already compatible since systemd-boot supports UKIs natively and your ESP has sufficient space.
Troubleshooting
Blank screen on boot: Secure Boot is probably still enabled. Enter BIOS and disable it.
"No entries found" in systemd-boot menu: Your .conf files are missing. Boot into the Live USB, mount your ESP, and run kernel-install add as described in Step 19.
System drops to emergency shell: Your fstab UUID is wrong. Boot the Live USB, mount your root partition, and correct the UUID in /mnt/etc/fstab.
"Error preparing initrd": The tuned service injected a bad parameter. Press e at the boot menu to edit the entry and remove any initrd /tuned... reference from the options line. Then re-run the tuned fix from Step 5 and reinstall the kernel entry.
GRUB keeps loading despite boot order change: Some firmware ignores efibootmgr changes and hardcodes a preference for \EFI\fedora\shimx64.efi. Enter your BIOS boot menu manually (usually F7 or F12) and select "Linux Boot Manager" directly. Once confirmed working, the EFI variable order should stick on subsequent boots.
btrfs /boot note: If your /boot was formatted as btrfs the deletion and reformat process is identical. btrfs requires no special handling. It is simply another filesystem that systemd-boot cannot read, and the partition merge resolves that the same way as XFS or ext4.
Summary
You now have:
- systemd-boot replacing GRUB
- A single clean ~1.7GB FAT32 boot partition
- Automatic bootloader updates configured
- A 3 second boot menu timeout
- A setup compatible with the upcoming UKI and Secure Boot transition
Fedora's default partition layout was designed around GRUB, which is why this manual migration is necessary in the first place. On a fresh install configured correctly from the start, none of this would be needed.
No comments:
Post a Comment