summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMikhail Kshevetskiy2024-12-30 03:44:59 +0000
committerDaniel Golle2025-09-23 22:15:33 +0000
commit9fa340db640eda0b998d7ba2b24727284d6f12c2 (patch)
treef2a5274f50bc86379475bf267f4539e06f318356
parent78d8084c737692c3e0924762f8bc1fa80268c4f4 (diff)
downloadfirmware-utils-9fa340db640eda0b998d7ba2b24727284d6f12c2.tar.gz
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 <mikhail.kshevetskiy@iopsys.eu>
-rw-r--r--src/ptgen.c52
1 files changed, 46 insertions, 6 deletions
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 <heads> -s <sectors> -o <outputfile>\n"
+ fprintf(stderr, "Usage: %s [-v] [-n] [-b] [-g] -h <heads> -s <sectors> -o <outputfile>\n"
" [-a <part number>] [-l <align kB>] [-G <guid>]\n"
" [-e <gpt_entry_offset>] [-d <gpt_disk_size>]\n"
" [[-t <type> | -T <GPT part type>] [-r] [-N <name>] -p <size>[@<start>]...] \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;