mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-11-07 04:36:52 -10:00
mkimg: Add per-partition alignment
This adds a "%align" field to partition specifications, resulting in the start of a partition being shifted to the next aligned position. When both :offset and %align are used, a relative offset is treated as a minimum value, while an unaligned absolute offset is an error. Reviewed by: imp (earlier version) MFC after: 1 week Sponsored by: Amazon Differential Revision: https://reviews.freebsd.org/D60450
This commit is contained in:
1 parent
e7f84fe6cf
commit
729883c93e
1 file changed
+50
-12
+50
-12
@@ -178,13 +178,15 @@ usage(const char *why)
|
||||
print_schemes(1);
|
||||
fputc('\n', stderr);
|
||||
fprintf(stderr, " partition specification:\n");
|
||||
fprintf(stderr, "\t<type>[/<label>]::<size>[:[+]<offset>]\t- "
|
||||
"empty partition of given size and\n\t\t\t\t\t"
|
||||
" optional relative or absolute offset\n");
|
||||
fprintf(stderr, "\t<type>[/<label>]:=<file>[:[+]offset]\t- partition "
|
||||
"content and size are\n\t\t\t\t\t"
|
||||
" determined by the named file and\n"
|
||||
"\t\t\t\t\t optional relative or absolute offset\n");
|
||||
fprintf(stderr, "\t<type>[/<label>]::<size>[:[+]<offset>][%%<align>]\n"
|
||||
"\t\t\t\t\t- empty partition of given size and\n"
|
||||
"\t\t\t\t\t optional relative or absolute offset\n"
|
||||
"\t\t\t\t\t and alignment\n");
|
||||
fprintf(stderr, "\t<type>[/<label>]:=<file>[:[+]<offset>][%%<align>]\n"
|
||||
"\t\t\t\t\t- partition content and size are\n"
|
||||
"\t\t\t\t\t determined by the named file and\n"
|
||||
"\t\t\t\t\t optional relative or absolute offset\n"
|
||||
"\t\t\t\t\t and alignment\n");
|
||||
fprintf(stderr, "\t<type>[/<label>]:-<cmd>\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");
|
||||
@@ -448,9 +450,9 @@ mkimg(void)
|
||||
struct part *part;
|
||||
struct stat sb;
|
||||
char *p;
|
||||
lba_t block, blkoffset;
|
||||
uint64_t bytesize, byteoffset;
|
||||
char *size, *offset;
|
||||
lba_t block, blkoffset, blkalign;
|
||||
uint64_t bytesize, byteoffset, bytealign;
|
||||
char *size, *offset, *align;
|
||||
bool abs_offset;
|
||||
int error, fd;
|
||||
|
||||
@@ -466,10 +468,16 @@ mkimg(void)
|
||||
TAILQ_FOREACH(part, &partlist, link) {
|
||||
byteoffset = blkoffset = 0;
|
||||
abs_offset = false;
|
||||
align = NULL;
|
||||
|
||||
/* Look for an offset. Set size too if we can. */
|
||||
switch (part->kind) {
|
||||
case PART_KIND_SIZE:
|
||||
p = strrchr(part->contents, '%');
|
||||
if (p != NULL) {
|
||||
*p = '\0';
|
||||
align = p + 1;
|
||||
}
|
||||
offset = part->contents;
|
||||
size = strsep(&offset, ":");
|
||||
if (expand_number(size, &bytesize) == -1)
|
||||
@@ -477,6 +485,13 @@ mkimg(void)
|
||||
break;
|
||||
case PART_KIND_FILE:
|
||||
size = part->contents;
|
||||
if (stat(part->contents, &sb) == -1) {
|
||||
p = strrchr(part->contents, '%');
|
||||
if (p != NULL) {
|
||||
*p = '\0';
|
||||
align = p + 1;
|
||||
}
|
||||
}
|
||||
if (stat(part->contents, &sb) == 0) {
|
||||
if (S_ISDIR(sb.st_mode)) {
|
||||
errc(EX_IOERR, EISDIR, "partition %d",
|
||||
@@ -498,6 +513,18 @@ mkimg(void)
|
||||
break;
|
||||
}
|
||||
|
||||
if (align != NULL) {
|
||||
if (expand_number(align, &bytealign) == -1)
|
||||
err(EX_DATAERR, "partition %d",
|
||||
part->index + 1);
|
||||
if ((bytealign == 0) || (bytealign % secsz != 0))
|
||||
errx(EX_DATAERR, "partition %d: "
|
||||
"invalid alignment", part->index + 1);
|
||||
blkalign = bytealign / secsz;
|
||||
} else {
|
||||
blkalign = 1;
|
||||
}
|
||||
|
||||
if (offset != NULL) {
|
||||
if (*offset != '+')
|
||||
abs_offset = true;
|
||||
@@ -509,12 +536,17 @@ mkimg(void)
|
||||
|
||||
/* Work out exactly where the partition starts. */
|
||||
blkoffset = (byteoffset + secsz - 1) / secsz;
|
||||
if (abs_offset)
|
||||
if (abs_offset) {
|
||||
block = scheme_metadata(SCHEME_META_PART_ABSOLUTE,
|
||||
blkoffset);
|
||||
else
|
||||
if (block % blkalign)
|
||||
errx(EX_DATAERR, "partition %d: absolute "
|
||||
"offset incompatible with alignment",
|
||||
part->index + 1);
|
||||
} else
|
||||
block = scheme_metadata(SCHEME_META_PART_BEFORE,
|
||||
block + blkoffset);
|
||||
block = ((block + blkalign - 1) / blkalign) * blkalign;
|
||||
part->block = block;
|
||||
|
||||
if (verbose)
|
||||
@@ -559,6 +591,12 @@ mkimg(void)
|
||||
(long long)byteoffset,
|
||||
(long long)blkoffset);
|
||||
}
|
||||
if (blkalign > 1) {
|
||||
fprintf(stderr,
|
||||
" alignment %llu bytes (%llu blocks)\n",
|
||||
(long long)bytealign,
|
||||
(long long)blkalign);
|
||||
}
|
||||
}
|
||||
block = scheme_metadata(SCHEME_META_PART_AFTER,
|
||||
part->block + part->size);
|
||||
|
||||
Reference in new issue
Block a user