Bug#585068: Which partitioning schemes should be supported by GRUB?
Colin Watson
cjwatson at ubuntu.com
Mon Jun 14 15:02:52 UTC 2010
On Mon, Jun 14, 2010 at 02:25:39PM +0100, Colin Watson wrote:
> On Mon, Jun 14, 2010 at 08:07:35AM -0500, richardvoigt at gmail.com wrote:
> > Colin Watson wrote:
> > > I can think of an alternative. We do still need grub_install_dos_part
> > > and grub_install_bsd_part for the multiboot trampoline, which is in
> > > assembly, so it's difficult to abandon them altogether. However,
> > > there's no reason we need to use them in make_install_device. How about
> > > we invent a way to encode most of the information in string form in
> > > grub_prefix, while leaving a placeholder for make_install_device to fill
> > > in the disk? There are 64 bytes available for grub_prefix, which should
> > > be plenty. For example, how about the following (with \0 standing for
> > > ASCII NUL):
> > >
> > > (\0,msdos1,bsd1)/boot/grub
> > >
> > > It's then just a matter of spotting the "(\0," sequence and replacing
> > > the \0 with the drive name. I think this can probably be done using
> > > less code than the first option above, and all told it feels a bit less
> > > hacky to me.
> >
> > Instead of doing string replacement, why not just define a
> > disk-relative partition format?
>
> Simple string replacement would be much easier to implement, and
> probably smaller. Plus, we don't need disk-relative device naming
> elsewhere, and I think it would require putting platform-specific code
> (otherwise how do you know which disk to be relative to?) in places that
> are otherwise pretty platform-independent.
>
> > Also, the '\0' seems unnecessary. Is having "(," meaningful in some
> > way already?
>
> Good point. This would be sufficient.
How about the following patch, implementing this proposal? I've tested this
with Debian GNU/kFreeBSD, and it's enough to make the boot loader work again
out of the box after grub-install. The 'root' variable is still wrong, but
that isn't particularly urgent as UUIDs usually take care of that.
The kernel.img size increase is 84 bytes, yielding a core.img size
increase of 50 bytes in this configuration (22932 -> 22982 bytes). Do I
need to work on making that smaller somehow? It seems tolerable to me.
2010-06-14 Colin Watson <cjwatson at ubuntu.com>
Fix i386-pc prefix handling with nested partitions (Debian bug
#585068).
* kern/i386/pc/init.c (make_install_device): If the prefix starts
with "(,", fill the boot drive in between those two characters, but
expect that a full partition specification including partition map
names will follow.
* util/i386/pc/grub-setup.c (setup): Unless an explicit prefix was
specified, write a prefix without the drive name but including a
full partition specification.
=== modified file 'kern/i386/pc/init.c'
--- kern/i386/pc/init.c 2010-05-21 18:08:48 +0000
+++ kern/i386/pc/init.c 2010-06-14 14:44:13 +0000
@@ -83,6 +83,14 @@ make_install_device (void)
grub_snprintf (ptr, sizeof (dev) - (ptr - dev), ")%s", grub_prefix);
grub_strcpy (grub_prefix, dev);
}
+ else if (grub_prefix[1] == ',')
+ {
+ /* We have a prefix, but still need to fill in the boot drive. */
+ grub_snprintf (dev, sizeof (dev),
+ "(%cd%u%s", (grub_boot_drive & 0x80) ? 'h' : 'f',
+ grub_boot_drive & 0x7f, grub_prefix + 1);
+ grub_strcpy (grub_prefix, dev);
+ }
return grub_prefix;
}
=== modified file 'util/i386/pc/grub-setup.c'
--- util/i386/pc/grub-setup.c 2010-06-11 20:31:16 +0000
+++ util/i386/pc/grub-setup.c 2010-06-14 14:45:24 +0000
@@ -99,6 +99,7 @@ setup (const char *dir,
struct grub_boot_blocklist *first_block, *block;
grub_int32_t *install_dos_part, *install_bsd_part;
grub_int32_t dos_part, bsd_part;
+ char *prefix;
char *tmp_img;
int i;
grub_disk_addr_t first_sector;
@@ -230,6 +231,8 @@ setup (const char *dir,
+ GRUB_KERNEL_MACHINE_INSTALL_DOS_PART);
install_bsd_part = (grub_int32_t *) (core_img + GRUB_DISK_SECTOR_SIZE
+ GRUB_KERNEL_MACHINE_INSTALL_BSD_PART);
+ prefix = (char *) (core_img + GRUB_DISK_SECTOR_SIZE +
+ GRUB_KERNEL_MACHINE_PREFIX);
/* Open the root device and the destination device. */
root_dev = grub_device_open (root);
@@ -289,21 +292,45 @@ setup (const char *dir,
override the current setting. */
if (*install_dos_part != -2)
{
+ grub_partition_t root_part = root_dev->disk->partition;
+
/* Embed information about the installed location. */
- if (root_dev->disk->partition)
+ if (root_part)
{
- if (root_dev->disk->partition->parent)
+ char *new_prefix;
+
+ if (root_part->parent)
{
- if (root_dev->disk->partition->parent->parent)
+ if (root_part->parent->parent)
grub_util_error ("Installing on doubly nested partitions is "
"not supported");
- dos_part = root_dev->disk->partition->parent->number;
- bsd_part = root_dev->disk->partition->number;
+ dos_part = root_part->parent->number;
+ bsd_part = root_part->number;
+
+ if (prefix[0] != '(')
+ {
+ new_prefix = xasprintf ("(,%s%d,%s%d)%s",
+ root_part->parent->partmap->name,
+ root_part->parent->number + 1,
+ root_part->partmap->name,
+ root_part->number + 1,
+ prefix);
+ strcpy (prefix, new_prefix);
+ }
}
else
{
- dos_part = root_dev->disk->partition->number;
+ dos_part = root_part->number;
bsd_part = -1;
+
+ if (prefix[0] != '(')
+ {
+ new_prefix = xasprintf ("(,%s%d)%s",
+ root_part->partmap->name,
+ root_part->number + 1,
+ prefix);
+ strcpy (prefix, new_prefix);
+ }
}
}
else
Thanks,
--
Colin Watson [cjwatson at ubuntu.com]
More information about the Pkg-grub-devel
mailing list