From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with archive (Exim 4.43) id 1OP3GW-0006X9-JG for mharc-grub-devel@gnu.org; Wed, 16 Jun 2010 20:47:32 -0400 Received: from [140.186.70.92] (port=45599 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OP3GR-0006VV-H0 for grub-devel@gnu.org; Wed, 16 Jun 2010 20:47:31 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OP3GM-0006Ir-QC for grub-devel@gnu.org; Wed, 16 Jun 2010 20:47:27 -0400 Received: from fg-out-1718.google.com ([72.14.220.159]:45757) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OP3GM-0006Ig-Ib for grub-devel@gnu.org; Wed, 16 Jun 2010 20:47:22 -0400 Received: by fg-out-1718.google.com with SMTP id d23so1462989fga.12 for ; Wed, 16 Jun 2010 17:47:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from :user-agent:mime-version:to:subject:references:in-reply-to :x-enigmail-version:content-type; bh=gL2HsyYN5ANKb9FZV3Mqmdp4uVNwDObEvaK3N3bg6zQ=; b=tDspuYwL4uOHctx+/jQLrzHedWpFhUazWUJxQMtui9tc5Le6ZbdDVCmPGxWft9MvQA Fk0gfMDCR0ZjTlWDLK9UiMRPBHVHEPFSFGQ03/lf1b+dcNlRq1LM79ivXBC5GGpVhUNN s+sMFMk0w0G7KS9H1ASqt7fHnl0oBAvLapV48= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:user-agent:mime-version:to:subject:references :in-reply-to:x-enigmail-version:content-type; b=V4HkjMYbxZ1O+flnu6VdHtSR4TAUmJka5rDEQXgxeU384xaKZTtCiJmXzuZwirWSEM BL0N62HsMKTzeT9a1efFEfsCsNry6A5RsFkBYCi7RxxJ2JJUftfxNM8jcEBhzCm+SQh2 xgswa5nkr4i+gyLDt2FuNmk1vTZ9rg8JPOtgc= Received: by 10.87.62.17 with SMTP id p17mr1070864fgk.30.1276735640556; Wed, 16 Jun 2010 17:47:20 -0700 (PDT) Received: from debian.bg45.phnet ([81.62.41.67]) by mx.google.com with ESMTPS id e11sm13478337fga.18.2010.06.16.17.47.19 (version=TLSv1/SSLv3 cipher=RC4-MD5); Wed, 16 Jun 2010 17:47:19 -0700 (PDT) Message-ID: <4C19708F.8000006@gmail.com> Date: Thu, 17 Jun 2010 02:47:11 +0200 From: =?UTF-8?B?VmxhZGltaXIgJ8+GLWNvZGVyL3BoY29kZXInIFNlcmJpbmVua28=?= User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.9) Gecko/20100515 Icedove/3.0.4 MIME-Version: 1.0 To: grub-devel@gnu.org References: <4C13B6A8.7060102@gmail.com> <4C13C33B.4090302@gmail.com> <4C15044D.9050608@gmail.com> <20100614113702.GN21862@riva.ucam.org> <20100614132536.GO21862@riva.ucam.org> <20100614150251.GA19053@riva.ucam.org> <4C1651BF.9010306@gmail.com> <20100614164310.GQ21862@riva.ucam.org> <4C166306.2030405@gmail.com> <20100615112111.GW21862@riva.ucam.org> In-Reply-To: <20100615112111.GW21862@riva.ucam.org> X-Enigmail-Version: 1.0.1 Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="------------enig0CB9EE615F363A190934FCCD" X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) Subject: Re: Which partitioning schemes should be supported by GRUB? X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: The development of GNU GRUB List-Id: The development of GNU GRUB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 17 Jun 2010 00:47:31 -0000 This is an OpenPGP/MIME signed message (RFC 2440 and 3156) --------------enig0CB9EE615F363A190934FCCD Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable On 06/15/2010 01:21 PM, Colin Watson wrote: > On Mon, Jun 14, 2010 at 07:12:38PM +0200, Gr=C3=A9goire Sutre wrote: > =20 >> On 06/14/2010 18:43, Colin Watson wrote: >> =20 >>> Do you have any suggestions on how to deal with that? I'm not famili= ar >>> with multiboot and need guidance. >>> =20 >> A possible solution would be to use the multiboot-command line. AFAIK= , >> the boot_device field of the multiboot information structure is suppos= ed >> to pass this kind of partition information, but you cannot specify the= >> partmaps in this field, hence its interpretation is ambiguous. >> =20 > That would potentially allow a user to override things, but doesn't hel= p > with users who don't change their configuration. Unless the user > explicitly configures things, boot_device is all we've got. > > =20 Apparently multiboot part has revealed to be a bit more tricky due to heterogenity. Go ahead with non-multiboot part, I'll review multiboot part separately (need to think about it a bit) > Thus, I guess we end up with a two-part fix: > > 1) Honour key=3Dvalue pairs in the multiboot command line when bootin= g > GRUB itself as a multiboot image. These would simply become > environment variables. Presumably this goes in grub_machine_init,= > by analogy with kern/ieee1275/init.c. This allows users to > override the prefix on the command line as if they had changed the= > image itself. > > 2) If multiboot_trampoline needs to change install_dos_part or > install_bsd_part based on the value of boot_device in the MBI, the= n > we know that the drive/partition part of prefix (which was > calculated in the same way as install_dos_part and install_bsd_par= t > when grub-setup was run) is now invalid and should be ignored. > This fact needs to be passed on to make_install_device. > > Something like this? I'm afraid I have no idea how to test this (GRUB'= s > multiboot command doesn't seem to accept command-line arguments?), not > to mention that this is the first time I've been anywhere near most of > this code. I would greatly appreciate advice and review. > > 2010-06-15 Colin Watson > > Fix i386-pc prefix handling with nested partitions (Debian bug > #585068). > > * include/grub/i386/pc/kernel.h (grub_multiboot_change_prefix): New > declaration. > * kern/i386/pc/startup.S (multiboot_entry): Save a pointer to the > MBI in startup_multiboot_info. > (multiboot_trampoline): If the new partition numbers differ from the > previous ones, then set grub_multiboot_change_prefix. > (grub_multiboot_change_prefix): New definition. > * kern/i386/pc/init.c (make_install_device): Invalidate any > drive/partition part of the prefix if grub_multiboot_change_prefix > is set. After that, 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. > (grub_parse_multiboot_cmdline): New function. > (grub_machine_init): If we have an MBI, copy it, then call > grub_parse_multiboot_cmdline. > * 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. > > =3D=3D=3D modified file 'include/grub/i386/pc/kernel.h' > --- include/grub/i386/pc/kernel.h 2010-04-26 19:11:16 +0000 > +++ include/grub/i386/pc/kernel.h 2010-06-15 11:02:34 +0000 > @@ -44,6 +44,10 @@ extern grub_int32_t grub_install_bsd_par > /* The boot BIOS drive number. */ > extern grub_uint8_t EXPORT_VAR(grub_boot_drive); > =20 > +/* Set if multiboot changed the partition numbers, so grub_prefix is n= ow > + invalid. */ > +extern grub_uint8_t grub_multiboot_change_prefix; > + > #endif /* ! ASM_FILE */ > =20 > #endif /* ! KERNEL_MACHINE_HEADER */ > > =3D=3D=3D 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-15 11:06:20 +0000 > @@ -32,6 +32,7 @@ > #include > #include > #include > +#include > =20 > struct mem_region > { > @@ -47,12 +48,29 @@ static int num_regions; > grub_addr_t grub_os_area_addr; > grub_size_t grub_os_area_size; > =20 > +/* A pointer to the MBI in its initial location. */ > +struct multiboot_info *startup_multiboot_info =3D NULL; > + > +/* The MBI has to be copied to our BSS so that it won't be > + overwritten. This is its final location. */ > +static struct multiboot_info kern_multiboot_info; > + > static char * > make_install_device (void) > { > /* XXX: This should be enough. */ > char dev[100], *ptr =3D dev; > =20 > + if (grub_prefix[0] =3D=3D '(' && grub_multiboot_change_prefix) > + { > + /* The multiboot information invalidated our hardcoded prefix be= cause > + partition numbers differed. Eliminate the drive/partition pa= rt of > + the prefix, if possible. */ > + char *ket =3D grub_strchr (grub_prefix, ')'); > + if (ket) > + grub_memmove (grub_prefix, ket + 1, grub_strlen (ket)); > + } > + > if (grub_prefix[0] !=3D '(') > { > /* No hardcoded root partition - make it from the boot drive and= the > @@ -83,6 +101,14 @@ make_install_device (void) > grub_snprintf (ptr, sizeof (dev) - (ptr - dev), ")%s", grub_pref= ix); > grub_strcpy (grub_prefix, dev); > } > + else if (grub_prefix[1] =3D=3D ',' || grub_prefix[1] =3D=3D ')') > + { > + /* 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); > + } > =20 > return grub_prefix; > } > @@ -134,6 +160,45 @@ compact_mem_regions (void) > } > } > =20 > +static void > +grub_parse_multiboot_cmdline (void) > +{ > + char *cmdline; > + char *p; > + > + if (! (kern_multiboot_info.flags & MULTIBOOT_INFO_CMDLINE)) > + return; > + > + p =3D cmdline =3D grub_strdup ((char *) kern_multiboot_info.cmdline)= ; > + > + while (*p) > + { > + char *command =3D p; > + char *end; > + char *val; > + > + end =3D grub_strchr (command, ' '); > + if (end) > + { > + *end =3D '\0'; > + p =3D end + 1; > + while (*p =3D=3D ' ') > + ++p; > + } > + > + /* Process command. */ > + val =3D grub_strchr (command, '=3D'); > + if (val) > + { > + *val =3D '\0'; > + grub_env_set (command, val + 1); > + > + if (grub_strcmp (command, "prefix") =3D=3D 0) > + grub_multiboot_change_prefix =3D 0; > + } > + } > +} > + > void > grub_machine_init (void) > { > @@ -214,6 +279,15 @@ grub_machine_init (void) > if (! grub_os_area_addr) > grub_fatal ("no upper memory"); > =20 > + if (startup_multiboot_info) > + { > + /* Move MBI to a safe place. */ > + grub_memmove (&kern_multiboot_info, startup_multiboot_info, > + sizeof (struct multiboot_info)); > + > + grub_parse_multiboot_cmdline (); > + } > + > grub_tsc_init (); > } > =20 > > =3D=3D=3D modified file 'kern/i386/pc/startup.S' > --- kern/i386/pc/startup.S 2010-04-05 13:59:32 +0000 > +++ kern/i386/pc/startup.S 2010-06-15 11:02:19 +0000 > @@ -142,6 +142,8 @@ multiboot_header: > =20 > multiboot_entry: > .code32 > + movl %ebx, EXT_C(startup_multiboot_info) > + > /* obtain the boot device */ > movl 12(%ebx), %edx > =20 > @@ -161,20 +163,38 @@ multiboot_entry: > jmp *%eax > =20 > multiboot_trampoline: > + /* remember the original boot information */ > + movl EXT_C(grub_install_dos_part), %eax > + orl %eax, %eax > + jns 1f > + movb $0xFF, %al > +1: > + movl EXT_C(grub_install_bsd_part), %ebx > + orl %ebx, %ebx > + jns 2f > + movb $0xFF, %bl > +2: > + movb %al, %bh > + > /* fill the boot information */ > movl %edx, %eax > shrl $8, %eax > + cmpw %ax, %bx > + je 3f > + /* doesn't match the original */ > + movb $1, EXT_C(grub_multiboot_change_prefix) > +3: > xorl %ebx, %ebx > cmpb $0xFF, %ah > - je 1f > + je 4f > movb %ah, %bl > movl %ebx, EXT_C(grub_install_dos_part) > -1: > +4: > cmpb $0xFF, %al > - je 2f > + je 5f > movb %al, %bl > movl %ebx, EXT_C(grub_install_bsd_part) > -2: > +5: > shrl $24, %edx > movb $0xFF, %dh > /* enter the usual booting */ > @@ -285,6 +305,8 @@ LOCAL (codestart): > =20 > VARIABLE(grub_boot_drive) > .byte 0 > +VARIABLE(grub_multiboot_change_prefix) > + .byte 0 > =20 > .p2align 2 /* force 4-byte alignment */ > =20 > > =3D=3D=3D 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 16:29:54 +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 =3D (grub_int32_t *) (core_img + GRUB_DISK_SECTOR_S= IZE > + GRUB_KERNEL_MACHINE_INSTALL_BSD_PART); > + prefix =3D (char *) (core_img + GRUB_DISK_SECTOR_SIZE + > + GRUB_KERNEL_MACHINE_PREFIX); > =20 > /* Open the root device and the destination device. */ > root_dev =3D grub_device_open (root); > @@ -305,6 +308,18 @@ setup (const char *dir, > dos_part =3D root_dev->disk->partition->number; > bsd_part =3D -1; > } > + > + if (prefix[0] !=3D '(') > + { > + char *root_part_name, *new_prefix; > + > + root_part_name =3D > + grub_partition_get_name (root_dev->disk->partition); > + new_prefix =3D xasprintf ("(,%s)%s", root_part_name, prefix); > + strcpy (prefix, new_prefix); > + free (new_prefix); > + free (root_part_name); > + } > } > else > dos_part =3D bsd_part =3D -1; > > Thanks, > > =20 --=20 Regards Vladimir '=CF=86-coder/phcoder' Serbinenko --------------enig0CB9EE615F363A190934FCCD Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iF4EAREKAAYFAkwZcJYACgkQNak7dOguQgmfVgD8D5s2hEWevLp9xu3wz3/wDCba eSa57IbJHNGk5q2hyq4A+wVlUSfPkvBAZrXJhyKaSWGmC2FRl2EpvIVo2opVL4lY =nlVC -----END PGP SIGNATURE----- --------------enig0CB9EE615F363A190934FCCD--