[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