[syslinux:master] chain: Allow booting the Syslinux partition with "fs"

syslinux-bot for Shao Miller shao.miller at yrdsb.edu.on.ca
Fri Jun 25 14:12:30 PDT 2010


Commit-ID:  0874223587fac2169c28965ce9e95b7bf0f82737
Gitweb:     http://syslinux.zytor.com/commit/0874223587fac2169c28965ce9e95b7bf0f82737
Author:     Shao Miller <shao.miller at yrdsb.edu.on.ca>
AuthorDate: Thu, 24 Jun 2010 16:49:05 -0400
Committer:  Shao Miller <shao.miller at yrdsb.edu.on.ca>
CommitDate: Thu, 24 Jun 2010 16:49:05 -0400

chain: Allow booting the Syslinux partition with "fs"

We will now accept an "fs" option which instructs us to
chain-load whatever partition we were booted from.  Not
useful for PXELINUX, for obvious reasons.  Can be used
in combination with a "file=" option, to boot something
other than Syslinux.

Signed-off-by: Shao Miller <shao.miller at yrdsb.edu.on.ca>


---
 NEWS                  |    1 +
 com32/modules/chain.c |   75 ++++++++++++++++++++++++++++--------------------
 2 files changed, 45 insertions(+), 31 deletions(-)

diff --git a/NEWS b/NEWS
index d3f43ca..fdf33cf 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,7 @@ to all derivatives.
 
 Changes in 4.00:
 	* chain.c32: support booting GPT partitions by index
+	* chain.c32: support booting the Syslinux partition with "fs"
 Changes in 3.86:
 	* chain.c32: fix chainloading the MBR of a hard disk (broken
 	  in 3.85).
diff --git a/com32/modules/chain.c b/com32/modules/chain.c
index 97a7086..2652de8 100644
--- a/com32/modules/chain.c
+++ b/com32/modules/chain.c
@@ -3,7 +3,7 @@
  *   Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
  *   Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
  *   Significant portions copyright (C) 2010 Shao Miller
- *					[partition iteration, GPT]
+ *					[partition iteration, GPT, "fs"]
  *
  *   This program is free software; you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License as published by
@@ -28,7 +28,7 @@
  * filesystem.  "chain hd0 1" will boot the first partition on the first hard
  * disk.
  *
- * When none of the "hdX", "fdX", "mbr:" or "boot" options are specified,
+ * When none of the "hdX", "fdX", "mbr:", "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.
  *
@@ -37,6 +37,9 @@
  *
  * Partitions 1-4 are primary, 5+ logical, 0 = boot MBR (default.)
  *
+ * "fs" will use the current Syslinux filesystem as the boot drive/partition.
+ * When booting from PXELINUX, you will most likely wish to specify a disk.
+ *
  * Options:
  *
  * file=<loader>:
@@ -1080,6 +1083,7 @@ Usage:   chain.c32 [options]\n\
          chain.c32 fd<disk#> [options]\n\
          chain.c32 mbr:<id> [<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\
          ntldr=<loader>     Load Windows NTLDR, SETUPLDR.BIN or BOOTMGR\n\
@@ -1103,8 +1107,9 @@ int main(int argc, char *argv[])
     struct disk_part_iter *cur_part = NULL;
     struct syslinux_rm_regs regs;
     char *drivename, *partition;
-    int hd, drive, whichpart;
+    int hd, drive, whichpart = 0;	/* MBR by default */
     int i;
+    uint64_t fs_lba = 0;	/* Syslinux partition */
     uint32_t file_lba = 0;
     unsigned char *isolinux_bin;
     uint32_t *checksum, *chkhead, *chktail;
@@ -1175,7 +1180,8 @@ int main(int argc, char *argv[])
 		   || !strncmp(argv[i], "mbr:", 4)
 		   || !strncmp(argv[i], "mbr=", 4)
 		   || !strcmp(argv[i], "boot")
-		   || !strncmp(argv[i], "boot,", 5)) {
+		   || !strncmp(argv[i], "boot,", 5)
+		   || !strncmp(argv[i], "fs", 2)) {
 	    drivename = argv[i];
 	    p = strchr(drivename, ',');
 	    if (p) {
@@ -1209,13 +1215,19 @@ int main(int argc, char *argv[])
 	hd = drivename[0] == 'h';
 	drivename += 2;
 	drive = (hd ? 0x80 : 0) | strtoul(drivename, NULL, 0);
-    } else if (!strcmp(drivename, "boot")) {
+    } else if (!strcmp(drivename, "boot") || !strcmp(drivename, "fs")) {
 	const union syslinux_derivative_info *sdi;
+
 	sdi = syslinux_derivative_info();
 	if (sdi->c.filesystem == SYSLINUX_FS_PXELINUX)
 	    drive = 0x80;	/* Boot drive not available */
 	else
 	    drive = sdi->disk.drive_number;
+	if (!strcmp(drivename, "fs")
+	    && (sdi->c.filesystem == SYSLINUX_FS_SYSLINUX
+		|| sdi->c.filesystem == SYSLINUX_FS_EXTLINUX))
+	    /* We should lookup the Syslinux partition number and use it */
+	    fs_lba = ((struct part_entry *)sdi->disk.ptab_ptr)->start_lba;
     } else {
 	error("Unparsable drive specification\n");
 	goto bail;
@@ -1224,22 +1236,6 @@ int main(int argc, char *argv[])
     /* DOS kernels want the drive number in BL instead of DL.  Indulge them. */
     regs.ebx.b[0] = regs.edx.b[0] = drive;
 
-    whichpart = 0;		/* Default */
-    if (partition)
-	whichpart = strtoul(partition, NULL, 0);
-
-    if (!(drive & 0x80) && whichpart) {
-	error("Warning: Partitions of floppy devices may not work\n");
-    }
-
-    /* 
-     * GRLDR of GRUB4DOS wants the partition number in DH:
-     * -1:   whole drive (default)
-     * 0-3:  primary partitions
-     * 4-*:  logical partitions
-     */
-    regs.edx.b[1] = whichpart - 1;
-
     /* Get the disk geometry and disk access setup */
     if (get_disk_params(drive)) {
 	error("Cannot get disk parameters\n");
@@ -1248,23 +1244,20 @@ int main(int argc, char *argv[])
 
     /* Get MBR */
     if (!(mbr = read_sectors(0, 1))) {
-	error("Cannot read Master Boot Record\n");
+	error("Cannot read Master Boot Record or sector 0\n");
 	goto bail;
     }
 
-    if (opt.hide) {
-	if (whichpart < 1 || whichpart > 4)
-	    error("WARNING: hide specified without a non-primary partition\n");
-	if (hide_unhide(mbr, whichpart))
-	    error("WARNING: failed to write MBR for 'hide'\n");
-    }
+    if (partition)
+	whichpart = strtoul(partition, NULL, 0);
 
     /* Boot the MBR by default */
-    if (whichpart) {
-	/* Boot a partition */
+    if (whichpart || fs_lba) {
+	/* Boot a partition, possibly the Syslinux partition itself */
 	cur_part = get_first_partition(NULL);
 	while (cur_part) {
-	    if (cur_part->index == whichpart)
+	    if ((cur_part->index == whichpart)
+		|| (cur_part->lba_data == fs_lba))
 		/* Found the partition to boot */
 		break;
 	    cur_part = cur_part->next(cur_part);
@@ -1273,6 +1266,26 @@ int main(int argc, char *argv[])
 	    error("Requested partition not found!\n");
 	    goto bail;
 	}
+	whichpart = cur_part->index;
+    }
+
+    if (!(drive & 0x80) && whichpart) {
+	error("Warning: Partitions of floppy devices may not work\n");
+    }
+
+    /* 
+     * GRLDR of GRUB4DOS wants the partition number in DH:
+     * -1:   whole drive (default)
+     * 0-3:  primary partitions
+     * 4-*:  logical partitions
+     */
+    regs.edx.b[1] = whichpart - 1;
+
+    if (opt.hide) {
+	if (whichpart < 1 || whichpart > 4)
+	    error("WARNING: hide specified without a non-primary partition\n");
+	if (hide_unhide(mbr, whichpart))
+	    error("WARNING: failed to write MBR for 'hide'\n");
     }
 
     /* Do the actual chainloading */



More information about the Syslinux-commits mailing list