aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rw-r--r--make_helpers/defaults.mk3
-rw-r--r--tools/fiptool/fiptool.c52
3 files changed, 54 insertions, 5 deletions
diff --git a/Makefile b/Makefile
index e9a07840e..001e94b8c 100644
--- a/Makefile
+++ b/Makefile
@@ -350,6 +350,10 @@ ifeq (${ENABLE_PSCI_STAT},1)
ENABLE_PMF := 1
endif
+ifneq (${FIP_ALIGN},0)
+FIP_ARGS += --align ${FIP_ALIGN}
+endif
+
################################################################################
# Auxiliary tools (fiptool, cert_create, etc)
################################################################################
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index fc39819d7..0b93dfcac 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -89,6 +89,9 @@ ENABLE_RUNTIME_INSTRUMENTATION := 0
# Build flag to treat usage of deprecated platform and framework APIs as error.
ERROR_DEPRECATED := 0
+# Byte alignment that each component in FIP is aligned to
+FIP_ALIGN := 0
+
# Default FIP file name
FIP_NAME := fip.bin
diff --git a/tools/fiptool/fiptool.c b/tools/fiptool/fiptool.c
index 6288cbfd4..865aeae1d 100644
--- a/tools/fiptool/fiptool.c
+++ b/tools/fiptool/fiptool.c
@@ -50,6 +50,7 @@
#define OPT_TOC_ENTRY 0
#define OPT_PLAT_TOC_FLAGS 1
+#define OPT_ALIGN 2
static image_desc_t *lookup_image_desc_from_uuid(const uuid_t *uuid);
static image_t *lookup_image_from_uuid(const uuid_t *uuid);
@@ -591,7 +592,7 @@ static void info_usage(void)
exit(1);
}
-static int pack_images(const char *filename, uint64_t toc_flags)
+static int pack_images(const char *filename, uint64_t toc_flags, unsigned long align)
{
FILE *fp;
image_t *image;
@@ -617,6 +618,7 @@ static int pack_images(const char *filename, uint64_t toc_flags)
entry_offset = buf_size;
for (image = image_head; image != NULL; image = image->next) {
payload_size += image->toc_e.size;
+ entry_offset = (entry_offset + align - 1) & ~(align - 1);
image->toc_e.offset_address = entry_offset;
*toc_entry++ = image->toc_e;
entry_offset += image->toc_e.size;
@@ -640,8 +642,12 @@ static int pack_images(const char *filename, uint64_t toc_flags)
if (verbose)
log_dbgx("Payload size: %zu bytes", payload_size);
- for (image = image_head; image != NULL; image = image->next)
+ for (image = image_head; image != NULL; image = image->next) {
+ if (fseek(fp, image->toc_e.offset_address, SEEK_SET))
+ log_errx("Failed to set file position");
+
xfwrite(image->buffer, image->toc_e.size, fp, filename);
+ }
fclose(fp);
return 0;
@@ -697,6 +703,24 @@ static void parse_plat_toc_flags(const char *arg, unsigned long long *toc_flags)
*toc_flags |= flags << 32;
}
+static int is_power_of_2(unsigned long x)
+{
+ return x && !(x & (x - 1));
+}
+
+static unsigned long get_image_align(char *arg)
+{
+ char *endptr;
+ unsigned long align;
+
+ errno = 0;
+ align = strtoul(arg, &endptr, 10);
+ if (*endptr != '\0' || !is_power_of_2(align) || errno != 0)
+ log_errx("Invalid alignment: %s", arg);
+
+ return align;
+}
+
static void parse_blob_opt(char *arg, uuid_t *uuid, char *filename, size_t len)
{
char *p;
@@ -717,6 +741,7 @@ static int create_cmd(int argc, char *argv[])
struct option *opts = NULL;
size_t nr_opts = 0;
unsigned long long toc_flags = 0;
+ unsigned long align = 1;
if (argc < 2)
create_usage();
@@ -724,6 +749,7 @@ static int create_cmd(int argc, char *argv[])
opts = fill_common_opts(opts, &nr_opts, required_argument);
opts = add_opt(opts, &nr_opts, "plat-toc-flags", required_argument,
OPT_PLAT_TOC_FLAGS);
+ opts = add_opt(opts, &nr_opts, "align", required_argument, OPT_ALIGN);
opts = add_opt(opts, &nr_opts, "blob", required_argument, 'b');
opts = add_opt(opts, &nr_opts, NULL, 0, 0);
@@ -745,6 +771,9 @@ static int create_cmd(int argc, char *argv[])
case OPT_PLAT_TOC_FLAGS:
parse_plat_toc_flags(optarg, &toc_flags);
break;
+ case OPT_ALIGN:
+ align = get_image_align(optarg);
+ break;
case 'b': {
char name[_UUID_STR_LEN + 1];
char filename[PATH_MAX] = { 0 };
@@ -780,7 +809,7 @@ static int create_cmd(int argc, char *argv[])
update_fip();
- pack_images(argv[0], toc_flags);
+ pack_images(argv[0], toc_flags, align);
free_images();
return 0;
}
@@ -792,6 +821,7 @@ static void create_usage(void)
printf("fiptool create [opts] FIP_FILENAME\n");
printf("\n");
printf("Options:\n");
+ printf(" --align <value>\t\tEach image is aligned to <value> (default: 1).\n");
printf(" --blob uuid=...,file=...\tAdd an image with the given UUID "
"pointed to by file.\n");
printf(" --plat-toc-flags <value>\t16-bit platform specific flag field "
@@ -811,12 +841,14 @@ static int update_cmd(int argc, char *argv[])
char outfile[PATH_MAX] = { 0 };
fip_toc_header_t toc_header = { 0 };
unsigned long long toc_flags = 0;
+ unsigned long align = 1;
int pflag = 0;
if (argc < 2)
update_usage();
opts = fill_common_opts(opts, &nr_opts, required_argument);
+ opts = add_opt(opts, &nr_opts, "align", required_argument, OPT_ALIGN);
opts = add_opt(opts, &nr_opts, "blob", required_argument, 'b');
opts = add_opt(opts, &nr_opts, "out", required_argument, 'o');
opts = add_opt(opts, &nr_opts, "plat-toc-flags", required_argument,
@@ -864,6 +896,9 @@ static int update_cmd(int argc, char *argv[])
set_image_desc_action(desc, DO_PACK, filename);
break;
}
+ case OPT_ALIGN:
+ align = get_image_align(optarg);
+ break;
case 'o':
snprintf(outfile, sizeof(outfile), "%s", optarg);
break;
@@ -890,7 +925,7 @@ static int update_cmd(int argc, char *argv[])
update_fip();
- pack_images(outfile, toc_flags);
+ pack_images(outfile, toc_flags, align);
free_images();
return 0;
}
@@ -902,6 +937,7 @@ static void update_usage(void)
printf("fiptool update [opts] FIP_FILENAME\n");
printf("\n");
printf("Options:\n");
+ printf(" --align <value>\t\tEach image is aligned to <value> (default: 1).\n");
printf(" --blob uuid=...,file=...\tAdd or update an image "
"with the given UUID pointed to by file.\n");
printf(" --out FIP_FILENAME\t\tSet an alternative output FIP file.\n");
@@ -1062,12 +1098,14 @@ static int remove_cmd(int argc, char *argv[])
char outfile[PATH_MAX] = { 0 };
fip_toc_header_t toc_header;
image_desc_t *desc;
+ unsigned long align = 1;
int fflag = 0;
if (argc < 2)
remove_usage();
opts = fill_common_opts(opts, &nr_opts, no_argument);
+ opts = add_opt(opts, &nr_opts, "align", required_argument, OPT_ALIGN);
opts = add_opt(opts, &nr_opts, "blob", required_argument, 'b');
opts = add_opt(opts, &nr_opts, "force", no_argument, 'f');
opts = add_opt(opts, &nr_opts, "out", required_argument, 'o');
@@ -1088,6 +1126,9 @@ static int remove_cmd(int argc, char *argv[])
set_image_desc_action(desc, DO_REMOVE, NULL);
break;
}
+ case OPT_ALIGN:
+ align = get_image_align(optarg);
+ break;
case 'b': {
char name[_UUID_STR_LEN + 1], filename[PATH_MAX];
uuid_t uuid = { 0 };
@@ -1152,7 +1193,7 @@ static int remove_cmd(int argc, char *argv[])
}
}
- pack_images(outfile, toc_header.flags);
+ pack_images(outfile, toc_header.flags, align);
free_images();
return 0;
}
@@ -1164,6 +1205,7 @@ static void remove_usage(void)
printf("fiptool remove [opts] FIP_FILENAME\n");
printf("\n");
printf("Options:\n");
+ printf(" --align <value>\tEach image is aligned to <value> (default: 1).\n");
printf(" --blob uuid=...\tRemove an image with the given UUID.\n");
printf(" --force\t\tIf the output FIP file already exists, use --force to "
"overwrite it.\n");