Gert Hulselmans
2010-Jun-30 12:10 UTC
[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