# HG changeset patch # User Navdeep Parhar # Date 1305762910 25200 # Node ID dc63f558fb17dffb0ec99c909983ad607096d205 # Parent c18f2a251b7d764f379fb5647ca9b598fe21e5ab Pass in the guid of the root ZFS pool to kfreebsd. The FreeBSD loader can be a kfreebsd even without this patch but it won't be able to load the kernel as it wouldn't know which pool to look for it in. # Example entry in grub.cfg (fbsd9 is the name of the root ZFS pool). menuentry "FreeBSD 9" { search -s -l fbsd9 kfreebsd -D /@/boot/zfsloader } diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c --- a/grub-core/loader/i386/bsd.c +++ b/grub-core/loader/i386/bsd.c @@ -65,6 +65,7 @@ static grub_addr_t entry, entry_hi, kern_start, kern_end; static void *kern_chunk_src; static grub_uint32_t bootflags; +static grub_uint64_t zpool_guid = 0; static int is_elf_kernel, is_64bit; static grub_uint32_t openbsd_root; static struct grub_relocator *relocator = NULL; @@ -741,9 +742,9 @@ stack[0] = entry; /* "Return" address. */ stack[1] = bootflags | FREEBSD_RB_BOOTINFO; stack[2] = freebsd_bootdev; - stack[3] = 0; - stack[4] = 0; - stack[5] = 0; + stack[3] = zpool_guid ? 4 : 0; + *(grub_uint64_t *)&stack[4] = zpool_guid; + /* stack[5] = 0; */ stack[6] = stack_target + 9 * sizeof (grub_uint32_t); stack[7] = bi.tags; stack[8] = kern_end; @@ -1064,6 +1065,7 @@ kernel_type = KERNEL_TYPE_NONE; grub_dl_unref (my_mod); + zpool_guid = 0; grub_relocator_unload (relocator); relocator = NULL; @@ -1362,6 +1364,31 @@ return result; } +static void +grub_fetch_zpool_guid(void) +{ + grub_device_t dev; + grub_fs_t fs; + char *uuid = NULL; + + dev = grub_device_open (NULL); + if (! dev) + return; + + fs = grub_fs_probe (dev); + if (! fs) + return; + + if (grub_strcmp(fs->name, "zfs") != 0 || + ! fs->uuid || fs->uuid (dev, &uuid) || !uuid) + return; + + zpool_guid = grub_strtoull(uuid, NULL, 16); + + grub_free (uuid); +} + + static grub_err_t grub_cmd_freebsd (grub_extcmd_context_t ctxt, int argc, char *argv[]) { @@ -1420,6 +1447,7 @@ (unit << FREEBSD_B_UNITSHIFT) + (part << FREEBSD_B_PARTSHIFT)); grub_loader_set (grub_freebsd_boot, grub_bsd_unload, 0); + grub_fetch_zpool_guid(); } return grub_errno;