aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Soltys <soltys@ziu.info>2013-02-14 16:51:46 +0100
committerMichal Soltys <soltys@ziu.info>2013-02-14 16:53:05 +0100
commitd4ce5b911628423adeb53db8a3cb796f8de2016d (patch)
treea3c00a9e5fd52d6b1682ce93a64a9ac8d506e211
parentc3e12b67d34fbf0efaae33c8b0867ccceb7c5949 (diff)
downloadsyslinux-d4ce5b911628423adeb53db8a3cb796f8de2016d.tar.gz
syslinux-d4ce5b911628423adeb53db8a3cb796f8de2016d.tar.xz
syslinux-d4ce5b911628423adeb53db8a3cb796f8de2016d.zip
com32/chain: implement handling of non-standard hybrid GPT+MBR layouts
We also take a bit relaxed approach - so we check for presence of 0xEE at any place, then attempt to read GPT header only if prefmbr is not set. Signed-off-by: Michal Soltys <soltys@ziu.info>
-rw-r--r--com32/chain/chain.c10
-rw-r--r--com32/chain/mangle.c4
-rw-r--r--com32/chain/options.c5
-rw-r--r--com32/chain/options.h15
-rw-r--r--com32/chain/partiter.c7
-rw-r--r--com32/chain/partiter.h5
-rw-r--r--doc/chain.txt6
7 files changed, 34 insertions, 18 deletions
diff --git a/com32/chain/chain.c b/com32/chain/chain.c
index f1120d93..d6eab7ce 100644
--- a/com32/chain/chain.c
+++ b/com32/chain/chain.c
@@ -72,7 +72,7 @@ static int find_by_sig(uint32_t mbr_sig,
for (drive = 0x80; drive < 0x80 + fixed_cnt; drive++) {
if (disk_get_params(drive, &diskinfo))
continue; /* Drive doesn't exist */
- if (!(boot_part = pi_begin(&diskinfo, opt.relax)))
+ if (!(boot_part = pi_begin(&diskinfo, opt.relax | opt.prefmbr)))
continue;
/* Check for a MBR disk */
if (boot_part->type != typedos) {
@@ -103,7 +103,7 @@ static int find_by_guid(const struct guid *gpt_guid,
for (drive = 0x80; drive < 0x80 + fixed_cnt; drive++) {
if (disk_get_params(drive, &diskinfo))
continue; /* Drive doesn't exist */
- if (!(boot_part = pi_begin(&diskinfo, opt.relax)))
+ if (!(boot_part = pi_begin(&diskinfo, opt.relax | opt.prefmbr)))
continue;
/* Check for a GPT disk */
if (boot_part->type != typegpt) {
@@ -135,7 +135,7 @@ static int find_by_label(const char *label, struct part_iter **_boot_part)
for (drive = 0x80; drive < 0x80 + fixed_cnt; drive++) {
if (disk_get_params(drive, &diskinfo))
continue; /* Drive doesn't exist */
- if (!(boot_part = pi_begin(&diskinfo, opt.relax)))
+ if (!(boot_part = pi_begin(&diskinfo, opt.relax | opt.prefmbr)))
continue;
/* Check for a GPT disk */
if (!(boot_part->type == typegpt)) {
@@ -324,7 +324,7 @@ int find_dp(struct part_iter **_iter)
if (disk_get_params(drive, &diskinfo))
goto bail;
/* this will start iteration over FDD, possibly raw */
- if (!(iter = pi_begin(&diskinfo, opt.relax)))
+ if (!(iter = pi_begin(&diskinfo, opt.relax | opt.prefmbr)))
goto bail;
} else if (!strcmp(opt.drivename, "boot") || !strcmp(opt.drivename, "fs")) {
@@ -344,7 +344,7 @@ int find_dp(struct part_iter **_iter)
if (disk_get_params(drive, &diskinfo))
goto bail;
/* this will start iteration over disk emulation, possibly raw */
- if (!(iter = pi_begin(&diskinfo, opt.relax)))
+ if (!(iter = pi_begin(&diskinfo, opt.relax | opt.prefmbr)))
goto bail;
/* 'fs' => we should lookup the syslinux partition number and use it */
diff --git a/com32/chain/mangle.c b/com32/chain/mangle.c
index 252128da..94e6e90f 100644
--- a/com32/chain/mangle.c
+++ b/com32/chain/mangle.c
@@ -537,7 +537,7 @@ int manglepe_hide(struct part_iter *miter)
if (miter->index > 4 && !(opt.hide & HIDE_EXT))
warn("Specified partition is logical, so it can't be unhidden without 'unhideall'.");
- if (!(iter = pi_begin(&miter->di, PIF_STEPALL | opt.relax)))
+ if (!(iter = pi_begin(&miter->di, PIF_STEPALL | opt.relax | opt.prefmbr)))
return -1;
while (!pi_next(iter) && !werr) {
@@ -611,7 +611,7 @@ int manglepe_fixchs(struct part_iter *miter)
return -1;
}
- if (!(iter = pi_begin(&miter->di, PIF_STEPALL | opt.relax)))
+ if (!(iter = pi_begin(&miter->di, PIF_STEPALL | opt.relax | opt.prefmbr)))
return -1;
while (!pi_next(iter) && !werr) {
diff --git a/com32/chain/options.c b/com32/chain/options.c
index 209ad017..4044520b 100644
--- a/com32/chain/options.c
+++ b/com32/chain/options.c
@@ -125,6 +125,7 @@ static void usage(void)
" warn Wait for a keypress to continue chainloading",
" break Don't chainload",
" relax Relax sanity checks",
+" prefmbr On hybrid MBR/GPT disks, prefer legacy layout",
"",
" file=<file> Load and execute <file>",
" seg=<s[:o[:i]]> Load file at <s:o>, jump to <s:i>",
@@ -334,6 +335,10 @@ int opt_parse_args(int argc, char *argv[])
opt.warn = true;
} else if (!strcmp(argv[i], "nowarn")) {
opt.warn = false;
+ } else if (!strcmp(argv[i], "prefmbr")) {
+ opt.prefmbr = PIF_PREFMBR;
+ } else if (!strcmp(argv[i], "noprefmbr")) {
+ opt.prefmbr = 0;
} else if (!strcmp(argv[i], "nobreak")) {
opt.brkchain = false;
} else if (!strcmp(argv[i], "break")) {
diff --git a/com32/chain/options.h b/com32/chain/options.h
index ac8f356b..5ae41090 100644
--- a/com32/chain/options.h
+++ b/com32/chain/options.h
@@ -37,16 +37,20 @@
enum {HIDE_OFF = 0, HIDE_ON = 1, HIDE_EXT = 2, HIDE_REV = 4};
struct options {
+ const char *drivename;
+ const char *partition;
+ const char *file;
+ const char *grubcfg;
unsigned int fseg;
unsigned int foff;
unsigned int fip;
unsigned int sseg;
unsigned int soff;
unsigned int sip;
- const char *drivename;
- const char *partition;
- const char *file;
- const char *grubcfg;
+ int hide;
+ int relax;
+ int prefmbr;
+ uint16_t keeppxe;
bool isolinux;
bool cmldr;
bool drmk;
@@ -56,7 +60,6 @@ struct options {
bool hand;
bool hptr;
bool swap;
- int hide;
bool sect;
bool save;
bool bss;
@@ -64,9 +67,7 @@ struct options {
bool filebpb;
bool fixchs;
bool warn;
- int relax;
bool brkchain;
- uint16_t keeppxe;
struct syslinux_rm_regs regs;
};
diff --git a/com32/chain/partiter.c b/com32/chain/partiter.c
index 967769f6..3c7670d6 100644
--- a/com32/chain/partiter.c
+++ b/com32/chain/partiter.c
@@ -549,7 +549,7 @@ void pi_del(struct part_iter **_iter)
/* pi_begin() - validate and and get proper iterator for a disk described by di */
struct part_iter *pi_begin(const struct disk_info *di, int flags)
{
- int ret = -1;
+ int gptprot, ret = -1;
struct part_iter *iter;
struct disk_dos_mbr *mbr = NULL;
struct disk_gpt_header *gpth = NULL;
@@ -574,7 +574,10 @@ struct part_iter *pi_begin(const struct disk_info *di, int flags)
}
/* Check for GPT protective MBR */
- if (mbr->table[0].ostype == 0xEE) {
+ gptprot = 0;
+ for (size_t i = 0; i < 4; i++)
+ gptprot |= (mbr->table[i].ostype == 0xEE);
+ if (gptprot && !(flags & PIF_PREFMBR)) {
if (!(gpth = disk_read_sectors(di, 1, 1))) {
error("Couldn't read potential GPT header.");
goto bail;
diff --git a/com32/chain/partiter.h b/com32/chain/partiter.h
index a737584e..4004ef9e 100644
--- a/com32/chain/partiter.h
+++ b/com32/chain/partiter.h
@@ -46,8 +46,9 @@ enum {PI_OK, PI_DONE, PI_INSANE, PI_ERRLOAD};
/* flags */
-#define PIF_STEPALL 0x01
-#define PIF_RELAX 0x02
+#define PIF_STEPALL 0b001
+#define PIF_RELAX 0b010
+#define PIF_PREFMBR 0b100
struct itertype;
struct part_iter;
diff --git a/doc/chain.txt b/doc/chain.txt
index d3c012c0..2321c102 100644
--- a/doc/chain.txt
+++ b/doc/chain.txt
@@ -226,6 +226,12 @@ stacks in memory (pxelinux only).
This option will wait for a keypress right before continuing the chainloading.
Useful to see warnings emited by the chain module.
+ prefmbr
+ *noprefmbr
+
+In the case of presence of non-standard hybrid MBR/GPT layout, this flag makes
+chain module prefer MBR layout over GPT.
+
relax
*norelax