Is it possible to boot FreeBSD 14.2 (UEFI + ZFS + GPT) using GRUB2-EFI?
grub-install -vvv see also https://gist.github.com/ykla/9b6de6c8d4eee524840acb9981bf850a
But I saw that Ubuntu supported full-disk ZFS a few years ago, and Ubuntu still uses GRUB2. So I think it should be theoretically possible.
Ubuntu :
Ubuntu 24.10 :
FreeBSD 14.2 RELEASE :
FreeBSD :
# grub-install --target=x86_64-efi --efi-directory=/boot/efi/efi/ --bootloader-id=grub --boot-directory=/boot/ --modules="part_gpt part_msdos bsd zfs"
grub-install: error: relocation 0x4 is not implemented yet.
root@ykla:~ # grub-install --target=x86_64-efi --efi-directory=/boot/efi/efi/ --bootloader-id=grub --boot-directory=/boot/ --modules="part_gpt part_msdos bsd zfs"
Installing for x86_64-efi platform.
grub-install: error: unknown filesystem.
root@ykla:~ # gpart show
=> 40 125829040 nda0 GPT (60G)
40 532480 1 efi (260M)
532520 2008 - free - (1.0M)
534528 4194304 2 freebsd-swap (2.0G)
4728832 121098240 3 freebsd-zfs (58G)
125827072 2008 - free - (1.0M)
grub-install -vvv see also https://gist.github.com/ykla/9b6de6c8d4eee524840acb9981bf850a
But I saw that Ubuntu supported full-disk ZFS a few years ago, and Ubuntu still uses GRUB2. So I think it should be theoretically possible.
Ubuntu :
$ sudo grub-install --target=x86_64-efi --efi-directory=/boot/efi/ --bootloader-id=grub --boot-directory=/boot/
Installing for x86_64-efi platform.
Installation finished. No error reported.
ubuntu@ubuntu-VMware20-1:~$ grub-install --version
grub-install (GRUB) 2.12-5ubuntu5
root@ubuntu-VMware20-1:/home/ubuntu# cat /boot/grub/grub.cfg
#
# DO NOT EDIT THIS FILE
#
# It is automatically generated by grub-mkconfig using templates
# from /etc/grub.d and settings from /etc/default/grub
#
### BEGIN /etc/grub.d/00_header ###
if [ -s $prefix/grubenv ]; then
set have_grubenv=true
load_env
fi
if [ "${initrdfail}" = 2 ]; then
set initrdfail=
elif [ "${initrdfail}" = 1 ]; then
set next_entry="${prev_entry}"
set prev_entry=
save_env prev_entry
if [ "${next_entry}" ]; then
set initrdfail=2
fi
fi
if [ "${next_entry}" ] ; then
set default="${next_entry}"
set next_entry=
save_env next_entry
set boot_once=true
else
set default="0"
fi
if [ x"${feature_menuentry_id}" = xy ]; then
menuentry_id_option="--id"
else
menuentry_id_option=""
fi
export menuentry_id_option
if [ "${prev_saved_entry}" ]; then
set saved_entry="${prev_saved_entry}"
save_env saved_entry
set prev_saved_entry=
save_env prev_saved_entry
set boot_once=true
fi
function savedefault {
if [ -z "${boot_once}" ]; then
saved_entry="${chosen}"
save_env saved_entry
fi
}
function initrdfail {
if [ -n "${have_grubenv}" ]; then if [ -n "${partuuid}" ]; then
if [ -z "${initrdfail}" ]; then
set initrdfail=1
if [ -n "${boot_once}" ]; then
set prev_entry="${default}"
save_env prev_entry
fi
fi
save_env initrdfail
fi; fi
}
function recordfail {
set recordfail=1
# GRUB lacks write support for zfs, so recordfail support is disabled.
}
function load_video {
if [ x$feature_all_video_module = xy ]; then
insmod all_video
else
insmod efi_gop
insmod efi_uga
insmod ieee1275_fb
insmod vbe
insmod vga
insmod video_bochs
insmod video_cirrus
fi
}
if [ x$feature_default_font_path = xy ] ; then
font=unicode
else
insmod part_gpt
insmod zfs
search --no-floppy --fs-uuid --set=root 3dff34677a7c87d9
font="/BOOT/ubuntu_ngje3w@/grub/unicode.pf2"
fi
if loadfont $font ; then
set gfxmode=auto
load_video
insmod gfxterm
fi
terminal_output gfxterm
if [ "${recordfail}" = 1 ] ; then
set timeout=30
else
if [ x$feature_timeout_style = xy ] ; then
set timeout_style=hidden
set timeout=0
# Fallback hidden-timeout code in case the timeout_style feature is
# unavailable.
elif sleep --interruptible 0 ; then
set timeout=0
fi
fi
if [ $grub_platform = efi ]; then
set timeout=30
if [ x$feature_timeout_style = xy ] ; then
set timeout_style=menu
fi
fi
### END /etc/grub.d/00_header ###
### BEGIN /etc/grub.d/05_debian_theme ###
set menu_color_normal=white/black
set menu_color_highlight=black/light-gray
### END /etc/grub.d/05_debian_theme ###
### BEGIN /etc/grub.d/10_linux ###
### END /etc/grub.d/10_linux ###
### BEGIN /etc/grub.d/10_linux_zfs ###
function gfxmode {
set gfxpayload="${1}"
if [ "${1}" = "keep" ]; then
set vt_handoff=vt.handoff=1
else
set vt_handoff=
fi
}
if [ "${recordfail}" != 1 ]; then
if [ -e ${prefix}/gfxblacklist.txt ]; then
if hwmatch ${prefix}/gfxblacklist.txt 3; then
if [ ${match} = 0 ]; then
set linux_gfx_mode=keep
else
set linux_gfx_mode=text
fi
else
set linux_gfx_mode=text
fi
else
set linux_gfx_mode=keep
fi
else
set linux_gfx_mode=text
fi
export linux_gfx_mode
function zsyshistorymenu {
# $1: root dataset (eg rpool/ROOT/ubuntu_2zhm07@autozsys_k56fr6)
# $2: boot device id (eg 411f29ce1557bfed)
# $3: initrd (eg /BOOT/ubuntu_2zhm07@autozsys_k56fr6/initrd.img-5.4.0-21-generic)
# $4: kernel (eg /BOOT/ubuntu_2zhm07@autozsys_k56fr6/vmlinuz-5.4.0-21-generic)
# $5: kernel_version (eg 5.4.0-21-generic)
set root_dataset="${1}"
set boot_device="${2}"
set initrd="${3}"
set kernel="${4}"
set kversion="${5}"
menuentry 'Revert system only' --class ubuntu --class gnu-linux --class gnu --class os ${menuentry_id_option} 'gnulinux-${root_dataset}-${kversion}' {
recordfail
load_video
gfxmode ${linux_gfx_mode}
insmod gzio
if [ "${grub_platform}" = xen ]; then insmod xzio; insmod lzopio; fi
if [ ${boot_device} = /dev/nvme0n1p2 ]; then
insmod part_gpt
insmod zfs
search --no-floppy --fs-uuid --set=root 3dff34677a7c87d9
fi
linux "${kernel}" root=ZFS="${root_dataset}" ro quiet splash crashkernel=2G-4G:320M,4G-32G:512M,32G-64G:1024M,64G-128G:2048M,128G-:4096M ${vt_handoff}
initrd "${initrd}"
}
menuentry 'Revert system and user data' --class ubuntu --class gnu-linux --class gnu --class os ${menuentry_id_option} 'gnulinux-${root_dataset}-${kversion}' {
recordfail
load_video
gfxmode ${linux_gfx_mode}
insmod gzio
if [ "${grub_platform}" = xen ]; then insmod xzio; insmod lzopio; fi
if [ ${boot_device} = /dev/nvme0n1p2 ]; then
insmod part_gpt
insmod zfs
search --no-floppy --fs-uuid --set=root 3dff34677a7c87d9
fi
linux "${kernel}" root=ZFS="${root_dataset}" ro quiet splash crashkernel=2G-4G:320M,4G-32G:512M,32G-64G:1024M,64G-128G:2048M,128G-:4096M ${vt_handoff} zsys-revert=userdata
initrd "${initrd}"
}
menuentry 'Revert system only (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os ${menuentry_id_option} 'gnulinux-${root_dataset}-${kversion}' {
recordfail
load_video
insmod gzio
if [ "${grub_platform}" = xen ]; then insmod xzio; insmod lzopio; fi
if [ ${boot_device} = /dev/nvme0n1p2 ]; then
insmod part_gpt
insmod zfs
search --no-floppy --fs-uuid --set=root 3dff34677a7c87d9
fi
echo Loading Linux ${kversion} ...
linux "${kernel}" root=ZFS="${root_dataset}" ro recovery nomodeset dis_ucode_ldr
echo 'Loading initial ramdisk ...'
initrd "${initrd}"
}
menuentry 'Revert system and user data (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os ${menuentry_id_option} 'gnulinux-${root_dataset}-${kversion}' {
recordfail
load_video
insmod gzio
if [ "${grub_platform}" = xen ]; then insmod xzio; insmod lzopio; fi
if [ ${boot_device} = /dev/nvme0n1p2 ]; then
insmod part_gpt
insmod zfs
search --no-floppy --fs-uuid --set=root 3dff34677a7c87d9
fi
echo Loading Linux ${kversion} ...
linux "${kernel}" root=ZFS="${root_dataset}" ro recovery nomodeset dis_ucode_ldr zsys-revert=userdata
echo 'Loading initial ramdisk ...'
initrd "${initrd}"
}
}
menuentry 'Ubuntu 24.10' --class ubuntu --class gnu-linux --class gnu --class os ${menuentry_id_option} 'gnulinux-rpool/ROOT/ubuntu_ngje3w-6.11.0-8-generic' {
recordfail
load_video
gfxmode ${linux_gfx_mode}
insmod gzio
if [ "${grub_platform}" = xen ]; then insmod xzio; insmod lzopio; fi
insmod part_gpt
insmod zfs
search --no-floppy --fs-uuid --set=root 3dff34677a7c87d9
linux "/BOOT/ubuntu_ngje3w@/vmlinuz-6.11.0-8-generic" root=ZFS="rpool/ROOT/ubuntu_ngje3w" ro quiet splash crashkernel=2G-4G:320M,4G-32G:512M,32G-64G:1024M,64G-128G:2048M,128G-:4096M ${vt_handoff}
initrd "/BOOT/ubuntu_ngje3w@/initrd.img-6.11.0-8-generic"
}
submenu 'Advanced options for Ubuntu 24.10' ${menuentry_id_option} 'gnulinux-advanced-rpool/ROOT/ubuntu_ngje3w' {
menuentry 'Ubuntu 24.10, with Linux 6.11.0-8-generic' --class ubuntu --class gnu-linux --class gnu --class os ${menuentry_id_option} 'gnulinux-rpool/ROOT/ubuntu_ngje3w-6.11.0-8-generic' {
recordfail
load_video
gfxmode ${linux_gfx_mode}
insmod gzio
if [ "${grub_platform}" = xen ]; then insmod xzio; insmod lzopio; fi
insmod part_gpt
insmod zfs
search --no-floppy --fs-uuid --set=root 3dff34677a7c87d9
echo Loading Linux 6.11.0-8-generic ...
linux "/BOOT/ubuntu_ngje3w@/vmlinuz-6.11.0-8-generic" root=ZFS="rpool/ROOT/ubuntu_ngje3w" ro quiet splash crashkernel=2G-4G:320M,4G-32G:512M,32G-64G:1024M,64G-128G:2048M,128G-:4096M ${vt_handoff}
echo 'Loading initial ramdisk ...'
initrd "/BOOT/ubuntu_ngje3w@/initrd.img-6.11.0-8-generic"
}
menuentry 'Ubuntu 24.10, with Linux 6.11.0-8-generic (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os ${menuentry_id_option} 'gnulinux-rpool/ROOT/ubuntu_ngje3w-6.11.0-8-generic' {
recordfail
load_video
insmod gzio
if [ "${grub_platform}" = xen ]; then insmod xzio; insmod lzopio; fi
insmod part_gpt
insmod zfs
search --no-floppy --fs-uuid --set=root 3dff34677a7c87d9
echo Loading Linux 6.11.0-8-generic ...
linux "/BOOT/ubuntu_ngje3w@/vmlinuz-6.11.0-8-generic" root=ZFS="rpool/ROOT/ubuntu_ngje3w" ro recovery nomodeset dis_ucode_ldr
echo 'Loading initial ramdisk ...'
initrd "/BOOT/ubuntu_ngje3w@/initrd.img-6.11.0-8-generic"
}
}
### END /etc/grub.d/10_linux_zfs ###
### BEGIN /etc/grub.d/20_linux_xen ###
### END /etc/grub.d/20_linux_xen ###
### BEGIN /etc/grub.d/20_memtest86+ ###
menuentry "Memory test (memtest86+x64.efi)" --class memtest $menuentry_id_option 'memtest86+' {
insmod part_gpt
insmod zfs
search --no-floppy --fs-uuid --set=root 3dff34677a7c87d9
linux /BOOT/ubuntu_ngje3w@/memtest86+x64.efi
}
menuentry 'Memory test (memtest86+x64.efi, serial console)' --class memtest $menuentry_id_option 'memtest86+-serial' {
insmod part_gpt
insmod zfs
search --no-floppy --fs-uuid --set=root 3dff34677a7c87d9
linux /BOOT/ubuntu_ngje3w@/memtest86+x64.efi console=ttyS0,115200
}
### END /etc/grub.d/20_memtest86+ ###
### BEGIN /etc/grub.d/25_bli ###
if [ "$grub_platform" = "efi" ]; then
insmod bli
fi
### END /etc/grub.d/25_bli ###
### BEGIN /etc/grub.d/30_os-prober ###
### END /etc/grub.d/30_os-prober ###
### BEGIN /etc/grub.d/30_uefi-firmware ###
if [ "$grub_platform" = "efi" ]; then
fwsetup --is-supported
if [ "$?" = 0 ]; then
menuentry 'UEFI Firmware Settings' $menuentry_id_option 'uefi-firmware' {
fwsetup
}
fi
fi
### END /etc/grub.d/30_uefi-firmware ###
### BEGIN /etc/grub.d/35_fwupd ###
### END /etc/grub.d/35_fwupd ###
### BEGIN /etc/grub.d/40_custom ###
# This file provides an easy way to add custom menu entries. Simply type the
# menu entries you want to add after this comment. Be careful not to change
# the 'exec tail' line above.
### END /etc/grub.d/40_custom ###
### BEGIN /etc/grub.d/41_custom ###
if [ -f ${config_directory}/custom.cfg ]; then
source ${config_directory}/custom.cfg
elif [ -z "${config_directory}" -a -f $prefix/custom.cfg ]; then
source $prefix/custom.cfg
fi
### END /etc/grub.d/41_custom ###
Ubuntu 24.10 :
root@ubuntu-VMware20-1:/home/ubuntu# zfs version
zfs-2.2.6-1ubuntu1
zfs-kmod-2.2.6-1ubuntu1
FreeBSD 14.2 RELEASE :
root@ykla:~ # zfs version
zfs-2.2.6-FreeBSD_g33174af15
zfs-kmod-2.2.6-FreeBSD_g33174af15
FreeBSD :
root@ykla:~ # zpool import
pool: bpool
id: 4467346974416078809
state: ONLINE
status: The pool was last accessed by another system.
action: The pool can be imported using its name or numeric identifier and
the '-f' flag.
see: https://openzfs.github.io/openzfs-docs/msg/ZFS-8000-EY
config:
bpool ONLINE
nda1p2 ONLINE
pool: rpool
id: 13973171540959982053
state: ONLINE
status: The pool was last accessed by another system.
action: The pool can be imported using its name or numeric identifier and
the '-f' flag.
see: https://openzfs.github.io/openzfs-docs/msg/ZFS-8000-EY
config:
rpool ONLINE
nda1p4 ONLINE