All of lore.kernel.org
 help / color / mirror / Atom feed
* [patch] Make knetbsd pass the root device
@ 2011-09-20 23:25 Grégoire Sutre
  2011-09-21  9:13 ` Grégoire Sutre
  2011-09-28 17:56 ` Grégoire Sutre
  0 siblings, 2 replies; 5+ messages in thread
From: Grégoire Sutre @ 2011-09-20 23:25 UTC (permalink / raw)
  To: The development of GNU GRUB

[-- Attachment #1: Type: text/plain, Size: 1143 bytes --]

Hi,

The attached patch adds bootdisk and bootwedge to the bootinfo
passed to NetBSD kernels by knetbsd.  These fields indicate to
the kernel which is the root device. The patch sets them to
GRUB's root device.

This way, specifying --root for knetbsd is no longer necessary
for common cases.

Examples:

- Root device is partition f: of the NetBSD label in hd0:
   insmod part_bsd
   set root=(hd0,netbsd6)

- Root device is partition a: of the NetBSD label in hd1 (*):
   insmod part_bsd
   set root=(hd1,netbsd1)

- Root device is first GPT partition of hd1:
   insmod part_gpt
   set root=(hd1,gpt1)
   Here, the NetBSD kernel will detect the root device as a disk
   wedge.

- Root device is 2nd DOS partition of hd0:
   set root=(hd0,msdos2)
   As in the previous case, the kernel will detect the root device
   as a disk wedge (if it is built with the appropriate option).


(*) Assuming that a: is the root partition of the NetBSD slice
contained in, say, (hd1,msdos3), one should specify (hd1,netbsd1)
and not (hd1,msdos3).  The latter would be ignored by the kernel
(or, possibly, detected as a wedge).

Comments welcome.

Grégoire


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: netbsd-btinfo.diff --]
[-- Type: text/x-patch; name="netbsd-btinfo.diff", Size: 5210 bytes --]

=== modified file 'ChangeLog'
--- ChangeLog	2011-09-17 21:40:10 +0000
+++ ChangeLog	2011-09-20 21:37:48 +0000
@@ -1,3 +1,15 @@
+2011-09-20  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-17  Grégoire Sutre  <gregoire.sutre@gmail.com>
 
 	* Makefile.util.def (grub-mkrelpath): Add LIBUTIL for getrawpartition(3)

=== 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-20 21:29:28 +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,84 @@ 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_uint8_t buf[GRUB_DISK_SECTOR_SIZE];
+  grub_uint8_t *hash;
+  grub_uint8_t ctx[GRUB_MD_MD5->contextsize];
+
+  dev = grub_device_open (0);
+  if (! (dev && dev->disk && dev->disk->partition))
+    return;
+
+  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 BSD disklabel.  */
+  label = (struct grub_partition_bsd_disk_label *) &buf;
+  if (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 +1687,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-20 21:23:33 +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-20 21:26:37 +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;


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [patch] Make knetbsd pass the root device
  2011-09-20 23:25 [patch] Make knetbsd pass the root device Grégoire Sutre
@ 2011-09-21  9:13 ` Grégoire Sutre
  2011-09-28 17:56 ` Grégoire Sutre
  1 sibling, 0 replies; 5+ messages in thread
From: Grégoire Sutre @ 2011-09-21  9:13 UTC (permalink / raw)
  To: grub-devel

On 09/21/2011 01:25 AM, Grégoire Sutre wrote:
> +  dev = grub_device_open (0);
> +  if (! (dev&&  dev->disk&&  dev->disk->partition))
> +    return;

This `return' should be a `goto fail'.

Grégoire


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [patch] Make knetbsd pass the root device
  2011-09-20 23:25 [patch] Make knetbsd pass the root device Grégoire Sutre
  2011-09-21  9:13 ` Grégoire Sutre
@ 2011-09-28 17:56 ` Grégoire Sutre
  2011-09-28 20:57   ` Vladimir 'φ-coder/phcoder' Serbinenko
  1 sibling, 1 reply; 5+ messages in thread
From: Grégoire Sutre @ 2011-09-28 17:56 UTC (permalink / raw)
  To: The development of GNU GRUB

[-- Attachment #1: Type: text/plain, Size: 247 bytes --]

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

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: netbsd-btinfo_v2.diff --]
[-- Type: text/x-patch; name="netbsd-btinfo_v2.diff", Size: 5322 bytes --]

=== 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.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

=== 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;


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [patch] Make knetbsd pass the root device
  2011-09-28 17:56 ` Grégoire Sutre
@ 2011-09-28 20:57   ` Vladimir 'φ-coder/phcoder' Serbinenko
  2011-09-28 22:25     ` Grégoire Sutre
  0 siblings, 1 reply; 5+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2011-09-28 20:57 UTC (permalink / raw)
  To: grub-devel

[-- Attachment #1: Type: text/plain, Size: 345 bytes --]

On 28.09.2011 19:56, Grégoire Sutre wrote:
> +  grub_uint64_t buf[(GRUB_DISK_SECTOR_SIZE + 7) / 8];
No need for + 7 since you know that GRUB_DISK_SECTOR_SIZE is divisible
by 8. Other than this patch looks good. Go ahead (I assume that you
checked that it works well with NetBSD)

-- 
Regards
Vladimir 'φ-coder/phcoder' Serbinenko



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 294 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [patch] Make knetbsd pass the root device
  2011-09-28 20:57   ` Vladimir 'φ-coder/phcoder' Serbinenko
@ 2011-09-28 22:25     ` Grégoire Sutre
  0 siblings, 0 replies; 5+ messages in thread
From: Grégoire Sutre @ 2011-09-28 22:25 UTC (permalink / raw)
  To: The development of GNU GRUB

On 09/28/2011 10:57 PM, Vladimir 'φ-coder/phcoder' Serbinenko wrote:
> On 28.09.2011 19:56, Grégoire Sutre wrote:
>> +  grub_uint64_t buf[(GRUB_DISK_SECTOR_SIZE + 7) / 8];
> No need for + 7 since you know that GRUB_DISK_SECTOR_SIZE is divisible
> by 8. Other than this patch looks good. Go ahead

Thanks, committed.

 > (I assume that you checked that it works well with NetBSD)

I made a number of tests, with various partitioning schemes,
mainly with NetBSD -current, but I also made a few with the
latest stable release.

Grégoire


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2011-09-28 22:25 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-09-20 23:25 [patch] Make knetbsd pass the root device Grégoire Sutre
2011-09-21  9:13 ` Grégoire Sutre
2011-09-28 17:56 ` Grégoire Sutre
2011-09-28 20:57   ` Vladimir 'φ-coder/phcoder' Serbinenko
2011-09-28 22:25     ` Grégoire Sutre

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.