* 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
* 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.
*
*
* 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>:
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\
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;
|| !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) {
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;
/* 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");
/* 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);
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 */