allow each partition to have its own align value

For partitions in the partition table, this defaults to the image's
alignment value, while partitions not listed there use a value of 1,
i.e. no particular alignment requirements.

Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
This commit is contained in:
Rasmus Villemoes 2021-01-10 22:54:22 +01:00 committed by Michael Olbrich
parent cf192fd98d
commit 030e7a3c2e
4 changed files with 18 additions and 5 deletions

View File

@ -111,6 +111,9 @@ Partition options:
:size: The size of this partition in bytes. If the size and
autoresize are both not set then the size of the partition
image is used.
:align: Alignment value to use for automatic computation of ``offset``
and ``size``. Defaults to 1 for partitions not in the partition
table, otherwise to the image's ``align`` value.
:partition-type: Used by dos partition tables to specify the partition type. Using
this option with a GPT partition table will create a hybrid MBR partition
table with a maximum of 3 partition entries(this limit does not effect the

View File

@ -91,6 +91,7 @@ static int image_set_handler(struct image *image, cfg_t *cfg)
static cfg_opt_t partition_opts[] = {
CFG_STR("offset", NULL, CFGF_NONE),
CFG_STR("size", NULL, CFGF_NONE),
CFG_STR("align", NULL, CFGF_NONE),
CFG_INT("partition-type", 0, CFGF_NONE),
CFG_BOOL("bootable", cfg_false, CFGF_NONE),
CFG_BOOL("read-only", cfg_false, CFGF_NONE),
@ -314,6 +315,7 @@ static int parse_partitions(struct image *image, cfg_t *imagesec)
list_add_tail(&part->list, &image->partitions);
part->size = cfg_getint_suffix(partsec, "size");
part->offset = cfg_getint_suffix(partsec, "offset");
part->align = cfg_getint_suffix(partsec, "align");
part->partition_type = cfg_getint(partsec, "partition-type");
part->bootable = cfg_getbool(partsec, "bootable");
part->read_only = cfg_getbool(partsec, "read-only");

View File

@ -34,6 +34,7 @@ struct mountpoint {
struct partition {
unsigned long long offset;
unsigned long long size;
unsigned long long align;
unsigned char partition_type;
cfg_bool_t bootable;
cfg_bool_t extended;

View File

@ -515,6 +515,13 @@ static int hdimage_setup(struct image *image, cfg_t *cfg)
list_for_each_entry(part, &image->partitions, list) {
if (part->in_partition_table)
++partition_table_entries;
if (!part->align)
part->align = part->in_partition_table ? hd->align : 1;
if (part->in_partition_table && part->align % hd->align) {
image_error(image, "partition alignment (%lld) of partition %s "
"must be multiple of image alignment (%lld)",
part->align, part->name, hd->align);
}
}
if (!hd->gpt && !hd->extended_partition && partition_table_entries > 4)
hd->extended_partition = 4;
@ -600,13 +607,13 @@ static int hdimage_setup(struct image *image, cfg_t *cfg)
if (part->extended) {
if (!hd->extended_lba)
hd->extended_lba = now;
now = roundup(now, hd->align);
now += hd->align;
now = roundup(now, part->align);
}
if (part->in_partition_table && (part->offset % hd->align)) {
if (part->in_partition_table && (part->offset % part->align)) {
image_error(image, "part %s offset (%lld) must be a"
"multiple of %lld bytes\n",
part->name, part->offset, hd->align);
part->name, part->offset, part->align);
return -EINVAL;
}
if (part->offset && part->in_partition_table) {
@ -616,7 +623,7 @@ static int hdimage_setup(struct image *image, cfg_t *cfg)
return -EINVAL;
}
} else if (!part->offset && part->in_partition_table) {
part->offset = roundup(now, hd->align);
part->offset = roundup(now, part->align);
}
if (autoresize) {
long long partsize = image->size - part->offset;
@ -637,7 +644,7 @@ static int hdimage_setup(struct image *image, cfg_t *cfg)
}
if (!part->size) {
if (part->in_partition_table)
part->size = roundup(child->size, hd->align);
part->size = roundup(child->size, part->align);
else
part->size = child->size;
} else if (child->size > part->size) {