File 0005-Fix-gpt-code-in-isohybrid-and-adjust-to-create-a-val.patch of Package syslinux
From 342c931c6dc3e1f94895066698b2ee89c0fd44f6 Mon Sep 17 00:00:00 2001
From: Steffen Winterfeldt <snwint@suse.de>
Date: Mon, 4 Feb 2013 14:29:58 +0100
Subject: [PATCH 05/22] Fix gpt code in isohybrid and adjust to create a valid
partition table for our new media layout
---
utils/isohybrid.c | 391 +++++++++++++++++++++++++---------------------
utils/isohybrid.h | 2 +-
2 files changed, 211 insertions(+), 182 deletions(-)
diff --git a/utils/isohybrid.c b/utils/isohybrid.c
index a9e38d4d..2d2133e4 100644
--- a/utils/isohybrid.c
+++ b/utils/isohybrid.c
@@ -43,40 +43,42 @@
char *prog = NULL;
extern int opterr, optind;
-struct stat isostat;
-unsigned int padding = 0;
uuid_t disk_uuid, part_uuid, iso_uuid;
uint8_t mode = 0;
-enum { VERBOSE = 1 , EFI = 2 , MAC = 4};
+enum { VERBOSE = 1 , EFI = 2 , MAC = 4 , MODE_GPT = 8 , MODE_MBR = 0x10 };
+
+/* partition numbers (1 based) */
+int part_data = 0;
+int part_efi = 0;
+int part_mac = 0;
/* user options */
uint16_t head = 64; /* 1 <= head <= 256 */
uint8_t sector = 32; /* 1 <= sector <= 63 */
uint8_t entry = 0; /* partition number: 1 <= entry <= 4 */
-uint8_t offset = 0; /* partition offset: 0 <= offset <= 64 */
+uint32_t offset = 0; /* partition offset: 0 <= offset <= 0xFFFFFFFF(4294967296) */
uint16_t type = 0x17; /* partition type: 0 <= type <= 255 */
uint32_t id = 0; /* MBR: 0 <= id <= 0xFFFFFFFF(4294967296) */
uint8_t hd0 = 0; /* 0 <= hd0 <= 2 */
uint8_t partok = 0; /* 0 <= partok <= 1 */
-char mbr_template_path[1024] = {0}; /* Path to MBR template */
-
uint16_t ve[16];
uint32_t catoffset = 0;
-uint32_t c = 0, cc = 0, cs = 0;
+uint32_t c = 0;
-uint32_t psize = 0, isosize = 0;
+off_t iso_size = 0;
+off_t iso_filesize = 0;
/* boot catalogue parameters */
uint32_t de_lba = 0;
uint16_t de_seg = 0, de_count = 0, de_mbz2 = 0;
uint8_t de_boot = 0, de_media = 0, de_sys = 0, de_mbz1 = 0;
uint32_t efi_lba = 0, mac_lba = 0;
-uint16_t efi_count = 0, mac_count = 0;
+uint32_t efi_count = 0, mac_count = 0;
uint8_t efi_boot = 0, efi_media = 0, efi_sys = 0;
int apm_parts = 3;
@@ -225,21 +227,22 @@ usage(void)
void
printh(void)
{
-#define FMT "%-20s %s\n"
+#define FMT "%-18s %s\n"
usage();
printf("\n");
printf("Options:\n");
- printf(FMT, " -h <X>", "Number of geometry heads (default 64)");
- printf(FMT, " -s <X>", "Number of geometry sectors (default 32)");
+ printf(FMT, " -h <X>", "Number of default geometry heads");
+ printf(FMT, " -s <X>", "Number of default geometry sectors");
printf(FMT, " -e --entry", "Specify partition entry number (1-4)");
- printf(FMT, " -o --offset", "Specify partition offset (default 0)");
+ printf(FMT, " -o --offset", "Specify partition offset (in 512 byte units, default 0)");
printf(FMT, " -t --type", "Specify partition type (default 0x17)");
printf(FMT, " -i --id", "Specify MBR ID (default random)");
printf(FMT, " -u --uefi", "Build EFI bootable image");
printf(FMT, " -m --mac", "Add AFP table support");
- printf(FMT, " -b --mbr <PATH>", "Load MBR from PATH");
+ printf(FMT, " --gpt", "Force GPT");
+ printf(FMT, " --mbr", "Force MBR");
printf("\n");
printf(FMT, " --forcehd0", "Assume we are loaded as disk ID 0");
@@ -262,20 +265,21 @@ check_option(int argc, char *argv[])
char *err = NULL;
int n = 0, ind = 0;
- const char optstr[] = ":h:s:e:o:t:i:b:umfcp?vV";
+ const char optstr[] = ":h:s:e:o:t:i:fcp?vV";
struct option lopt[] = \
{
{ "entry", required_argument, NULL, 'e' },
{ "offset", required_argument, NULL, 'o' },
{ "type", required_argument, NULL, 't' },
{ "id", required_argument, NULL, 'i' },
+ { "gpt", no_argument, NULL, 1001 },
+ { "mbr", no_argument, NULL, 1002 },
{ "forcehd0", no_argument, NULL, 'f' },
{ "ctrlhd0", no_argument, NULL, 'c' },
{ "partok", no_argument, NULL, 'p'},
{ "uefi", no_argument, NULL, 'u'},
{ "mac", no_argument, NULL, 'm'},
- { "mbr", required_argument, NULL, 'b' },
{ "help", no_argument, NULL, '?' },
{ "verbose", no_argument, NULL, 'v' },
@@ -305,14 +309,12 @@ 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':
offset = strtoul(optarg, &err, 0);
- if (*err || offset > 64)
- errx(1, "invalid offset: `%s', 0 <= offset <= 64", optarg);
+ if (*err)
+ errx(1, "invalid offset: `%s', 0 <= offset <= 0xFFFFFFFF", optarg);
break;
case 't':
@@ -341,26 +343,24 @@ 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 'b':
- if (strlen(optarg) >= sizeof(mbr_template_path))
- errx(1, "--mbr : Path too long");
- strcpy(mbr_template_path, optarg);
- break;
-
case 'v':
mode |= VERBOSE;
break;
+ case 1001:
+ mode |= MODE_GPT;
+ break;
+
+ case 1002:
+ mode |= MODE_MBR;
+ break;
+
case 'V':
printf("%s version %s\n", prog, VERSION);
exit(0);
@@ -476,7 +476,7 @@ check_banner(const uint8_t *buf)
int
check_catalogue(const uint8_t *buf)
{
- int i = 0;
+ int i, cs;
for (i = 0, cs = 0; i < 16; i++)
{
@@ -552,7 +552,7 @@ read_efi_section(const uint8_t *buf)
}
int
-read_efi_catalogue(const uint8_t *buf, uint16_t *count, uint32_t *lba)
+read_efi_catalogue(const uint8_t *buf, uint32_t *count, uint32_t *lba)
{
buf += 6;
@@ -582,62 +582,33 @@ display_catalogue(void)
}
-void
-read_mbr_template(char *path, uint8_t *mbr)
+uint32_t ofs2chs(uint32_t ofs)
{
- FILE *fp;
- int ret;
-
- fp = fopen(path, "rb");
- if (fp == NULL)
- err(1, "could not open MBR template file `%s'", path);
- clearerr(fp);
- ret = fread(mbr, 1, MBRSIZE, fp);
- if (ferror(fp) || ret != MBRSIZE)
- err(1, "error while reading MBR template file `%s'", path);
- fclose(fp);
-}
+ unsigned c, h, s;
+ s = (ofs % sector) + 1;
+ h = (ofs / sector) % head;
+ c = ofs / (sector * head);
+ if(c > 1023) c = 1023;
+
+ return ((c & 0xff) << 24) + ((s + ((c >> 8) << 6)) << 16) + (h << 8);
+}
int
initialise_mbr(uint8_t *mbr)
{
int i = 0;
- uint32_t tmp = 0;
- uint8_t ptype = 0, *rbm = mbr;
- uint8_t bhead = 0, bsect = 0, bcyle = 0;
- uint8_t ehead = 0, esect = 0, ecyle = 0;
+ uint32_t tmp = 0, chs;
+ uint8_t *rbm = mbr;
-#ifndef ISOHYBRID_C_STANDALONE
extern unsigned char isohdpfx[][MBRSIZE];
-#endif
-
- if (mbr_template_path[0]) {
- read_mbr_template(mbr_template_path, mbr);
- } else {
-
-#ifdef ISOHYBRID_C_STANDALONE
-
- err(1, "This is a standalone binary. You must specify --mbr. E.g with /usr/lib/syslinux/isohdpfx.bin");
-
-#else
-
- memcpy(mbr, &isohdpfx[hd0 + 3 * partok], MBRSIZE);
-#endif /* ! ISOHYBRID_C_STANDALONE */
-
- }
+ memcpy(mbr, &isohdpfx[hd0 + 3 * partok], MBRSIZE);
if (mode & MAC) {
- memcpy(mbr, afp_header, sizeof(afp_header));
+ 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);
@@ -656,50 +627,66 @@ initialise_mbr(uint8_t *mbr)
mbr[1] = '\0';
mbr += 2; /* offset 446 */
- ptype = type;
- psize = c * head * sector - offset;
+ for (i = 1; i <= 4; i++, mbr += 16)
+ {
+ memset(mbr, 0, 16);
- bhead = (offset / sector) % head;
- bsect = (offset % sector) + 1;
- bcyle = offset / (head * sector);
+ if (!(mode & MODE_MBR)) {
+ /* write protective mbr */
+ if(i == 1 && (mode & MODE_GPT)) {
+ chs = ofs2chs(1);
+ mbr[1] = chs >> 8;
+ mbr[2] = chs >> 16;
+ mbr[3] = chs >> 24;
+ mbr[4] = 0xee;
+ chs = ofs2chs(iso_filesize/512 - 1);
+ mbr[5] = chs >> 8;
+ mbr[6] = chs >> 16;
+ mbr[7] = chs >> 24;
+
+ tmp = lendian_int(1);
+ memcpy(&mbr[8], &tmp, sizeof(tmp));
- bsect += (bcyle & 0x300) >> 2;
- bcyle &= 0xFF;
+ tmp = lendian_int(iso_filesize/512 - 1);
+ memcpy(&mbr[12], &tmp, sizeof(tmp));
+ }
- ehead = head - 1;
- esect = sector + (((cc - 1) & 0x300) >> 2);
- ecyle = (cc - 1) & 0xFF;
+ continue;
+ }
- for (i = 1; i <= 4; i++)
- {
- memset(mbr, 0, 16);
- if (i == entry)
- {
+ if (i == 1)
mbr[0] = 0x80;
- mbr[1] = bhead;
- mbr[2] = bsect;
- mbr[3] = bcyle;
- mbr[4] = ptype;
- mbr[5] = ehead;
- mbr[6] = esect;
- mbr[7] = ecyle;
+
+ if (i == part_data)
+ {
+ chs = ofs2chs(offset);
+ mbr[1] = chs >> 8;
+ mbr[2] = chs >> 16;
+ mbr[3] = chs >> 24;
+ chs = ofs2chs(c * head * sector - 1);
+ mbr[4] = type;
+ mbr[5] = chs >> 8;
+ mbr[6] = chs >> 16;
+ mbr[7] = chs >> 24;
tmp = lendian_int(offset);
memcpy(&mbr[8], &tmp, sizeof(tmp));
- tmp = lendian_int(psize);
+ tmp = lendian_int(c * head * sector - offset);
memcpy(&mbr[12], &tmp, sizeof(tmp));
}
- if (i == 2 && (mode & EFI))
+
+ if (i == part_efi)
{
- mbr[0] = 0x0;
- mbr[1] = 0xfe;
- mbr[2] = 0xff;
- mbr[3] = 0xff;
+ chs = ofs2chs(efi_lba * 4);
+ mbr[1] = chs >> 8;
+ mbr[2] = chs >> 16;
+ mbr[3] = chs >> 24;
+ chs = ofs2chs(efi_lba * 4 + efi_count - 1);
mbr[4] = 0xef;
- mbr[5] = 0xfe;
- mbr[6] = 0xff;
- mbr[7] = 0xff;
+ mbr[5] = chs >> 8;
+ mbr[6] = chs >> 16;
+ mbr[7] = chs >> 24;
tmp = lendian_int(efi_lba * 4);
memcpy(&mbr[8], &tmp, sizeof(tmp));
@@ -707,9 +694,9 @@ initialise_mbr(uint8_t *mbr)
tmp = lendian_int(efi_count);
memcpy(&mbr[12], &tmp, sizeof(tmp));
}
- if (i == 3 && (mode & MAC))
+
+ if (i == part_mac)
{
- mbr[0] = 0x0;
mbr[1] = 0xfe;
mbr[2] = 0xff;
mbr[3] = 0xff;
@@ -724,8 +711,8 @@ initialise_mbr(uint8_t *mbr)
tmp = lendian_int(mac_count);
memcpy(&mbr[12], &tmp, sizeof(tmp));
}
- mbr += 16;
}
+
mbr[0] = 0x55;
mbr[1] = 0xAA;
mbr += 2;
@@ -808,6 +795,9 @@ initialise_gpt(uint8_t *gpt, uint32_t current, uint32_t alternate, int primary)
struct gpt_part_header *part;
int hole = 0;
int gptsize = 128 / 4 + 2;
+ int i;
+
+ if(!(mode & MODE_GPT)) return;
if (mac_lba) {
/* 2048 bytes per partition, plus round to 2048 boundary */
@@ -825,8 +815,7 @@ initialise_gpt(uint8_t *gpt, uint32_t current, uint32_t alternate, int primary)
header->currentLBA = lendian_64(current);
header->backupLBA = lendian_64(alternate);
header->firstUsableLBA = lendian_64(gptsize + hole);
- header->lastUsableLBA = lendian_64((isostat.st_size + padding)/512 -
- gptsize);
+ header->lastUsableLBA = lendian_64(iso_filesize/512 - gptsize);
if (primary)
header->partitionEntriesLBA = lendian_64(0x02 + hole);
else
@@ -848,40 +837,34 @@ initialise_gpt(uint8_t *gpt, uint32_t current, uint32_t alternate, int primary)
reverse_uuid(iso_uuid);
}
- memcpy(part->partGUID, iso_uuid, sizeof(uuid_t));
- memcpy(part->partTypeGUID, basic_partition, sizeof(uuid_t));
- part->firstLBA = lendian_64(0);
- part->lastLBA = lendian_64(psize - 1);
- ascii_to_utf16le(part->name, "ISOHybrid ISO");
-
- gpt += sizeof(struct gpt_part_header);
- part++;
-
- memcpy(part->partGUID, part_uuid, sizeof(uuid_t));
- memcpy(part->partTypeGUID, basic_partition, sizeof(uuid_t));
- part->firstLBA = lendian_64(efi_lba * 4);
- part->lastLBA = lendian_64(part->firstLBA + efi_count - 1);
- ascii_to_utf16le(part->name, "ISOHybrid");
-
- gpt += sizeof(struct gpt_part_header);
-
- if (mac_lba) {
- gpt += sizeof(struct gpt_part_header);
-
- part++;
+ for(i = 1; i <= 4; i++, part++) {
+ if(i == part_data) {
+ memcpy(part->partGUID, iso_uuid, sizeof(uuid_t));
+ memcpy(part->partTypeGUID, basic_partition, sizeof(uuid_t));
+ part->firstLBA = lendian_64(offset);
+ part->lastLBA = lendian_64(iso_size/512 - 1);
+ ascii_to_utf16le(part->name, "ISOHybrid ISO");
+ }
- memcpy(part->partGUID, part_uuid, sizeof(uuid_t));
- memcpy(part->partTypeGUID, hfs_partition, sizeof(uuid_t));
- part->firstLBA = lendian_64(mac_lba * 4);
- part->lastLBA = lendian_64(part->firstLBA + mac_count - 1);
- ascii_to_utf16le(part->name, "ISOHybrid");
+ if(i == part_efi) {
+ memcpy(part->partGUID, part_uuid, sizeof(uuid_t));
+ memcpy(part->partTypeGUID, efi_system_partition, sizeof(uuid_t));
+ part->firstLBA = lendian_64(efi_lba * 4);
+ part->lastLBA = lendian_64(part->firstLBA + efi_count - 1);
+ ascii_to_utf16le(part->name, "ISOHybrid");
+ }
- part--;
+ if (i == part_mac) {
+ memcpy(part->partGUID, part_uuid, sizeof(uuid_t));
+ memcpy(part->partTypeGUID, hfs_partition, sizeof(uuid_t));
+ part->firstLBA = lendian_64(mac_lba * 4);
+ part->lastLBA = lendian_64(part->firstLBA + mac_count - 1);
+ ascii_to_utf16le(part->name, "ISOHybrid");
+ }
}
- part--;
- header->partitionEntriesCRC = lendian_int (chksum_crc32((uint8_t *)part,
+ header->partitionEntriesCRC = lendian_int (chksum_crc32(gpt,
header->numParts * header->sizeOfPartitionEntries));
header->headerCRC = lendian_int(chksum_crc32((uint8_t *)header,
@@ -896,7 +879,7 @@ initialise_apm(uint8_t *gpt, uint32_t start)
part->signature = bendian_short(0x504d);
part->map_count = bendian_int(apm_parts);
part->start_block = bendian_int(1);
- part->block_count = bendian_int(4);
+ part->block_count = bendian_int(0x10);
strcpy(part->name, "Apple");
strcpy(part->type, "Apple_partition_map");
part->data_start = bendian_int(0);
@@ -908,11 +891,11 @@ initialise_apm(uint8_t *gpt, uint32_t start)
part->signature = bendian_short(0x504d);
part->map_count = bendian_int(3);
part->start_block = bendian_int(efi_lba);
- part->block_count = bendian_int(efi_count / 4);
+ part->block_count = bendian_int(efi_count);
strcpy(part->name, "EFI");
strcpy(part->type, "Apple_HFS");
part->data_start = bendian_int(0);
- part->data_count = bendian_int(efi_count / 4);
+ part->data_count = bendian_int(efi_count);
part->status = bendian_int(0x33);
part = (struct apple_part_header *)(gpt + 4096);
@@ -922,11 +905,11 @@ initialise_apm(uint8_t *gpt, uint32_t start)
part->signature = bendian_short(0x504d);
part->map_count = bendian_int(3);
part->start_block = bendian_int(mac_lba);
- part->block_count = bendian_int(mac_count / 4);
+ part->block_count = bendian_int(mac_count);
strcpy(part->name, "EFI");
strcpy(part->type, "Apple_HFS");
part->data_start = bendian_int(0);
- part->data_count = bendian_int(mac_count / 4);
+ part->data_count = bendian_int(mac_count);
part->status = bendian_int(0x33);
} else {
part->signature = bendian_short(0x504d);
@@ -948,8 +931,10 @@ main(int argc, char *argv[])
FILE *fp = NULL;
uint8_t *buf = NULL, *bufz = NULL;
int cylsize = 0, frac = 0;
+ unsigned padding = 0;
size_t orig_gpt_size, free_space, gpt_size;
struct iso_primary_descriptor descriptor;
+ struct stat isostat;
prog = strcpy(alloca(strlen(argv[0]) + 1), argv[0]);
i = check_option(argc, argv);
@@ -962,8 +947,19 @@ main(int argc, char *argv[])
return 1;
}
- if ((mode & EFI) && offset)
- errx(1, "%s: --offset is invalid with UEFI images\n", argv[0]);
+ if (!(mode & (MODE_MBR | MODE_GPT))) {
+ mode |= (mode & EFI) ? MODE_GPT : MODE_MBR;
+ }
+
+ if ((mode & EFI) && !offset) type = 0;
+
+ part_data = 1;
+ if(mode & EFI) part_efi = 2;
+ if(mode & MAC) part_mac = 3;
+
+ if(entry) {
+ if(entry != part_efi && entry != part_mac) part_data = entry;
+ }
srand(time(NULL) << (getppid() << getpid()));
@@ -1014,7 +1010,23 @@ main(int argc, char *argv[])
if (!read_efi_section(buf)) {
buf += 32;
if (!read_efi_catalogue(buf, &efi_count, &efi_lba) && efi_lba) {
- offset = 0;
+ if(efi_count < 2) {
+ unsigned char bpb[512];
+
+ if (fseeko(fp, ((off_t)efi_lba * 2048), SEEK_SET)) {
+ err(1, "%s: seek error - 3", argv[0]);
+ }
+
+ if (fread(bpb, 1, sizeof bpb, fp) != sizeof bpb) {
+ err(1, "%s", argv[0]);
+ }
+
+ if((bpb[511] << 8) + bpb[510] == 0xaa55) {
+ unsigned s = bpb[19] + (bpb[20] << 8);
+ if(!s) s = bpb[32] + (bpb[33] << 8) + (bpb[34] << 16) + (bpb[35] << 24);
+ if(s) efi_count = s;
+ }
+ }
} else {
errx(1, "%s: invalid efi catalogue", argv[0]);
}
@@ -1030,7 +1042,6 @@ main(int argc, char *argv[])
if (!read_efi_section(buf)) {
buf += 32;
if (!read_efi_catalogue(buf, &mac_count, &mac_lba) && mac_lba) {
- offset = 0;
} else {
errx(1, "%s: invalid efi catalogue", argv[0]);
}
@@ -1052,27 +1063,55 @@ main(int argc, char *argv[])
"signature. Note that isolinux-debug.bin does not support " \
"hybrid booting", argv[0]);
+ if (offset && efi_lba && offset > efi_lba * 4)
+ {
+ part_efi = 1;
+ part_data = 2;
+ if (part_mac)
+ {
+ part_mac = 2;
+ part_data = 3;
+ }
+ }
+
if (stat(argv[0], &isostat))
err(1, "%s", argv[0]);
- isosize = lendian_int(descriptor.size) * lendian_short(descriptor.block_size);
- free_space = isostat.st_size - isosize;
+ iso_size = (off_t) lendian_int(descriptor.size) * lendian_short(descriptor.block_size);
+ free_space = isostat.st_size - iso_size;
cylsize = head * sector * 512;
frac = isostat.st_size % cylsize;
padding = (frac > 0) ? cylsize - frac : 0;
if (mode & VERBOSE)
- printf("imgsize: %zu, padding: %d\n", (size_t)isostat.st_size, padding);
+ printf("imgsize: %zu, padding: %d\n", (size_t)iso_filesize, padding);
- cc = c = ( isostat.st_size + padding) / cylsize;
+ c = (isostat.st_size + padding) / cylsize;
if (c > 1024)
{
warnx("Warning: more than 1024 cylinders: %d", c);
warnx("Not all BIOSes will be able to boot this device");
- cc = 1024;
}
+ /* 512 byte header, 128 entries of 128 bytes */
+ orig_gpt_size = gpt_size = 512 + (128 * 128);
+
+ /* Leave space for the APM if necessary */
+ if (mac_lba)
+ gpt_size += (4 * 2048);
+
+ /*
+ * We need to ensure that we have enough space for the secondary GPT.
+ * Unlike the primary, this doesn't need a hole for the APM. We still
+ * want to be 1MB aligned so just bump the padding by a megabyte.
+ */
+ if ((mode & MODE_GPT) && free_space < orig_gpt_size && padding < orig_gpt_size) {
+ padding += 1024 * 1024;
+ }
+
+ iso_filesize = isostat.st_size + padding;
+
if (!id)
{
if (fseeko(fp, (off_t) 440, SEEK_SET))
@@ -1094,6 +1133,16 @@ main(int argc, char *argv[])
buf = bufz;
memset(buf, 0, BUFSIZE);
+
+ if (fseeko(fp, 0, SEEK_SET))
+ err(1, "%s: seek error - 5", argv[0]);
+
+ /* clean up first 16 blocks */
+ for (i = 0; i < 16; i++) {
+ if (fwrite(buf, sizeof(char), BUFSIZE, fp) != BUFSIZE)
+ err(1, "%s: write error - 1", argv[0]);
+ }
+
i = initialise_mbr(buf);
if (mode & VERBOSE)
@@ -1105,40 +1154,20 @@ main(int argc, char *argv[])
if (fwrite(buf, sizeof(char), i, fp) != (size_t)i)
err(1, "%s: write error - 1", argv[0]);
- if (efi_lba) {
+ if (mode & MODE_GPT) {
+ /* always write primary gpt, if only to cleanup old data */
+ reverse_uuid(efi_system_partition);
reverse_uuid(basic_partition);
reverse_uuid(hfs_partition);
- /* 512 byte header, 128 entries of 128 bytes */
- orig_gpt_size = gpt_size = 512 + (128 * 128);
-
- /* Leave space for the APM if necessary */
- if (mac_lba)
- gpt_size += (4 * 2048);
-
buf = calloc(gpt_size, sizeof(char));
memset(buf, 0, gpt_size);
- /*
- * We need to ensure that we have enough space for the secondary GPT.
- * Unlike the primary, this doesn't need a hole for the APM. We still
- * want to be 1MB aligned so just bump the padding by a megabyte.
- */
- if (free_space < orig_gpt_size && padding < orig_gpt_size) {
- padding += 1024 * 1024;
- }
-
- /*
- * Determine the size of the ISO filesystem. This will define the size
- * of the partition that covers it.
- */
- psize = isosize / 512;
-
/*
* Primary GPT starts at sector 1, secondary GPT starts at 1 sector
* before the end of the image
*/
- initialise_gpt(buf, 1, (isostat.st_size + padding - 512) / 512, 1);
+ initialise_gpt(buf, 1, iso_filesize / 512 - 1, 1);
if (fseeko(fp, (off_t) 512, SEEK_SET))
err(1, "%s: seek error - 6", argv[0]);
@@ -1166,17 +1195,17 @@ main(int argc, char *argv[])
if (fsync(fileno(fp)))
err(1, "%s: could not synchronise", argv[0]);
- if (ftruncate(fileno(fp), isostat.st_size + padding))
+ if (ftruncate(fileno(fp), iso_filesize))
err(1, "%s: could not add padding bytes", argv[0]);
}
- if (efi_lba) {
+ if (mode & MODE_GPT) {
buf = realloc(buf, orig_gpt_size);
memset(buf, 0, orig_gpt_size);
buf += orig_gpt_size - sizeof(struct gpt_header);
- initialise_gpt(buf, (isostat.st_size + padding - 512) / 512, 1, 0);
+ initialise_gpt(buf, iso_filesize / 512 - 1, 1, 0);
/* Shift back far enough to write the 128 GPT entries */
buf -= 128 * sizeof(struct gpt_part_header);
@@ -1186,7 +1215,7 @@ main(int argc, char *argv[])
* end of the image
*/
- if (fseeko(fp, (isostat.st_size + padding) - orig_gpt_size, SEEK_SET))
+ if (fseeko(fp, iso_filesize - orig_gpt_size, SEEK_SET))
err(1, "%s: seek error - 8", argv[0]);
if (fwrite(buf, sizeof(char), orig_gpt_size, fp) != orig_gpt_size)
diff --git a/utils/isohybrid.h b/utils/isohybrid.h
index eecf1caa..157f6e1d 100644
--- a/utils/isohybrid.h
+++ b/utils/isohybrid.h
@@ -20,7 +20,7 @@
*
*/
-#define VERSION "0.12"
+#define VERSION "0.12.1"
#define BUFSIZE 2048
#define MBRSIZE 432
--
2.42.0