[syslinux] [PATCH] isohybrid: Generate MBR even when in EFI mode

Matthew Garrett mjg at redhat.com
Wed Feb 15 09:12:17 PST 2012


Various EFI systems insist that there be no active flag in the pMBR in
order to parse the GPT. The only way around this is to also generate a
valid MBR - the firmware will then pick that up and use the system
partition provided there. In order to deal with other EFI "sanity" checks,
the partition type for the non-EFI partitions is set to 0 to skip the
firmware bailing because of overlapping partitions.
---
 utils/isohybrid.c |   54 ++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 49 insertions(+), 5 deletions(-)

diff --git a/utils/isohybrid.c b/utils/isohybrid.c
index 1dcbaa1..ac04bfd 100644
--- a/utils/isohybrid.c
+++ b/utils/isohybrid.c
@@ -54,7 +54,7 @@ enum { VERBOSE = 1 , EFI = 2 , MAC = 4};
 uint16_t head = 64;             /* 1 <= head <= 256 */
 uint8_t sector = 32;            /* 1 <= sector <= 63  */
 
-uint8_t entry = 1;              /* partition number: 1 <= entry <= 4 */
+uint8_t entry = 0;              /* partition number: 1 <= entry <= 4 */
 uint8_t offset = 0;             /* partition offset: 0 <= offset <= 64 */
 uint16_t type = 0x17;           /* partition type: 0 <= type <= 255 */
 uint32_t id = 0;                /* MBR: 0 <= id <= 0xFFFFFFFF(4294967296) */
@@ -300,6 +300,8 @@ check_option(int argc, char *argv[])
             entry = strtoul(optarg, &err, 0);
             if (entry < 1 || entry > 4)
                 errx(1, "invalid entry: `%s', 1 <= entry <= 4", optarg);
+	    if (mode & MAC || mode & EFI)
+		errx(1, "setting an entry is unsupported with EFI or Mac");
             break;
 
         case 'o':
@@ -334,10 +336,14 @@ check_option(int argc, char *argv[])
 
 	case 'u':
 	    mode |= EFI;
+	    if (entry)
+		errx(1, "setting an entry is unsupported with EFI or Mac");
 	    break;
 
 	case 'm':
 	    mode |= MAC;
+	    if (entry)
+		errx(1, "setting an entry is unsupported with EFI or Mac");
 	    break;
 
         case 'v':
@@ -581,6 +587,12 @@ initialise_mbr(uint8_t *mbr)
 	memcpy(mbr, afp_header, sizeof(afp_header));
     }
 
+    if (!entry)
+	entry = 1;
+
+    if (mode & EFI)
+	type = 0;
+
     mbr += MBRSIZE;                                 /* offset 432 */
 
     tmp = lendian_int(de_lba * 4);
@@ -633,6 +645,40 @@ initialise_mbr(uint8_t *mbr)
             tmp = lendian_int(psize);
             memcpy(&mbr[12], &tmp, sizeof(tmp));
         }
+        if (i == 2 && (mode & EFI))
+        {
+            mbr[0] = 0x0;
+            mbr[1] = 0xfe;
+            mbr[2] = 0xff;
+            mbr[3] = 0xff;
+            mbr[4] = 0xef;
+            mbr[5] = 0xfe;
+            mbr[6] = 0xff;
+            mbr[7] = 0xff;
+
+            tmp = lendian_int(efi_lba * 4);
+            memcpy(&mbr[8], &tmp, sizeof(tmp));
+
+            tmp = lendian_int(efi_count);
+            memcpy(&mbr[12], &tmp, sizeof(tmp));
+        }
+        if (i == 3 && (mode & MAC))
+        {
+            mbr[0] = 0x0;
+            mbr[1] = 0xfe;
+            mbr[2] = 0xff;
+            mbr[3] = 0xff;
+            mbr[4] = 0x0;
+            mbr[5] = 0xfe;
+            mbr[6] = 0xff;
+            mbr[7] = 0xff;
+
+            tmp = lendian_int(mac_lba * 4);
+            memcpy(&mbr[8], &tmp, sizeof(tmp));
+
+            tmp = lendian_int(mac_count);
+            memcpy(&mbr[12], &tmp, sizeof(tmp));
+        }
         mbr += 16;
     }
     mbr[0] = 0x55;
@@ -908,8 +954,7 @@ main(int argc, char *argv[])
 	if (!read_efi_section(buf)) {
 	    buf += 32;
 	    if (!read_efi_catalogue(buf, &efi_count, &efi_lba) && efi_lba) {
-		offset = 1;
-		type = 0xee;
+		offset = 0;
 	    } else {
 		errx(1, "%s: invalid efi catalogue", argv[0]);
 	    }
@@ -925,8 +970,7 @@ main(int argc, char *argv[])
 	if (!read_efi_section(buf)) {
 	    buf += 32;
 	    if (!read_efi_catalogue(buf, &mac_count, &mac_lba) && mac_lba) {
-		offset = 1;
-		type = 0xee;
+		offset = 0;
 	    } else {
 		errx(1, "%s: invalid efi catalogue", argv[0]);
 	    }
-- 
1.7.7.6




More information about the Syslinux mailing list