>From 1db8a8919482dbed4cc15509d8078b2f16a289bb Mon Sep 17 00:00:00 2001
From: Gert Hulselmans <gerth at zytor.com>
Date: Wed, 30 Jun 2010 14:10:23 +0200
Subject: [PATCH] chain.c32: add grubcfg= for passing an alternative config
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