From: Mikhail Kshevetskiy Date: Mon, 30 Dec 2024 03:44:59 +0000 (+0300) Subject: ptgen: create separate images for gpt data structure X-Git-Url: http://git.openwrt.org/?a=commitdiff_plain;h=9fa340db640eda0b998d7ba2b24727284d6f12c2;p=project%2Ffirmware-utils.git ptgen: create separate images for gpt data structure This patch creates 2 or 3 gpt images: image.start: PMBR + GPT Header image.entry: GPT Entry Table image.end: GPT Entry Table + Alternative GPT HEADER If GPT Entry table follow GPT Header without gap, then image.entry will be joined to the end of image.start file. Signed-off-by: Mikhail Kshevetskiy --- diff --git a/src/ptgen.c b/src/ptgen.c index d675abd..d9fb744 100644 --- a/src/ptgen.c +++ b/src/ptgen.c @@ -172,6 +172,7 @@ bool use_guid_partition_table = false; struct partinfo parts[GPT_ENTRY_MAX]; char *filename = NULL; +int gpt_split_image = false; int gpt_alternate = false; uint64_t gpt_first_entry_sector = GPT_FIRST_ENTRY_SECTOR; uint64_t gpt_last_usable_sector = 0; @@ -422,6 +423,7 @@ static int gen_gptable(uint32_t signature, guid_t guid, unsigned nr) uint64_t sect = GPT_SIZE + gpt_first_entry_sector; int fd, ret = -1; unsigned i, pmbr = 1; + char img_name[strlen(filename) + 20]; memset(pte, 0, sizeof(struct pte) * MBR_ENTRY_MAX); memset(gpte, 0, GPT_ENTRY_SIZE * GPT_ENTRY_MAX); @@ -516,8 +518,13 @@ static int gen_gptable(uint32_t signature, guid_t guid, unsigned nr) fprintf(stderr, "PartitionEntryLBA=%" PRIu64 ", FirstUsableLBA=%" PRIu64 ", LastUsableLBA=%" PRIu64 "\n", gpt_first_entry_sector, gpt_first_entry_sector + GPT_SIZE, gpt_last_usable_sector); - if ((fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0) { - fprintf(stderr, "Can't open output file '%s'\n",filename); + if (!gpt_split_image) + strcpy(img_name, filename); + else + snprintf(img_name, sizeof(img_name), "%s.start", filename); + + if ((fd = open(img_name, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0) { + fprintf(stderr, "Can't open output file '%s'\n",img_name); return ret; } @@ -544,7 +551,24 @@ static int gen_gptable(uint32_t signature, guid_t guid, unsigned nr) goto fail; } - lseek(fd, gpt_first_entry_sector * DISK_SECTOR_SIZE, SEEK_SET); + lseek(fd, 2 * DISK_SECTOR_SIZE - 1, SEEK_SET); + if (write(fd, "\x00", 1) != 1) { + fputs("write failed.\n", stderr); + goto fail; + } + + if (!gpt_split_image || (gpt_first_entry_sector == GPT_FIRST_ENTRY_SECTOR)) { + lseek(fd, gpt_first_entry_sector * DISK_SECTOR_SIZE, SEEK_SET); + } else { + close(fd); + + snprintf(img_name, sizeof(img_name), "%s.entry", filename); + if ((fd = open(img_name, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0) { + fprintf(stderr, "Can't open output file '%s'\n",img_name); + return ret; + } + } + if (write(fd, &gpte, GPT_ENTRY_SIZE * GPT_ENTRY_MAX) != GPT_ENTRY_SIZE * GPT_ENTRY_MAX) { fputs("write failed.\n", stderr); goto fail; @@ -557,7 +581,19 @@ static int gen_gptable(uint32_t signature, guid_t guid, unsigned nr) gpth.crc32 = 0; gpth.crc32 = cpu_to_le32(gpt_crc32(&gpth, GPT_HEADER_SIZE)); - lseek(fd, end * DISK_SECTOR_SIZE - GPT_ENTRY_SIZE * GPT_ENTRY_MAX, SEEK_SET); + if (!gpt_split_image) { + lseek(fd, end * DISK_SECTOR_SIZE - GPT_ENTRY_SIZE * GPT_ENTRY_MAX, SEEK_SET); + } else { + close(fd); + + end = GPT_SIZE; + snprintf(img_name, sizeof(img_name), "%s.end", filename); + if ((fd = open(img_name, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0) { + fprintf(stderr, "Can't open output file '%s'\n",img_name); + return ret; + } + } + if (write(fd, &gpte, GPT_ENTRY_SIZE * GPT_ENTRY_MAX) != GPT_ENTRY_SIZE * GPT_ENTRY_MAX) { fputs("write failed.\n", stderr); goto fail; @@ -583,7 +619,7 @@ fail: static void usage(char *prog) { - fprintf(stderr, "Usage: %s [-v] [-n] [-g] -h -s -o \n" + fprintf(stderr, "Usage: %s [-v] [-n] [-b] [-g] -h -s -o \n" " [-a ] [-l ] [-G ]\n" " [-e ] [-d ]\n" " [[-t | -T ] [-r] [-N ] -p [@]...] \n", prog); @@ -625,7 +661,7 @@ int main (int argc, char **argv) guid_t guid = GUID_INIT( signature, 0x2211, 0x4433, \ 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0x00); - while ((ch = getopt(argc, argv, "h:s:p:a:t:T:o:vnHN:gl:rS:G:e:d:")) != -1) { + while ((ch = getopt(argc, argv, "h:s:p:a:t:T:o:vnbHN:gl:rS:G:e:d:")) != -1) { switch (ch) { case 'o': filename = optarg; @@ -669,6 +705,10 @@ int main (int argc, char **argv) gpt_last_usable_sector = total_sectors - GPT_SIZE - 2; } break; + case 'b': + gpt_alternate = true; + gpt_split_image = true; + break; case 'h': heads = (int)strtoul(optarg, NULL, 0); break;