Following Vladimir's comments on IRC, here is the second version of the
patch.

- Make sure that buffers are well-aligned.
- Check that partmap->name is "netbsd".
  (I kept the magic test since it's cheap, but I won't fight over it :-)

Grégoire
=== modified file 'ChangeLog'
--- ChangeLog	2011-09-28 14:43:00 +0000
+++ ChangeLog	2011-09-28 16:33:40 +0000
@@ -1,3 +1,15 @@
+2011-09-28  Grégoire Sutre  <gregoire.su...@gmail.com>
+
+	* include/grub/bsdlabel.h (grub_partition_bsd_disk_label): Add fields
+	type and packname.
+	* include/grub/i386/netbsd_bootinfo.h (NETBSD_BTINFO_BOOTDISK):
+	Resurrected.
+	(NETBSD_BTINFO_BOOTWEDGE): New definition.
+	(grub_netbsd_btinfo_bootwedge): New struct.
+	* grub-core/loader/i386/bsd.c (grub_netbsd_add_boot_disk_and_wedge):
+	New function.
+	(grub_cmd_netbsd): Call grub_netbsd_add_boot_disk_and_wedge.
+
 2011-09-28  Thomas Haller <thomas.hal...@fen-net.de>
 
 	* grub-core/loader/multiboot_elfxx.c (Elf_Shdr): Set according to

=== modified file 'grub-core/loader/i386/bsd.c'
--- grub-core/loader/i386/bsd.c	2011-06-27 11:57:03 +0000
+++ grub-core/loader/i386/bsd.c	2011-09-28 16:16:06 +0000
@@ -33,6 +33,8 @@
 #include <grub/extcmd.h>
 #include <grub/i18n.h>
 #include <grub/ns8250.h>
+#include <grub/bsdlabel.h>
+#include <grub/crypto.h>
 
 GRUB_MOD_LICENSE ("GPLv3+");
 
@@ -946,6 +948,86 @@ grub_netbsd_add_modules (void)
   return err;
 }
 
+/*
+ * Adds NetBSD bootinfo bootdisk and bootwedge.  The partition identified
+ * in these bootinfo fields is the root device.
+ */
+static void
+grub_netbsd_add_boot_disk_and_wedge (void)
+{
+  grub_device_t dev;
+  grub_disk_t disk;
+  grub_partition_t part;
+  grub_uint32_t biosdev;
+  grub_uint32_t partmapsector;
+  struct grub_partition_bsd_disk_label *label;
+  grub_uint64_t buf[(GRUB_DISK_SECTOR_SIZE + 7) / 8];
+  grub_uint8_t *hash;
+  grub_uint64_t ctx[(GRUB_MD_MD5->contextsize + 7) / 8];
+
+  dev = grub_device_open (0);
+  if (! (dev && dev->disk && dev->disk->partition))
+    goto fail;
+
+  disk = dev->disk;
+  part = disk->partition;
+
+  if (disk->dev && disk->dev->id == GRUB_DISK_DEVICE_BIOSDISK_ID)
+    biosdev = (grub_uint32_t) disk->id & 0xff;
+  else
+    biosdev = 0xff;
+
+  /* Absolute sector of the partition map describing this partition.  */
+  partmapsector = grub_partition_get_start (part->parent) + part->offset;
+
+  disk->partition = part->parent;
+  if (grub_disk_read (disk, part->offset, 0, GRUB_DISK_SECTOR_SIZE, buf) != GRUB_ERR_NONE)
+    goto fail;
+  disk->partition = part;
+
+  /* Fill bootwedge.  */
+  {
+    struct grub_netbsd_btinfo_bootwedge biw;
+
+    grub_memset (&biw, 0, sizeof (biw));
+    biw.biosdev = biosdev;
+    biw.startblk = grub_partition_get_start (part);
+    biw.nblks = part->len;
+    biw.matchblk = partmapsector;
+    biw.matchnblks = 1;
+
+    GRUB_MD_MD5->init (&ctx);
+    GRUB_MD_MD5->write (&ctx, buf, GRUB_DISK_SECTOR_SIZE);
+    GRUB_MD_MD5->final (&ctx);
+    hash = GRUB_MD_MD5->read (&ctx);
+    memcpy (biw.matchhash, hash, 16);
+
+    grub_bsd_add_meta (NETBSD_BTINFO_BOOTWEDGE, &biw, sizeof (biw));
+  }
+
+  /* Fill bootdisk if this a NetBSD disk label.  */
+  label = (struct grub_partition_bsd_disk_label *) &buf;
+  if (part->partmap != NULL &&
+      (grub_strcmp (part->partmap->name, "netbsd") == 0) &&
+      label->magic == grub_cpu_to_le32 (GRUB_PC_PARTITION_BSD_LABEL_MAGIC))
+    {
+      struct grub_netbsd_btinfo_bootdisk bid;
+
+      grub_memset (&bid, 0, sizeof (bid));
+      bid.labelsector = partmapsector;
+      bid.label.type = label->type;
+      bid.label.checksum = label->checksum;
+      memcpy (bid.label.packname, label->packname, 16);
+      bid.biosdev = biosdev;
+      bid.partition = part->number;
+      grub_bsd_add_meta (NETBSD_BTINFO_BOOTDISK, &bid, sizeof (bid));
+    }
+
+fail:
+  if (dev)
+    grub_device_close (dev);
+}
+
 static grub_err_t
 grub_netbsd_boot (void)
 {
@@ -1607,6 +1689,8 @@ grub_cmd_netbsd (grub_extcmd_context_t c
 	  grub_bsd_add_meta (NETBSD_BTINFO_CONSOLE, &cons, sizeof (cons));
 	}
 
+      grub_netbsd_add_boot_disk_and_wedge ();
+
       grub_loader_set (grub_netbsd_boot, grub_bsd_unload, 0);
     }
 

=== modified file 'include/grub/bsdlabel.h'
--- include/grub/bsdlabel.h	2010-07-16 23:57:48 +0000
+++ include/grub/bsdlabel.h	2011-09-28 15:06:02 +0000
@@ -80,7 +80,10 @@ struct grub_partition_bsd_entry
 struct grub_partition_bsd_disk_label
 {
   grub_uint32_t magic;
-  grub_uint8_t padding[128];
+  grub_uint16_t type;
+  grub_uint8_t unused1[18];
+  grub_uint8_t packname[16];
+  grub_uint8_t unused2[92];
   grub_uint32_t magic2;
   grub_uint16_t checksum;
   grub_uint16_t num_partitions;

=== modified file 'include/grub/i386/netbsd_bootinfo.h'
--- include/grub/i386/netbsd_bootinfo.h	2010-01-18 22:37:11 +0000
+++ include/grub/i386/netbsd_bootinfo.h	2011-09-28 15:06:02 +0000
@@ -51,9 +51,11 @@
 
 #define NETBSD_BTINFO_BOOTPATH		0
 #define NETBSD_BTINFO_ROOTDEVICE	1
+#define NETBSD_BTINFO_BOOTDISK		3
 #define NETBSD_BTINFO_CONSOLE		6
 #define NETBSD_BTINFO_SYMTAB		8
 #define NETBSD_BTINFO_MEMMAP		9
+#define NETBSD_BTINFO_BOOTWEDGE		10
 #define NETBSD_BTINFO_MODULES		11
 #define NETBSD_BTINFO_FRAMEBUF		12
 
@@ -83,6 +85,15 @@ struct grub_netbsd_btinfo_bootdisk
   grub_uint32_t partition;
 };
 
+struct grub_netbsd_btinfo_bootwedge {
+  grub_uint32_t biosdev;
+  grub_disk_addr_t startblk;
+  grub_uint64_t nblks;
+  grub_disk_addr_t matchblk;
+  grub_uint64_t matchnblks;
+  grub_uint8_t matchhash[16];  /* MD5 hash */
+} __packed;
+
 struct grub_netbsd_btinfo_symtab
 {
   grub_uint32_t nsyms;

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to