EndeavourOS with ZFS Boot Menu
written by rick on Monday, July 7, 2025
Why
- ZFS is the only good filesystem. Fight me
- Linux ZFS root is usually weird and always feels like applying the linux way to zfs rather than doing things the zfs way. ZFSBootMenu fixes this
- In my testing, EndeavourOS was the most pleasant experience for gaming on linux (I’m sure ubuntu is fine). You can do it on plain Arch but something is always weird. EndeavourOS just installs like a normal operating system. (NixOS was weird)
- I am used to NixOS generation rollback and the only way to approach this is rollback to file system snapshots in the boot menu. ZFSBootMenu does this beautifully.
It almost works (skip down for full guide)
If you have this almost working but keep getting a failure with /dev/gpt-auto-root
and
then dumped onto a recovery shell (which might be non-functional). Here is what to do:
-
Reset, press Escape on the boot screen to get the full boot menu.
-
Press Ctrl + E to edit the kernel command line
-
Add this argument to the end of the command line
rd.systemd.gpt_auto=0
-
Once in the running system, run
sudo zfs get org.zfsbootmenu:commandline [BOOT dataset]
(probably something like zroot/ROOT or zroot/ROOT/eos) to get your existing kernel command line. Copy this value. -
Update the kernel command line by running
sudo zfs set org.zfsbootmenu="[VALUE YOU COPIED] rd.systemd.gpt_auto=0"
This is the same change we made in the pre-boot environment, but makes it permanent so your system will now boot automatically. -
Reboot, let it auto-boot to check that the change worked. If not, go back and try again to make sure you did everything correctly.
Getting Started
First you need to do all the normal installing linux stuff with a disk image and live environment. (Remember to disable secure boot)
A note on virtual machines
Arch can be kinda weird in vms. I recommend changing your graphics to SPICE
or SPICE (qxl)
or QXL
for better compatibility
Installation
Once you’re booted into the live environment, follow this guide to hack zfs support into the calamares installer and install EndeavourOS on a zfs root with a few updates and adjustments:
The systemd configuration file at /etc/calamares/modules/services-systemd.conf
no
longer has changed syntax a bit so there is just one big units
section. Add .service
to the end of the services and .target
and set action: enable
instead of mandatory
to match the other services in the file. It will look something like
- name: "vmtoolsd.service"
action: "enable"
- name: "vmware-vmblock-fuse.service"
action: "enable"
- name: "zfs.target"
action: "enable"
- name: "zfs-import.target"
action: "enable"
- name: "zfs-import-cache.service"
action: "enable"
- name: "zfs-mount.service"
action: "enable"
be careful about indentation. YAML is like that.
You can also edit /etc/calamares/modules/zfs.conf
to change settings about the pool
and datasets, but the defaults are find if you don’t want to. I would change the
poolname, but only because the default is really long
I would do a swap partition, you can’t have a swapfile.
Follow the rest of the guide, choose online install, and do the normal install stuff. Obviously choose zfs in the partitioning menu. When it gets to selection a bootloader, choose no bootloader. When the installer completes do NOT reboot, your system is not yet bootable, now we need to install ZBM.
Configuring the zfs pool for booting
Info Gathering
We need to set two important options on the pool so that ZBM can boot it. First run sudo zpool status
to verify the name of your pool. Then run sudo zfs list
to view the datasets
created by calamares. One of them will be called something like
zpendeavouros/ROOT/eos/root
and have a mountpoint like
/tmp/calamares-root-[garbage]
. This will become the root dataset mounted to /
when you reboot.
Note the dataset NAME. Now we have the information to set the options.
Setting options
bootfs
Set the bootfs flag on the pool by running sudo zpool set bootfs=[ROOT DATASET] [POOL NAME]
for me this looks like sudo zpool set bootfs=zpendeavouros/ROOT/eos/root zpendeavouros
. You can run sudo zpool get bootfs [POOL NAME]
to verify that it
worked.
kernel command line
ZBM gets the kernel command line from an attribute on the pool, so we need to set that
as well. For EndeavourOS it is essential that you set rd.systemd.gpt_auto=0
or the
boot will fail. You can set any other kernel command line arguments you want, other than
root or rootfstype, which ZBM will handle for us. The option is
org.zfsbootmenu:commandline
set like
sudo zfs set org.zfsbootmenu:commandline="rd.systemd.gpt_auto=0" zpendeavouros/ROOT
ZFS attributes
are inherited, so as long as you set this value on a parent of the bootfs dataset you
should be good, but the guides usually set it on something like zroot/ROOT
, so that’s
what I did.
ZFSBootMenu installation
Re-mounting the ESP
Now that the installer has completed, we will download ZBM to the efi partition and
then add an entry to the efi boot list. Calamares probably unmounted it, so we will need
to remount it. It will likely be the first partition on on the disk you installed to,
but you can find out for sure by running lsblk -f
and looking for the drive that has
zfs_member
as the FSTYPE for one of the partitions. Another partition on that drive
has vfat
in the FSTYPE and this is your efi system partition (ESP). I’ll mount this
with sudo mount --mkdir /dev/[drive] /mnt/efi
, but you can put it wherever, just
remember where it is.
Downloading ZBM
This basically follows the steps common to all the guides on the ZBM website.
cd
to your ESP mountpoint and run sudo mkdir -p EFI/ZBM
then sudo curl -o EFI/ZBM/VMLINUZ.EFI -L https://get.zfsbootmenu.org/efi
. You should end up with [ESP mount]/EFI/ZBM/VMLINUZ.EFI
ZBM only supports zfs booting, so if you have other linux distros or a windows dual boot, you’ll need to install rEFInd and set it up to chain-load into ZBM. You can
Direct EFI boot (skip if using rEFInd)
We need to add ZBM to the boot menu, which we will do with efibootmgr
(should be
installed already). You need the information about your ESP again. If you installed to a
sata drive, it’ll just be /dev/sdX (X will be a letter) for the drive and then the number
that follows that is the partition number (it’s almost certainly 1, unless you’re doing
something really weird). NVME drives are named differently with lots of letters and
numbers. At the end, there should be a p
and then a number. The number is the
partition number (p for partition), and everything before the p (NOT INCLUDING THE p) is
the drive name. If you want to be extra sure, you can ls -l /dev/disk/by-id
.
The command is
sudo efibootmgr -c -d [ESP DISK] -p [ESP partition number] \
-L "ZFSBootMenu"
-l '\EFI\ZBM\VMLINUZ.EFI'
This creates and efi entry for your disk, names it ZFSBootMenu, and tells it to look for
a loader at \EFI\ZBM\VMLINUZ.EFI
. Make sure you use windows-style back-slashes in the
path.
For my drive it looks like
sudo efibootmgr -c -d /dev/sda -p 1 \
-L "ZFSBootMenu"
-l '\EFI\ZBM\VMLINUZ.EFI'
For an install on an NVME disk like /dev/nvme0n1p1
, it would look like
sudo efibootmgr -c -d /dev/nvme0n1 -p 1 \
-L "ZFSBootMenu"
-l '\EFI\ZBM\VMLINUZ.EFI'
rEFInd bootloader (skip if using direct efi boot)
First you need to install refind
with sudo pacman -S refind
. Double check that your
ESP is still mounted and then run sudo refind-install
. In the output it should say
ESP was found on [ESP mountpoint] using vfat
. It will also create a configuration file
(probably /boot/refind_linux.conf
) which is wrong and you should delete it. Create a file at
[efi mount]/EFI/ZBM/refind_linux.conf
with the contents (use your editor or a heredoc)
"Boot default" "quiet loglevel=0 zbm.skip"
"Boot to menu" "quiet loglevel=0 zbm.show"
It should be next to the ZBM binary.
Sanity checks
You can peek at some things on the new system just to make sure it’s working, or just skip down to Export and Reboot.
First run sudo zfs mount [ROOT DATASET]
to re-mount the new system. You cannot just
run sudo zfs mount -a
because the root dataset has canmount=noauto
set.
etc/fstab
The fstab should be configured correctly. Double check that the efi partition and swap are present but none of the zfs datasets are there. The zfs datasets are mounted by the zfs-import and zfs-mount services, not by fstab. Speaking of…
systemd targets and services
Navigate to the etc/systemd/system
of the new system (not the live image), and double
check that the zfs.target.wants
and zfs-import.target.wants
directories are present.
zfs.target.wants
should contain links to zfs-import.service
and
zfs-mount.service
.zfs-import.target.wants
should contain a link to
zfs-import-cache.service
. It’s ok if these links are broken, they’ll be correct when
you reboot. If anything is missing, you can sudo arch-chroot [system mountpoint]
and
enable all the targets and services with systemctl enable
. Do the targets first. exit
to leave the chroot environment.
When you’re done, cd
back to the live environment and sudo zfs umount -a
.
TRIM
Assuming you are running an SSD, you need to enable trim to avoid random system
slowdowns and hangs. You can trim manually by running sudo zpool trim [poolname]
, but
it’s much better to do this automatically by setting sudo zpool set autotrim=on [poolname]
. There is also an fs-trim
service in the util-linux
package if you want
something else.
Export and reboot
The last thing you need to do is export the zpool so you don’t get an error trying to
boot it. sudo zpool export [POOL NAME]
. It might not export cleanly, but it should be
OK anyway. If not you can reboot into the live environment and import and export it.
Post-Install
Now that it’s up and running, you should consider setting up automatic snapshots and backups. File system snapshots are one of the main reasons to use ZFS. I like [sanoid] but you could also use zfs-auto-snapshot.
Extra notes
Using ZBM
Pressing Escape at boot will get you into the full zbm menu. It has pretty good built-in help, so if your system does break, you chroot into it or boot a snapshot or rollback to a snapshot right in the pre-boot environment.
If you are using rEFInd to boot, press Tab then select
Boot to menu
.
Other kernels
EndeavourOS installs the mainline linux kernel by default, but you can usually swap it out or install additional
kernels the usual way. Install the corresponding headers so the
zfs-dkms
module can build correctly. Always check that a newly installed kernel boots before deleting the old one.
The kernel is stored on the main zfs dataset, so you can revert kernels rolling back to
an older snapshot. Get to the boot menu then press
Ctrl + K
to select a kernel to boot. You can change the default kernel in that same menu.
Encryption
One big advantage of ZBM is native encrypted root instead of having to wrap it in a LUKS partition. I couldn’t quite get it working in EndeavourOS; it should be possible, but might require a manual install.
Sources and inspirations
This is mostly based on a few guides about zfs and zbm and arch and endeavour
- ZBM Documentation
- Unofficial EndeavourOS ZFS on Root Guide
- Installing Arch Linux On Ecrypted Root This guide almost works for EndeavourOS, but Endeavour uses dracut instead of mkinitcpio and, of course, the graphical installer.
- This github issue which solved the dracut /dev/gpt-auto-root issue.