From a776840538b8f52053aa005952f713a498132565 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Mon, 30 Jun 2008 15:28:16 -0700 Subject: [PATCH] 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. --- NEWS | 3 +++ com32/modules/chain.c | 45 ++++++++++++++++++++++++++++++++------------- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/NEWS b/NEWS index 746b68f..b9ea008 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 e669961..3d1c28c 100644 --- a/com32/modules/chain.c +++ b/com32/modules/chain.c @@ -18,6 +18,7 @@ * Usage: chain hd [] [options] * chain fd [options] * chain mbr: [] [options] + * chain boot [] [options] * * ... e.g. "chain hd0 1" will boot the first partition on the first hard * disk. @@ -30,17 +31,24 @@ * * Options: * - * -file : + * file=: * loads the file **from the SYSLINUX filesystem** * instead of loading the boot sector. * - * -seg : + * seg=: * loads at and jumps to :0000 instead of 0000:7C00. * - * -ntldr : + * ntldr=: * equivalent to -seg 0x2000 -file , used with WinNT's loaders * - * -swap: + * freedos=: + * equivalent to -seg 0x60 -file , used with FreeDOS kernel.sys. + * + * msdos= + * pcdos= + * equivalent to -seg 0x70 -file , 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 #include #include +#include #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. */ -- 2.7.4