Currently grub2 tries to guess root device name in OS notation basing
on BIOS number. This fails in multiple cases. This patch lets user
specify root device.

-- 
Regards
Vladimir 'phcoder' Serbinenko

Personal git repository: http://repo.or.cz/w/grub2/phcoder.git
diff --git a/ChangeLog b/ChangeLog
index a00842c..04e2e17 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
 2009-08-23  Vladimir Serbinenko  <phco...@gmail.com>
 
+       Let user specify NetBSD root device.
+
+       * loader/i386/bsd.c (netbsd_root): New variable.
+       (netbsd_opts): New option 'root'.
+       (NETBSD_ROOT_ARG): New macro.
+       (grub_netbsd_boot): Use 'netbsd_root'.
+       (grub_bsd_unload): Free 'netbsd_root'.
+       (grub_cmd_netbsd): Fill 'netbsd_root'.
+
+2009-08-23  Vladimir Serbinenko  <phco...@gmail.com>
+
        * commands/search.c (search_fs): Try searching without autoload first.
        * util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Load
        filesystem module explicitly for faster booting.
diff --git a/loader/i386/bsd.c b/loader/i386/bsd.c
index d5f677a..adfe8a0 100644
--- a/loader/i386/bsd.c
+++ b/loader/i386/bsd.c
@@ -56,6 +56,7 @@ static grub_uint32_t bootflags;
 static char *mod_buf;
 static grub_uint32_t mod_buf_len, mod_buf_max, kern_end_mdofs;
 static int is_elf_kernel, is_64bit;
+static char *netbsd_root = 0;
 
 static const struct grub_arg_option freebsd_opts[] =
   {
@@ -113,6 +114,7 @@ static const struct grub_arg_option netbsd_opts[] =
     {"verbose", 'v', 0, "Boot with verbose messages.", 0, 0},
     {"debug", 'x', 0, "Boot with debug messages.", 0, 0},
     {"silent", 'z', 0, "Supress normal output (warnings remain).", 0, 0},
+    {"root", 'r', 0, "Set root device.", "DEVICE", ARG_TYPE_STRING},
     {0, 0, 0, 0, 0, 0}
   };
 
@@ -124,6 +126,8 @@ static const grub_uint32_t netbsd_flags[] =
   NETBSD_AB_SILENT, 0
 };
 
+#define NETBSD_ROOT_ARG (ARRAY_SIZE (netbsd_flags) - 1)
+
 static void
 grub_bsd_get_device (grub_uint32_t * biosdev,
                     grub_uint32_t * unit,
@@ -605,22 +609,35 @@ grub_openbsd_boot (void)
 static grub_err_t
 grub_netbsd_boot (void)
 {
-  struct grub_netbsd_btinfo_rootdevice *rootdev;
   struct grub_netbsd_bootinfo *bootinfo;
   grub_uint32_t biosdev, unit, slice, part;
 
   grub_bsd_get_device (&biosdev, &unit, &slice, &part);
 
-  rootdev = (struct grub_netbsd_btinfo_rootdevice *) GRUB_BSD_TEMP_BUFFER;
+  if (kern_end + sizeof (struct grub_netbsd_btinfo_rootdevice)
+      + sizeof (struct grub_netbsd_bootinfo) > grub_os_area_addr
+      + grub_os_area_size)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "No memory fo boot info.");
+
+  if (netbsd_root)
+    {
+      struct grub_netbsd_btinfo_rootdevice *rootdev;
 
-  rootdev->common.len = sizeof (struct grub_netbsd_btinfo_rootdevice);
-  rootdev->common.type = NETBSD_BTINFO_ROOTDEVICE;
-  grub_sprintf (rootdev->devname, "%cd%d%c", (biosdev & 0x80) ? 'w' : 'f',
-               unit, 'a' + part);
+      rootdev = (struct grub_netbsd_btinfo_rootdevice *) kern_end;
 
-  bootinfo = (struct grub_netbsd_bootinfo *) (rootdev + 1);
-  bootinfo->bi_count = 1;
-  bootinfo->bi_data[0] = rootdev;
+      rootdev->common.len = sizeof (struct grub_netbsd_btinfo_rootdevice);
+      rootdev->common.type = NETBSD_BTINFO_ROOTDEVICE;
+      grub_strncpy (rootdev->devname, netbsd_root, sizeof (rootdev->devname));
+
+      bootinfo = (struct grub_netbsd_bootinfo *) (rootdev + 1);
+      bootinfo->bi_count = 1;
+      bootinfo->bi_data[0] = rootdev;
+    }
+  else
+    {
+      bootinfo = (struct grub_netbsd_bootinfo *) kern_end;
+      bootinfo->bi_count = 0;
+    }
 
   grub_unix_real_boot (entry, bootflags, 0, bootinfo,
                       0, grub_mmap_get_upper () >> 10,
@@ -643,6 +660,9 @@ grub_bsd_unload (void)
   kernel_type = KERNEL_TYPE_NONE;
   grub_dl_unref (my_mod);
 
+  grub_free (netbsd_root);
+  netbsd_root = 0;
+
   return GRUB_ERR_NONE;
 }
 
@@ -923,7 +943,11 @@ grub_cmd_netbsd (grub_extcmd_t cmd, int argc, char *argv[])
   bootflags = grub_bsd_parse_flags (cmd->state, netbsd_flags);
 
   if (grub_bsd_load (argc, argv) == GRUB_ERR_NONE)
-    grub_loader_set (grub_netbsd_boot, grub_bsd_unload, 1);
+    {
+      grub_loader_set (grub_netbsd_boot, grub_bsd_unload, 1);
+      if (cmd->state[NETBSD_ROOT_ARG].set)
+       netbsd_root = grub_strdup (cmd->state[NETBSD_ROOT_ARG].arg);
+    }
 
   return grub_errno;
 }
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to