[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