[syslinux] [PATCH] chain.c32: add support for loading GRUB stage2
Paul Bolle
pebolle at tiscali.nl
Tue Jun 29 03:19:58 PDT 2010
On Mon, 2010-06-28 at 09:07 -0400, Shao Miller wrote:
> "boot" is only intended to pass the Syslinux INT 0x13 drive number, not
> the filesystem's partition's index. Use "fs" to pass both. That is,
> passing 0xFF (whichpart - 1 iff whichpart == 0) would be correct, here.
>
> [...]
>
> Paul Bolle wrote:
> > I should have added here that this last command can have the identical
> > effect as the first command if partition 2 is the SYLINUX filesystem.
>
> Nope. See "boot" versus "fs", above.
It looks like I misinterpreted chain.c32's usage.
I've pasted (at the bottom of this message) a draft patch that clarifies
chain.c32's usage a bit. The idea of this patch is to:
- update the usage comment and the usage string;
- s/drivename/argument/g;
- disallow setting a partition for the "fs" argument;
- do not allow arguments like "hd1,2" (that should be "hd1 2" instead);
But perhaps I still do not understand the usage of this module
correctly.
Paul
diff --git a/com32/modules/chain.c b/com32/modules/chain.c
index f0a2a30..4fa849c 100644
--- a/com32/modules/chain.c
+++ b/com32/modules/chain.c
@@ -18,22 +18,22 @@
*
* Chainload a hard disk (currently rather braindead.)
*
- * Usage: chain [options]
- * chain hd<disk#> [<partition>] [options]
+ * Usage: chain hd<disk#> [<partition>] [options]
* chain fd<disk#> [options]
* chain mbr:<id> [<partition>] [options]
* chain guid:<guid> [<partition>] [options]
* chain label:<label> [<partition>] [options]
- * chain boot [<partition>] [options]
+ * chain [boot] [<partition>] [options]
+ * chain fs [options]
*
* For example, "chain msdos=io.sys" will load DOS from the current Syslinux
* filesystem. "chain hd0 1" will boot the first partition on the first hard
* disk.
*
* When none of the "hdX", "fdX", "mbr:", "guid:", "label:", "boot" or "fs"
- * options are specified, the default behaviour is equivalent to "boot".
- * "boot" means to use the current Syslinux drive, and you can also specify
- * a partition.
+ * arguments are specified, the default behaviour is equivalent to "boot".
+ * "boot" will use the drive of the current Syslinux filesystem, but you can
+ * still specify a different partition on that drive.
*
* The mbr: syntax means search all the hard disks until one with a
* specific MBR serial number (bytes 440-443) is found.
@@ -1263,13 +1263,12 @@ static uint32_t get_file_lba(const char *filename)
static void usage(void)
{
static const char usage[] = "\
-Usage: chain.c32 [options]\n\
- chain.c32 hd<disk#> [<partition>] [options]\n\
+Usage: chain.c32 hd<disk#> [<partition>] [options]\n\
chain.c32 fd<disk#> [options]\n\
chain.c32 mbr:<id> [<partition>] [options]\n\
chain.c32 guid:<guid> [<partition>] [options]\n\
chain.c32 label:<label> [<partition>] [options]\n\
- chain.c32 boot [<partition>] [options]\n\
+ chain.c32 [boot] [<partition>] [options]\n\
chain.c32 fs [options]\n\
Options: file=<loader> Load and execute file, instead of boot sector\n\
isolinux=<loader> Load another version of ISOLINUX\n\
@@ -1294,10 +1293,10 @@ See syslinux/com32/modules/chain.c for more information\n";
int main(int argc, char *argv[])
{
struct mbr *mbr = NULL;
- char *p;
+ char *p = NULL;
struct disk_part_iter *cur_part = NULL;
struct syslinux_rm_regs regs;
- char *drivename, *partition;
+ char *argument, *partition;
int hd, drive, whichpart = 0; /* MBR by default */
int i;
uint64_t fs_lba = 0; /* Syslinux partition */
@@ -1312,7 +1311,7 @@ int main(int argc, char *argv[])
openconsole(&dev_null_r, &dev_stdcon_w);
- drivename = "boot";
+ argument = "boot";
partition = NULL;
/* Prepare the register set */
@@ -1386,10 +1385,11 @@ int main(int argc, char *argv[])
|| !strncmp(argv[i], "label:", 6)
|| !strncmp(argv[i], "label=", 6)
|| !strcmp(argv[i], "boot")
- || !strncmp(argv[i], "boot,", 5)
- || !strcmp(argv[i], "fs")) {
- drivename = argv[i];
- p = strchr(drivename, ',');
+ || !strncmp(argv[i], "boot,", 5)) {
+ argument = argv[i];
+ /* do not allow things like "hd0,4" (use "hd0 4" instead) */
+ if (!strncmp(argument, "boot,", 5))
+ p = strchr(argument, ',');
if (p) {
*p = '\0';
partition = p + 1;
@@ -1410,36 +1410,36 @@ int main(int argc, char *argv[])
}
hd = 0;
- if (!strncmp(drivename, "mbr", 3)) {
- drive = find_disk(strtoul(drivename + 4, NULL, 0));
+ if (!strncmp(argument, "mbr", 3)) {
+ drive = find_disk(strtoul(argument + 4, NULL, 0));
if (drive == -1) {
error("Unable to find requested MBR signature\n");
goto bail;
}
- } else if (!strncmp(drivename, "guid", 4)) {
- if (str_to_guid(drivename + 5, &gpt_guid))
+ } else if (!strncmp(argument, "guid", 4)) {
+ if (str_to_guid(argument + 5, &gpt_guid))
goto bail;
drive = find_by_guid(&gpt_guid, &cur_part);
if (drive == -1) {
error("Unable to find requested GPT disk/partition\n");
goto bail;
}
- } else if (!strncmp(drivename, "label", 5)) {
- if (!drivename[6]) {
+ } else if (!strncmp(argument, "label", 5)) {
+ if (!argument[6]) {
error("No label specified.\n");
goto bail;
}
- drive = find_by_label(drivename + 6, &cur_part);
+ drive = find_by_label(argument + 6, &cur_part);
if (drive == -1) {
error("Unable to find requested partition by label\n");
goto bail;
}
- } else if ((drivename[0] == 'h' || drivename[0] == 'f') &&
- drivename[1] == 'd') {
- hd = drivename[0] == 'h';
- drivename += 2;
- drive = (hd ? 0x80 : 0) | strtoul(drivename, NULL, 0);
- } else if (!strcmp(drivename, "boot") || !strcmp(drivename, "fs")) {
+ } else if ((argument[0] == 'h' || argument[0] == 'f') &&
+ argument[1] == 'd') {
+ hd = argument[0] == 'h';
+ argument += 2;
+ drive = (hd ? 0x80 : 0) | strtoul(argument, NULL, 0);
+ } else if (!strcmp(argument, "boot") || !strcmp(argument, "fs")) {
const union syslinux_derivative_info *sdi;
sdi = syslinux_derivative_info();
@@ -1447,7 +1447,7 @@ int main(int argc, char *argv[])
drive = 0x80; /* Boot drive not available */
else
drive = sdi->disk.drive_number;
- if (!strcmp(drivename, "fs")
+ if (!strcmp(argument, "fs")
&& (sdi->c.filesystem == SYSLINUX_FS_SYSLINUX
|| sdi->c.filesystem == SYSLINUX_FS_EXTLINUX
|| sdi->c.filesystem == SYSLINUX_FS_ISOLINUX))
More information about the Syslinux
mailing list