]> git.proxmox.com Git - grub2.git/commitdiff
Make knetbsd pass bootinfo bootdisk and bootwedge.
authorGrégoire Sutre <gregoire.sutre@gmail.com>
Wed, 28 Sep 2011 21:45:57 +0000 (23:45 +0200)
committerGrégoire Sutre <gregoire.sutre@gmail.com>
Wed, 28 Sep 2011 21:45:57 +0000 (23:45 +0200)
ChangeLog
grub-core/loader/i386/bsd.c
include/grub/bsdlabel.h
include/grub/i386/netbsd_bootinfo.h

index d415a4bcd4afac6e792717ef9f26786014714f06..8cdd158cd45b30bc61402db8a3f6e3fe0ecc09f8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2011-09-28  Grégoire Sutre  <gregoire.sutre@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.haller@fen-net.de>
 
        * grub-core/loader/multiboot_elfxx.c (Elf_Shdr): Set according to
index dffe482579f19e2e1633a4e3d43b52d642da1662..18ebeb760be9194ee49afba1d4fd0053dfb84505 100644 (file)
@@ -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 / 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 ctxt, int argc, char *argv[])
          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);
     }
 
index 636bd41a188a09b47558e6d3347b2158b2b33315..b10336c0100e8a19c5d6d8756559ee6720abb68c 100644 (file)
@@ -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;
index fd429a2515f306229f4a9a9778df47fba05e017e..228f26aaa17c4babf68fce572ddc427de53ceecc 100644 (file)
 
 #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;