Release v2.2.2 is EOL. Refer to https://docs.zfsbootmenu.org for current documentation.

SYSLINUX MBR#

This guide can be used to install Void onto a single ZFS disk with or without ZFS encryption. It assumes the following:

  • Your system uses BIOS to boot

  • Your system is x86_64

  • You will use glibc as your system libc.

  • /dev/sda is the disk to be used for both ZFS and syslinux

  • You're mildly comfortable with ZFS and discovering system facts on your own (lsblk, dmesg, gdisk, ...)

ZFSBootMenu does not require glibc and is not restricted to x86_64. If you are comfortable installing Void Linux on other architectures or with the musl libc, you can adapt the instructions here to your desired configuration.

Download the latest hrmpf, write it to USB drive and boot your system in BIOS mode.

Configure Live Environment#

Source /etc/os-release#

The file /etc/os-release defines variables that describe the running distribution. In particular, the $ID variable defined within can be used as a short name for the filesystem that will hold this installation.

source /etc/os-release
export ID

Generate /etc/hostid#

zgenhostid -f 0x00bab10c

Define disk variables#

For convenience and to reduce the likelihood of errors, set environment variables that refer to the devices that will be configured during the setup.

For many users, it is most convenient to place boot files (i.e., ZFSBootMenu and any loader responsible for launching it) on the the same disk that will hold the ZFS pool. However, some users may wish to dedicate an entire disk to the ZFS pool or create a multi-disk pool. A USB flash drive provides a convenient location for the boot partition. Fortunately, this alternative configuration is easily realized by simply defining a few environment variables differently.

Verify your target disk devices with lsblk. /dev/sda, /dev/sdb and /dev/nvme0n1 used below are examples.

First, define variables that refer to the disk and partition number that will hold boot files:

export BOOT_DISK="/dev/sda"
export BOOT_PART="1"
export BOOT_DEVICE="${BOOT_DISK}${BOOT_PART}"

Next, define variables that refer to the disk and partition number that will hold the ZFS pool:

export POOL_DISK="/dev/sda"
export POOL_PART="2"
export POOL_DEVICE="${POOL_DISK}${POOL_PART}"

Disk preparation#

The disk(s) that will hold the syslinux partition and ZFS pool should be labeled in MBR format and configured to provide partitions for boot files as well as the ZFSBootMenu.

cat <<EOF | sfdisk "${POOL_DISK}"
label: dos
start=1MiB, size=512MiB, type=83, bootable
start=513MiB, size=+, type=83
EOF

ZFS pool creation#

Create the zpool#

zpool create -f -o ashift=12 \
 -O compression=lz4 \
 -O acltype=posixacl \
 -O xattr=sa \
 -O relatime=on \
 -o autotrim=on \
 -o compatibility=openzfs-2.1-linux \
 -m none zroot "$POOL_DEVICE"

Note

The option -o compatibility=openzfs-2.1-linux ensures that the pool is created only with feature flags supported by the current ZFSBootMenu binary release. If you plan on building a custom ZFSBootMenu image that you will keep synchronized with your host, the compatibility option may be omitted.

Binary releases of ZFSBootMenu are generally built with the latest stable version of ZFS. Future releases of ZFSBootMenu may therefore support newer feature sets. Check project release notes prior to updating or removing compatibility options and upgrading your system pool.

Create initial file systems#

zfs create -o mountpoint=none zroot/ROOT
zfs create -o mountpoint=/ -o canmount=noauto zroot/ROOT/${ID}
zfs create -o mountpoint=/home zroot/home

zpool set bootfs=zroot/ROOT/${ID} zroot

Note

It is important to set the property canmount=noauto on any file systems with mountpoint=/ (that is, on any additional boot environments you create). Without this property, the OS will attempt to automount all ZFS file systems and fail when multiple file systems attempt to mount at /; this will prevent your system from booting. Automatic mounting of / is not required because the root file system is explicitly mounted in the boot process.

Also note that, unlike many ZFS properties, canmount is not inheritable. Therefore, setting canmount=noauto on zroot/ROOT is not sufficient, as any subsequent boot environments you create will default to canmount=on. It is necessary to explicitly set the canmount=noauto on every boot environment you create.

Export, then re-import with a temporary mountpoint of /mnt#

zpool export zroot
zpool import -N -R /mnt zroot
zfs mount zroot/ROOT/${ID}
zfs mount zroot/home

Verify that everything is mounted correctly#

# mount | grep mnt
zroot/ROOT/void on /mnt type zfs (rw,relatime,xattr,posixacl)
zroot/home on /mnt/home type zfs (rw,relatime,xattr,posixacl)

Install Void#

Adjust the mirror, libc, and package selection as you see fit.

XBPS_ARCH=x86_64 xbps-install \
  -S -R https://mirrors.servercentral.com/voidlinux/current \
  -r /mnt base-system

Copy our files into the new install#

cp /etc/hostid /mnt/etc

Chroot into the new OS#

xchroot /mnt

Basic Void configuration#

Set the keymap, timezone and hardware clock#

cat << EOF >> /etc/rc.conf
KEYMAP="us"
HARDWARECLOCK="UTC"
EOF
ln -sf /usr/share/zoneinfo/<timezone> /etc/localtime

Configure your glibc locale#

Note

This does not need to be done on musl, as musl does not have system locale support.

cat << EOF >> /etc/default/libc-locales
en_US.UTF-8 UTF-8
en_US ISO-8859-1
EOF
xbps-reconfigure -f glibc-locales

Set a root password#

passwd

ZFS Configuration#

Configure Dracut to load ZFS support#

cat << EOF > /etc/dracut.conf.d/zol.conf
nofsck="yes"
add_dracutmodules+=" zfs "
omit_dracutmodules+=" btrfs "
EOF

Install ZFS#

xbps-install -S zfs

Install and configure syslinux#

Create a ext4 boot filesystem#

mkfs.ext4 -O '^64bit' "$BOOT_DEVICE"

Note

Under some circumstances, syslinux may fail to recognize files on an ext4 filesystem. The issue may be related to the 64bit feature of the filesystem, which is explicitly disabled in the command above. If syslinux still fails to recognize files on the ext4 partition, try using ext3 or ext2 as a fallback.

Create an fstab entry and mount#

cat << EOF >> /etc/fstab
$( blkid | grep "$BOOT_DEVICE" | cut -d ' ' -f 2 ) /boot/syslinux ext4 defaults 0 0
EOF

mkdir /boot/syslinux
mount /boot/syslinux

Install the syslinux package, copy modules#

xbps-install -S syslinux
cp /usr/lib/syslinux/*.c32 /boot/syslinux

Install extlinux#

extlinux --install /boot/syslinux

Install the syslinux MBR data#

dd bs=440 count=1 conv=notrunc if=/usr/lib/syslinux/mbr.bin of="$BOOT_DISK"

Install and configure ZFSBootMenu#

Set ZFSBootMenu properties on datasets#

Assign command-line arguments to be used when booting the final kernel. Because ZFS properties are inherited, assign the common properties to the ROOT dataset so all children will inherit common arguments by default.

zfs set org.zfsbootmenu:commandline="quiet loglevel=4" zroot/ROOT

Install the ZFSBootMenu package#

xbps-install -S zfsbootmenu

Enable zfsbootmenu image creation#

Edit /etc/zfsbootmenu/config.yaml and make sure that the following parameters are set:

Global:
  ManageImages: true
  BootMountPoint: /boot/syslinux
Components:
  Enabled: true
  Versions: false
  ImageDir: /boot/syslinux/zfsbootmenu

See generate-zbm(5) for more details.

Configure syslinux#

The generate-zbm image-creation utility includes now-deprecated support for managing a syslinux configuration. Because this capability is slated for removal and was not reliable in the first place, it is better to create a static syslinux configuration. The ZFSBootMenu configuration described above disables explicit image versioning, which means that each invocation of generate-zbm will produce two output files at a predictable location:

  • /boot/syslinux/zfsbootmenu/vmlinuz-bootmenu

  • /boot/syslinux/zfsbootmenu/initramfs-bootmenu.img

In addition, any existing copies of the ZFSBootMenu kernel and initramfs will be saved to a backup location:

  • /boot/syslinux/zfsbootmenu/vmlinuz-bootmenu-backup

  • /boot/syslinux/zfsbootmenu/initramfs-bootmenu-backup.img

The following syslinux configuration will provide a simple menu that provides a choice between the current and backup images:

cat > /boot/syslinux/syslinux.cfg <<EOF
UI menu.c32
PROMPT 0

MENU TITLE ZFSBootMenu
TIMEOUT 50

DEFAULT zfsbootmenu

LABEL zfsbootmenu
  MENU LABEL ZFSBootMenu
  KERNEL /zfsbootmenu/vmlinuz-bootmenu
  INITRD /zfsbootmenu/initramfs-bootmenu.img
  APPEND zfsbootmenu quiet loglevel=4

LABEL zfsbootmenu-backup
  MENU LABEL ZFSBootMenu (Backup)
  KERNEL /zfsbootmenu/vmlinuz-bootmenu-backup
  INITRD /zfsbootmenu/initramfs-bootmenu-backup.img
  APPEND zfsbootmenu quiet loglevel=4
EOF

Consult the syslinux documentation for more details on the contents of the syslinux.cfg configuration file. To alter the command-line arguments passed to the ZFSBootMenu image, adjust the contents of the APPEND lines in the configuration.

Generate the initial ZFSBootMenu initramfs#

xbps-reconfigure -f zfsbootmenu

Prepare for first boot#

Exit the chroot, unmount everything#

exit
umount -n -R /mnt

Export the zpool and reboot#

zpool export zroot
reboot