[PATCH] chain.c32: add grubcfg= for passing an alternative config

Gert Hulselmans gerth at zytor.com
Wed Jun 30 05:10:23 PDT 2010


filename to GRUB Legacy

GRUB Legacy reserves 89 bytes for storing the filename of the configfile
from memory address 0x8217 to 0x826f.
We allow overwriting the default value (/boot/grub/menu.lst) when
grubcfg=<filename> is used together with grub=<loader>.

Examples:
  chain.c32 fs grub=/boot/grub/stage2 grubcfg=/boot/grub/grub.lst
  chain.c32 hd1,10 grub=/boot/grub/stage2 grubcfg=/boot/grub/grub.lst

Signed-off-by: Gert Hulselmans <gerth at zytor.com>
---
 com32/modules/chain.c |   50
+++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 44 insertions(+), 6 deletions(-)

diff --git a/com32/modules/chain.c b/com32/modules/chain.c
index 4f5baf1..fd48bb8 100644
--- a/com32/modules/chain.c
+++ b/com32/modules/chain.c
@@ -78,7 +78,11 @@
  *
  * grub=<loader>
  *	same as seg=0x800 file=<loader> & jumping to seg 0x820,
- *	used with GRUB stage2 files.
+ *	used with GRUB Legacy stage2 files.
+ *
+ * grubcfg=<filename>
+ *	set an alternative config filename in stage2 of Grub Legacy
+ *	only applicable in combination with "grub=<loader>"
  *
  * grldr=<loader>
  *	pass the partition number to GRUB4DOS,
@@ -125,6 +129,7 @@ static struct options {
     bool cmldr;
     bool grub;
     bool grldr;
+    const char *grubcfg;
     bool swap;
     bool hide;
     bool sethidden;
@@ -1276,7 +1281,8 @@ Options: file=<loader>      Load and execute file,
instead of boot sector\n\
          freedos=<loader>   Load FreeDOS KERNEL.SYS\n\
          msdos=<loader>     Load MS-DOS IO.SYS\n\
          pcdos=<loader>     Load PC-DOS IBMBIO.COM\n\
-         grub=<loader>      Load GRUB stage2\n\
+         grub=<loader>      Load GRUB Legacy stage2\n\
+         grubcfg=<filename> Set alternative config filename for GRUB
Legacy\n\
          grldr=<loader>     Load GRUB4DOS grldr\n\
          seg=<segment>      Jump to <seg>:0000, instead of 0000:7C00\n\
          swap               Swap drive numbers, if bootdisk is not
fd0/hd0\n\
@@ -1349,6 +1355,8 @@ int main(int argc, char *argv[])
 	    opt.seg = 0x800;	/* stage2 wants this address */
 	    opt.loadfile = argv[i] + 5;
 	    opt.grub = true;
+	} else if (!strncmp(argv[i], "grubcfg=", 8)) {
+            opt.grubcfg = argv[i] + 8;
 	} else if (!strncmp(argv[i], "grldr=", 6)) {
 	    opt.loadfile = argv[i] + 6;
 	    opt.grldr = true;
@@ -1585,13 +1593,43 @@ int main(int argc, char *argv[])
 	if (opt.grub) {
 	    regs.ip = 0x200;	/* jump 0x200 bytes into the loadfile */

-	    /* GRUB's stage2 wants the partition number in the install_partition
+	    /*
+	     * GRUB's stage2 wants the partition number in the install_partition
 	     * variable, located at memory address 0x8208.
-	     * We only need to change the value of memory address 0x820a too:
-	     *   -1:   whole drive (default)
+	     *
+	     * It looks very similar to the "boot information format" of the
+	     * Multiboot specification:
+	     *  
http://www.gnu.org/software/grub/manual/multiboot/multiboot.html#Boot-information-format
+	     *
+	     *   0x8208 = part3: sub-partition in sub-partiton part2
+	     *   0x8209 = part2: sub-partiton in top-level partition
+	     *   0x820a = part1: top-level partition number
+	     *   0x820b = drive: BIOS drive number (must be 0)
+	     *
+	     * GRUB Legacy doesn't store the BIOS drive number at 0x820b, but at
+	     * another location.
+	     *
+	     * Partition numbers always start from zero.
+	     * Unused partition bytes must be set to 0xFF.
+	     *
+	     * We only care about top-level partition, so we only need to change
+	     * "part1" to the appropriate value:
+	     *   -1:   whole drive (default) (-1 = 0xFF)
 	     *   0-3:  primary partitions
-	     *   4-*:  logical partitions */
+	     *   4-*:  logical partitions
+	     */
 	    ((uint8_t*) data[ndata].data)[0x20a] = (uint8_t)(whichpart - 1);
+
+	    /*
+	     * Grub Legacy reserves 89 bytes (from 0x8217 to 0x826f) for the
+	     * config filename. The filename passed via grubcfg= will overwrite
+	     * the default config filename "/boot/grub/menu.lst".
+	     */
+	    if (opt.grubcfg && strlen(opt.grubcfg) <= 88
+		&& data[ndata].size > 0x26f)
+
+		memcpy((char *)data[ndata].data + 0x217, opt.grubcfg,
+		       strlen(opt.grubcfg) + 1);
 	}

 	ndata++;
-- 
1.6.3.3



More information about the Syslinux mailing list