I've got a system with an oddball, but valid setup that is outside the
bounds of what GRUB supports. As such I'm starting to work on
familiarizing myself with GRUB2's internals on the way to solving the
problem.

I've found two issues worth fixing so far and I'm attaching patches.
First, what is refered to as "a magic number used by Windows NT" is
apparently used as a volume identifier to identify disks. Current
versions of LILO in fact use it to locate the disk holding its second
stage. Second, perhaps minor, but I'm surprised someone chose to break
the checksum verification code in grub-core/partmap/sun.c and didn't
didn't keep the magic number check with it. I hereby release the two
attached patches under GPL version 3 and subsequent varients.

I'm not very familiar with Bazaar, shouldn't be a problem. Does seem git
is taking over from Subversion.


-- 
(\___(\___(\______          --=> 8-) EHM <=--          ______/)___/)___/)
 \BS (    |         e...@gremlin.m5p.com PGP F6B23DE0         |    )   /
  \_CS\   |  _____  -O #include <stddisclaimer.h> O-   _____  |   /  _/
2477\___\_|_/DC21 03A0 5D61 985B <-PGP-> F2BE 6526 ABD2 F6B2\_|_/___/3DE0




-- 
(\___(\___(\______          --=> 8-) EHM <=--          ______/)___/)___/)
 \BS (    |         e...@gremlin.m5p.com PGP F6B23DE0         |    )   /
  \_CS\   |  _____  -O #include <stddisclaimer.h> O-   _____  |   /  _/
2477\___\_|_/DC21 03A0 5D61 985B <-PGP-> F2BE 6526 ABD2 F6B2\_|_/___/3DE0


=== modified file 'grub-core/boot/i386/pc/boot.S'
--- grub-core/boot/i386/pc/boot.S	2010-09-19 22:06:45 +0000
+++ grub-core/boot/i386/pc/boot.S	2010-12-17 04:27:12 +0000
@@ -407,11 +407,13 @@
 	ret
 
 	/*
-	 *  Windows NT breaks compatibility by embedding a magic
-	 *  number here.
+	 *  Windows NT uses this as a 32-bit Volume Id that is unique
+	 *  amoung disks connected to the system and needs to be
+	 *  preserved. LILO acts similarly, using this field to locate
+	 *  the disks with its second stage.
 	 */
 
-	. = _start + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC
+	. = _start + GRUB_BOOT_MACHINE_X86_VOLID
 nt_magic:
 	.long 0
 	.word 0

=== modified file 'include/grub/i386/pc/boot.h'
--- include/grub/i386/pc/boot.h	2010-04-26 08:56:12 +0000
+++ include/grub/i386/pc/boot.h	2010-12-12 06:22:16 +0000
@@ -39,8 +39,8 @@
 /* The offset of BOOT_DRIVE_CHECK.  */
 #define GRUB_BOOT_MACHINE_DRIVE_CHECK	0x66
 
-/* The offset of a magic number used by Windows NT.  */
-#define GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC	0x1b8
+/* The offset of what is used as a Volume Id by Windows NT and LILO.	*/
+#define GRUB_BOOT_MACHINE_X86_VOLID	0x1b8
 
 /* The offset of the start of the partition table.  */
 #define GRUB_BOOT_MACHINE_PART_START	0x1be

=== modified file 'util/grub-setup.c'
--- util/grub-setup.c	2010-11-26 21:03:16 +0000
+++ util/grub-setup.c	2010-12-12 06:19:44 +0000
@@ -396,9 +396,9 @@
 
     /* Copy the partition table.  */
     if (dest_partmap)
-      memcpy (boot_img + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC,
-	      tmp_img + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC,
-	      GRUB_BOOT_MACHINE_PART_END - GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC);
+      memcpy (boot_img + GRUB_BOOT_MACHINE_X86_VOLID,
+	      tmp_img + GRUB_BOOT_MACHINE_X86_VOLID,
+	      GRUB_BOOT_MACHINE_PART_END - GRUB_BOOT_MACHINE_X86_VOLID);
 
     free (tmp_img);
     

=== modified file 'grub-core/partmap/sun.c'
--- grub-core/partmap/sun.c	2010-09-14 19:07:39 +0000
+++ grub-core/partmap/sun.c	2010-12-17 05:04:53 +0000
@@ -67,19 +67,27 @@
 
 static struct grub_partition_map grub_sun_partition_map;
 
-/* Verify checksum (true=ok).  */
-static int
-grub_sun_is_valid (struct grub_sun_block *label)
+/* test whether we're dealing with a valid Sun disklabel */
+static grub_err_t
+grub_sun_test (struct grub_sun_block *label)
 {
   grub_uint16_t *pos;
   grub_uint16_t sum = 0;
 
+  if (GRUB_PARTMAP_SUN_MAGIC != grub_be_to_cpu16 (label->magic))
+    return grub_error (GRUB_ERR_BAD_PART_TABLE, "not a sun partition table");
+
   for (pos = (grub_uint16_t *) label;
        pos < (grub_uint16_t *) (label + 1);
        pos++)
     sum ^= *pos;
 
-  return ! sum;
+  /* Maybe another error value would be better, because partition
+     table _is_ recognized but invalid.  */
+  if (sum)
+    return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid checksum");
+
+  return GRUB_ERR_NONE;
 }
 
 static grub_err_t
@@ -98,14 +106,9 @@
   if (err)
     return err;
 
-  if (GRUB_PARTMAP_SUN_MAGIC != grub_be_to_cpu16 (block.magic))
-    return grub_error (GRUB_ERR_BAD_PART_TABLE, "not a sun partition table");
+  if (GRUB_ERR_NONE != (err = grub_sun_test(&block)))
+    return err;
 
-  if (! grub_sun_is_valid (&block))
-      return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid checksum");
-  
-  /* Maybe another error value would be better, because partition
-     table _is_ recognized but invalid.  */
   for (partnum = 0; partnum < GRUB_PARTMAP_SUN_MAX_PARTS; partnum++)
     {
       struct grub_sun_partition_descriptor *desc;

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

Reply via email to