summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2008-06-30 15:28:16 -0700
committerH. Peter Anvin <hpa@zytor.com>2008-06-30 15:28:16 -0700
commita776840538b8f52053aa005952f713a498132565 (patch)
tree1b3a90a302db4ca882cd896994f2e8929277d1ee
parent5d707e3005f23fb82de8f2c0d23f7e523cf9bb12 (diff)
downloadsyslinux-a776840538b8f52053aa005952f713a498132565.tar.gz
chain.c32: allow "boot" as a drive specification
Allow "boot" as the drive specification; this can be used both with partition numbers and with loaders.
-rw-r--r--NEWS3
-rw-r--r--com32/modules/chain.c45
2 files changed, 35 insertions, 13 deletions
diff --git a/NEWS b/NEWS
index 746b68fd..b9ea008c 100644
--- a/NEWS
+++ b/NEWS
@@ -54,6 +54,9 @@ Changes in 3.70:
* Complex menu system: unbreak menus which has unnamed
submenus, like complex.c.
* Fix newline on the serial port for some com32 modules.
+ * chain.c32: support "boot" as the drive specification,
+ indicating the drive from which it was booted
+ (for syslinux/extlinux).
Changes in 3.64:
* SYSLINUX/EXTLINUX: support "localboot" with the same feature
diff --git a/com32/modules/chain.c b/com32/modules/chain.c
index e6699614..3d1c28c2 100644
--- a/com32/modules/chain.c
+++ b/com32/modules/chain.c
@@ -18,6 +18,7 @@
* Usage: chain hd<disk#> [<partition>] [options]
* chain fd<disk#> [options]
* chain mbr:<id> [<partition>] [options]
+ * chain boot [<partition>] [options]
*
* ... e.g. "chain hd0 1" will boot the first partition on the first hard
* disk.
@@ -30,17 +31,24 @@
*
* Options:
*
- * -file <loader>:
+ * file=<loader>:
* loads the file <loader> **from the SYSLINUX filesystem**
* instead of loading the boot sector.
*
- * -seg <segment>:
+ * seg=<segment>:
* loads at and jumps to <seg>:0000 instead of 0000:7C00.
*
- * -ntldr <loader>:
+ * ntldr=<loader>:
* equivalent to -seg 0x2000 -file <loader>, used with WinNT's loaders
*
- * -swap:
+ * freedos=<loader>:
+ * equivalent to -seg 0x60 -file <loader>, used with FreeDOS kernel.sys.
+ *
+ * msdos=<loader>
+ * pcdos=<loader>
+ * equivalent to -seg 0x70 -file <loader>, used with DOS' io.sys.
+ *
+ * swap:
* if the disk is not fd0/hd0, install a BIOS stub which swaps
* the drive numbers.
*/
@@ -55,6 +63,7 @@
#include <stdbool.h>
#include <syslinux/loadfile.h>
#include <syslinux/bootrm.h>
+#include <syslinux/config.h>
#define SECTOR 512 /* bytes/sector */
@@ -539,7 +548,7 @@ int main(int argc, char *argv[])
openconsole(&dev_null_r, &dev_stdcon_w);
- drivename = NULL;
+ drivename = "boot";
partition = NULL;
/* Prepare the register set */
@@ -571,7 +580,8 @@ int main(int argc, char *argv[])
opt.keeppxe = 3;
} else if (((argv[i][0] == 'h' || argv[i][0] == 'f') && argv[i][1] == 'd')
|| !strncmp(argv[i], "mbr:", 4)
- || !strncmp(argv[i], "mbr=", 4)) {
+ || !strncmp(argv[i], "mbr=", 4)
+ || !strcmp(argv[i], "boot") || !strncmp(argv[i], "boot,", 5)) {
drivename = argv[i];
p = strchr(drivename, ',');
if (p) {
@@ -581,7 +591,7 @@ int main(int argc, char *argv[])
partition = argv[++i];
}
} else {
- error("Usage: chain.c32 (hd#|fd#|mbr:#)[,partition] [options]\n");
+ error("Usage: chain.c32 (hd#|fd#|mbr:#|boot)[,partition] [options]\n");
goto bail;
}
}
@@ -609,13 +619,22 @@ int main(int argc, char *argv[])
error("Unable to find requested MBR signature\n");
goto bail;
}
- } else {
- if ( (drivename[0] == 'h' || drivename[0] == 'f') &&
- drivename[1] == 'd' ) {
- hd = drivename[0] == 'h';
- drivename += 2;
- }
+ } 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")) {
+ const union syslinux_derivative_info *sdi;
+ sdi = syslinux_derivative_info();
+ if (sdi->c.filesystem == SYSLINUX_FS_PXELINUX ||
+ sdi->c.filesystem == SYSLINUX_FS_ISOLINUX)
+ drive = 0x80; /* Boot drive not available */
+ else
+ drive = sdi->disk.drive_number;
+ } else {
+ error("Unparsable drive specification\n");
+ goto bail;
}
/* DOS kernels want the drive number in BL instead of DL. Indulge them. */