Index: usr.bin/mkimg/mkimg.c =================================================================== --- usr.bin/mkimg/mkimg.c +++ usr.bin/mkimg/mkimg.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -170,13 +171,14 @@ print_schemes(1); fputc('\n', stderr); fprintf(stderr, " partition specification:\n"); - fprintf(stderr, "\t[/]::\t- empty partition of given " - "size\n"); - fprintf(stderr, "\t[/]:=\t- partition content and size " - "are determined\n\t\t\t\t by the named file\n"); - fprintf(stderr, "\t[/]:-\t- partition content and size " - "are taken from\n\t\t\t\t the output of the command to run\n"); - fprintf(stderr, "\t-\t\t\t- unused partition entry\n"); + fprintf(stderr, "\t[/]::[:[+]]\t- " + "empty partition of given size and\n\t\t\t\t\t" + " optional relative or absolute offset\n"); + fprintf(stderr, "\t[/]:=\t\t- partition content and size " + "are\n\t\t\t\t\t determined by the named file\n"); + fprintf(stderr, "\t[/]:-\t\t- partition content and size " + "are taken\n\t\t\t\t\t from the output of the command to run\n"); + fprintf(stderr, "\t-\t\t\t\t- unused partition entry\n"); fprintf(stderr, "\t where:\n"); fprintf(stderr, "\t\t\t- scheme neutral partition type\n"); fprintf(stderr, "\t\t\t- optional scheme-dependent partition " @@ -401,8 +403,10 @@ { FILE *fp; struct part *part; - lba_t block; - off_t bytesize; + lba_t block, blkoffset; + off_t bytesize, byteoffset; + char *size, *offset; + bool abs_offset; int error, fd; /* First check partition information */ @@ -413,16 +417,27 @@ } block = scheme_metadata(SCHEME_META_IMG_START, 0); + abs_offset = false; TAILQ_FOREACH(part, &partlist, link) { - block = scheme_metadata(SCHEME_META_PART_BEFORE, block); + if (!abs_offset) + block = scheme_metadata(SCHEME_META_PART_BEFORE, block); if (verbose) fprintf(stderr, "partition %d: starting block %llu " "... ", part->index + 1, (long long)block); part->block = block; + byteoffset = blkoffset = 0; + abs_offset = false; switch (part->kind) { case PART_KIND_SIZE: - if (expand_number(part->contents, &bytesize) == -1) + offset = part->contents; + size = strsep(&offset, ":"); + if (*offset != '+') + abs_offset = true; + if (expand_number(size, &bytesize) == -1) error = errno; + if (offset != NULL) + if (expand_number(offset, &byteoffset) == -1) + error = errno; break; case PART_KIND_FILE: fd = open(part->contents, O_RDONLY, 0); @@ -445,13 +460,32 @@ if (error) errc(EX_IOERR, error, "partition %d", part->index + 1); part->size = (bytesize + secsz - 1) / secsz; + blkoffset = (byteoffset + secsz - 1) / secsz; + if (abs_offset) { + part->block = blkoffset; + } else { + part->block += blkoffset; + } if (verbose) { bytesize = part->size * secsz; fprintf(stderr, "size %llu bytes (%llu blocks)\n", (long long)bytesize, (long long)part->size); + if (abs_offset) { + fprintf(stderr, + " location %llu bytes (%llu blocks)\n", + (long long)byteoffset, + (long long)blkoffset); + } else if (blkoffset > 0) { + fprintf(stderr, + " offset %llu bytes (%llu blocks)\n", + (long long)byteoffset, + (long long)blkoffset); + } + } + if (!abs_offset) { + block = scheme_metadata(SCHEME_META_PART_AFTER, + part->block + part->size); } - block = scheme_metadata(SCHEME_META_PART_AFTER, - part->block + part->size); } block = scheme_metadata(SCHEME_META_IMG_END, block);