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