Commit b04efcce authored by dp-arm's avatar dp-arm
Browse files

fiptool: Link `toc_entry` and `image` structures via UUID



The `toc_entry` and `image` data structures had a cyclic
relationship.  This patch removes the explicit dependencies and introduces
functions to link them via the UUID.

This change highlights the intent of the code better and makes it more
flexible for future enhancements.

Change-Id: I0c3dd7bfda2a631a3827c8ba4831849c500affe9
Signed-off-by: default avatardp-arm <dimitris.papastamos@arm.com>
parent 6bb37adc
...@@ -187,7 +187,7 @@ static void free_images(void) ...@@ -187,7 +187,7 @@ static void free_images(void)
} }
} }
static toc_entry_t *get_entry_lookup_from_uuid(const uuid_t *uuid) static toc_entry_t *lookup_entry_from_uuid(uuid_t *uuid)
{ {
toc_entry_t *toc_entry = toc_entries; toc_entry_t *toc_entry = toc_entries;
...@@ -197,6 +197,19 @@ static toc_entry_t *get_entry_lookup_from_uuid(const uuid_t *uuid) ...@@ -197,6 +197,19 @@ static toc_entry_t *get_entry_lookup_from_uuid(const uuid_t *uuid)
return NULL; return NULL;
} }
static image_t *lookup_image_from_uuid(uuid_t *uuid)
{
image_t *image;
int i;
for (i = 0; i < nr_images; i++) {
image = images[i];
if (memcmp(&image->uuid, uuid, sizeof(uuid_t)) == 0)
return image;
}
return NULL;
}
static int parse_fip(char *filename, fip_toc_header_t *toc_header_out) static int parse_fip(char *filename, fip_toc_header_t *toc_header_out)
{ {
struct stat st; struct stat st;
...@@ -268,16 +281,6 @@ static int parse_fip(char *filename, fip_toc_header_t *toc_header_out) ...@@ -268,16 +281,6 @@ static int parse_fip(char *filename, fip_toc_header_t *toc_header_out)
toc_entry->size); toc_entry->size);
image->size = toc_entry->size; image->size = toc_entry->size;
image->toc_entry = get_entry_lookup_from_uuid(&toc_entry->uuid);
if (image->toc_entry == NULL) {
add_image(image);
toc_entry++;
continue;
}
assert(image->toc_entry->image == NULL);
/* Link backpointer from lookup entry. */
image->toc_entry->image = image;
add_image(image); add_image(image);
toc_entry++; toc_entry++;
...@@ -290,12 +293,14 @@ static int parse_fip(char *filename, fip_toc_header_t *toc_header_out) ...@@ -290,12 +293,14 @@ static int parse_fip(char *filename, fip_toc_header_t *toc_header_out)
return 0; return 0;
} }
static image_t *read_image_from_file(toc_entry_t *toc_entry, char *filename) static image_t *read_image_from_file(uuid_t *uuid, char *filename)
{ {
struct stat st; struct stat st;
image_t *image; image_t *image;
FILE *fp; FILE *fp;
assert(uuid != NULL);
fp = fopen(filename, "r"); fp = fopen(filename, "r");
if (fp == NULL) if (fp == NULL)
log_err("fopen %s", filename); log_err("fopen %s", filename);
...@@ -307,7 +312,7 @@ static image_t *read_image_from_file(toc_entry_t *toc_entry, char *filename) ...@@ -307,7 +312,7 @@ static image_t *read_image_from_file(toc_entry_t *toc_entry, char *filename)
if (image == NULL) if (image == NULL)
log_err("malloc"); log_err("malloc");
memcpy(&image->uuid, &toc_entry->uuid, sizeof(uuid_t)); memcpy(&image->uuid, uuid, sizeof(uuid_t));
image->buffer = malloc(st.st_size); image->buffer = malloc(st.st_size);
if (image->buffer == NULL) if (image->buffer == NULL)
...@@ -315,7 +320,6 @@ static image_t *read_image_from_file(toc_entry_t *toc_entry, char *filename) ...@@ -315,7 +320,6 @@ static image_t *read_image_from_file(toc_entry_t *toc_entry, char *filename)
if (fread(image->buffer, 1, st.st_size, fp) != st.st_size) if (fread(image->buffer, 1, st.st_size, fp) != st.st_size)
log_errx("Failed to read %s", filename); log_errx("Failed to read %s", filename);
image->size = st.st_size; image->size = st.st_size;
image->toc_entry = toc_entry;
fclose(fp); fclose(fp);
return image; return image;
...@@ -391,18 +395,21 @@ static int info_cmd(int argc, char *argv[]) ...@@ -391,18 +395,21 @@ static int info_cmd(int argc, char *argv[])
(sizeof(fip_toc_entry_t) * (nr_images + 1)); (sizeof(fip_toc_entry_t) * (nr_images + 1));
for (i = 0; i < nr_images; i++) { for (i = 0; i < nr_images; i++) {
toc_entry_t *toc_entry;
image = images[i]; image = images[i];
if (image->toc_entry != NULL) toc_entry = lookup_entry_from_uuid(&image->uuid);
printf("%s: ", image->toc_entry->name); if (toc_entry != NULL)
printf("%s: ", toc_entry->name);
else else
printf("Unknown entry: "); printf("Unknown entry: ");
image_size = image->size; image_size = image->size;
printf("offset=0x%llX, size=0x%llX", printf("offset=0x%llX, size=0x%llX",
(unsigned long long)image_offset, (unsigned long long)image_offset,
(unsigned long long)image_size); (unsigned long long)image_size);
if (image->toc_entry != NULL) if (toc_entry != NULL)
printf(", cmdline=\"--%s\"", printf(", cmdline=\"--%s\"",
image->toc_entry->cmdline_name); toc_entry->cmdline_name);
if (verbose) { if (verbose) {
unsigned char md[SHA256_DIGEST_LENGTH]; unsigned char md[SHA256_DIGEST_LENGTH];
...@@ -505,7 +512,7 @@ static int pack_images(char *filename, uint64_t toc_flags) ...@@ -505,7 +512,7 @@ static int pack_images(char *filename, uint64_t toc_flags)
static void update_fip(void) static void update_fip(void)
{ {
toc_entry_t *toc_entry; toc_entry_t *toc_entry;
image_t *image; image_t *new_image, *old_image;
/* Add or replace images in the FIP file. */ /* Add or replace images in the FIP file. */
for (toc_entry = toc_entries; for (toc_entry = toc_entries;
...@@ -514,21 +521,21 @@ static void update_fip(void) ...@@ -514,21 +521,21 @@ static void update_fip(void)
if (toc_entry->action != DO_PACK) if (toc_entry->action != DO_PACK)
continue; continue;
image = read_image_from_file(toc_entry, toc_entry->action_arg); new_image = read_image_from_file(&toc_entry->uuid,
if (toc_entry->image != NULL) { toc_entry->action_arg);
old_image = lookup_image_from_uuid(&toc_entry->uuid);
if (old_image != NULL) {
if (verbose) if (verbose)
log_dbgx("Replacing image %s.bin with %s", log_dbgx("Replacing image %s.bin with %s",
toc_entry->cmdline_name, toc_entry->cmdline_name,
toc_entry->action_arg); toc_entry->action_arg);
replace_image(toc_entry->image, image); replace_image(old_image, new_image);
} else { } else {
if (verbose) if (verbose)
log_dbgx("Adding image %s", log_dbgx("Adding image %s",
toc_entry->action_arg); toc_entry->action_arg);
add_image(image); add_image(new_image);
} }
/* Link backpointer from lookup entry. */
toc_entry->image = image;
free(toc_entry->action_arg); free(toc_entry->action_arg);
toc_entry->action_arg = NULL; toc_entry->action_arg = NULL;
...@@ -758,23 +765,13 @@ static int unpack_cmd(int argc, char *argv[]) ...@@ -758,23 +765,13 @@ static int unpack_cmd(int argc, char *argv[])
if (chdir(outdir) == -1) if (chdir(outdir) == -1)
log_err("chdir %s", outdir); log_err("chdir %s", outdir);
/* Mark all images to be unpacked. */
if (unpack_all) {
for (toc_entry = toc_entries;
toc_entry->cmdline_name != NULL;
toc_entry++) {
if (toc_entry->image != NULL) {
toc_entry->action = DO_UNPACK;
toc_entry->action_arg = NULL;
}
}
}
/* Unpack all specified images. */ /* Unpack all specified images. */
for (toc_entry = toc_entries; for (toc_entry = toc_entries;
toc_entry->cmdline_name != NULL; toc_entry->cmdline_name != NULL;
toc_entry++) { toc_entry++) {
if (toc_entry->action != DO_UNPACK) image_t *image;
if (!unpack_all && toc_entry->action != DO_UNPACK)
continue; continue;
/* Build filename. */ /* Build filename. */
...@@ -785,7 +782,9 @@ static int unpack_cmd(int argc, char *argv[]) ...@@ -785,7 +782,9 @@ static int unpack_cmd(int argc, char *argv[])
snprintf(file, sizeof(file), "%s", snprintf(file, sizeof(file), "%s",
toc_entry->action_arg); toc_entry->action_arg);
if (toc_entry->image == NULL) { image = lookup_image_from_uuid(&toc_entry->uuid);
if (image == NULL) {
if (!unpack_all)
log_warnx("Requested image %s is not in %s", log_warnx("Requested image %s is not in %s",
file, argv[0]); file, argv[0]);
free(toc_entry->action_arg); free(toc_entry->action_arg);
...@@ -796,7 +795,7 @@ static int unpack_cmd(int argc, char *argv[]) ...@@ -796,7 +795,7 @@ static int unpack_cmd(int argc, char *argv[])
if (access(file, F_OK) != 0 || fflag) { if (access(file, F_OK) != 0 || fflag) {
if (verbose) if (verbose)
log_dbgx("Unpacking %s", file); log_dbgx("Unpacking %s", file);
write_image_to_file(toc_entry->image, file); write_image_to_file(image, file);
} else { } else {
log_warnx("File %s already exists, use --force to overwrite it", log_warnx("File %s already exists, use --force to overwrite it",
file); file);
...@@ -885,13 +884,16 @@ static int remove_cmd(int argc, char *argv[]) ...@@ -885,13 +884,16 @@ static int remove_cmd(int argc, char *argv[])
for (toc_entry = toc_entries; for (toc_entry = toc_entries;
toc_entry->cmdline_name != NULL; toc_entry->cmdline_name != NULL;
toc_entry++) { toc_entry++) {
image_t *image;
if (toc_entry->action != DO_REMOVE) if (toc_entry->action != DO_REMOVE)
continue; continue;
if (toc_entry->image != NULL) { image = lookup_image_from_uuid(&toc_entry->uuid);
if (image != NULL) {
if (verbose) if (verbose)
log_dbgx("Removing %s.bin", log_dbgx("Removing %s.bin",
toc_entry->cmdline_name); toc_entry->cmdline_name);
remove_image(toc_entry->image); remove_image(image);
} else { } else {
log_warnx("Requested image %s.bin is not in %s", log_warnx("Requested image %s.bin is not in %s",
toc_entry->cmdline_name, argv[0]); toc_entry->cmdline_name, argv[0]);
......
...@@ -57,7 +57,6 @@ typedef struct image { ...@@ -57,7 +57,6 @@ typedef struct image {
uuid_t uuid; uuid_t uuid;
size_t size; size_t size;
void *buffer; void *buffer;
struct toc_entry *toc_entry;
} image_t; } image_t;
typedef struct cmd { typedef struct cmd {
......
...@@ -35,49 +35,155 @@ ...@@ -35,49 +35,155 @@
/* The images used depends on the platform. */ /* The images used depends on the platform. */
toc_entry_t toc_entries[] = { toc_entry_t toc_entries[] = {
{ "SCP Firmware Updater Configuration FWU SCP_BL2U", UUID_TRUSTED_UPDATE_FIRMWARE_SCP_BL2U, {
"scp-fwu-cfg", NULL, 0, NULL }, .name = "SCP Firmware Updater Configuration FWU SCP_BL2U",
{ "AP Firmware Updater Configuration BL2U", UUID_TRUSTED_UPDATE_FIRMWARE_BL2U, .uuid = UUID_TRUSTED_UPDATE_FIRMWARE_SCP_BL2U,
"ap-fwu-cfg", NULL, 0, NULL }, .cmdline_name = "scp-fwu-cfg",
{ "Firmware Updater NS_BL2U", UUID_TRUSTED_UPDATE_FIRMWARE_NS_BL2U, .action = 0,
"fwu", NULL, 0, NULL }, .action_arg = NULL
{ "Non-Trusted Firmware Updater certificate", UUID_TRUSTED_FWU_CERT, },
"fwu-cert", NULL, 0, NULL }, {
{ "Trusted Boot Firmware BL2", UUID_TRUSTED_BOOT_FIRMWARE_BL2, .name = "AP Firmware Updater Configuration BL2U",
"tb-fw", NULL, 0, NULL }, .uuid = UUID_TRUSTED_UPDATE_FIRMWARE_BL2U,
{ "SCP Firmware SCP_BL2", UUID_SCP_FIRMWARE_SCP_BL2, .cmdline_name = "ap-fwu-cfg",
"scp-fw", NULL, 0, NULL }, .action = 0,
{ "EL3 Runtime Firmware BL31", UUID_EL3_RUNTIME_FIRMWARE_BL31, .action_arg = NULL
"soc-fw", NULL, 0, NULL }, },
{ "Secure Payload BL32 (Trusted OS)", UUID_SECURE_PAYLOAD_BL32, {
"tos-fw", NULL, 0, NULL }, .name = "Firmware Updater NS_BL2U",
{ "Non-Trusted Firmware BL33", UUID_NON_TRUSTED_FIRMWARE_BL33, .uuid = UUID_TRUSTED_UPDATE_FIRMWARE_NS_BL2U,
"nt-fw", NULL, 0, NULL }, .cmdline_name = "fwu",
.action = 0,
.action_arg = NULL
},
{
.name = "Non-Trusted Firmware Updater certificate",
.uuid = UUID_TRUSTED_FWU_CERT,
.cmdline_name = "fwu-cert",
.action = 0,
.action_arg = NULL
},
{
.name = "Trusted Boot Firmware BL2",
.uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
.cmdline_name = "tb-fw",
.action = 0,
.action_arg = NULL
},
{
.name = "SCP Firmware SCP_BL2",
.uuid = UUID_SCP_FIRMWARE_SCP_BL2,
.cmdline_name = "scp-fw",
.action = 0,
.action_arg = NULL
},
{
.name = "EL3 Runtime Firmware BL31",
.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
.cmdline_name = "soc-fw",
.action = 0,
.action_arg = NULL
},
{
.name = "Secure Payload BL32 (Trusted OS)",
.uuid = UUID_SECURE_PAYLOAD_BL32,
.cmdline_name = "tos-fw",
.action = 0,
.action_arg = NULL
},
{
.name = "Non-Trusted Firmware BL33",
.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
.cmdline_name = "nt-fw",
.action = 0,
.action_arg = NULL
},
/* Key Certificates */ /* Key Certificates */
{ "Root Of Trust key certificate", UUID_ROT_KEY_CERT, {
"rot-cert", NULL, 0, NULL }, .name = "Root Of Trust key certificate",
{ "Trusted key certificate", UUID_TRUSTED_KEY_CERT, .uuid = UUID_ROT_KEY_CERT,
"trusted-key-cert", NULL, 0, NULL }, .cmdline_name = "rot-cert",
{ "SCP Firmware key certificate", UUID_SCP_FW_KEY_CERT, .action = 0,
"scp-fw-key-cert", NULL, 0, NULL }, .action_arg = NULL
{ "SoC Firmware key certificate", UUID_SOC_FW_KEY_CERT, },
"soc-fw-key-cert", NULL, 0, NULL }, {
{ "Trusted OS Firmware key certificate", UUID_TRUSTED_OS_FW_KEY_CERT, .name = "Trusted key certificate",
"tos-fw-key-cert", NULL, 0, NULL }, .uuid = UUID_TRUSTED_KEY_CERT,
{ "Non-Trusted Firmware key certificate", UUID_NON_TRUSTED_FW_KEY_CERT, .cmdline_name = "trusted-key-cert",
"nt-fw-key-cert", NULL, 0, NULL }, .action = 0,
.action_arg = NULL
},
{
.name = "SCP Firmware key certificate",
.uuid = UUID_SCP_FW_KEY_CERT,
.cmdline_name = "scp-fw-key-cert",
.action = 0,
.action_arg = NULL
},
{
.name = "SoC Firmware key certificate",
.uuid = UUID_SOC_FW_KEY_CERT,
.cmdline_name = "soc-fw-key-cert",
.action = 0,
.action_arg = NULL
},
{
.name = "Trusted OS Firmware key certificate",
.uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
.cmdline_name = "tos-fw-key-cert",
.action = 0,
.action_arg = NULL
},
{
.name = "Non-Trusted Firmware key certificate",
.uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
.cmdline_name = "nt-fw-key-cert",
.action = 0,
.action_arg = NULL
},
/* Content certificates */ /* Content certificates */
{ "Trusted Boot Firmware BL2 certificate", UUID_TRUSTED_BOOT_FW_CERT, {
"tb-fw-cert", NULL, 0, NULL }, .name = "Trusted Boot Firmware BL2 certificate",
{ "SCP Firmware content certificate", UUID_SCP_FW_CONTENT_CERT, .uuid = UUID_TRUSTED_BOOT_FW_CERT,
"scp-fw-cert", NULL, 0, NULL }, .cmdline_name = "tb-fw-cert",
{ "SoC Firmware content certificate", UUID_SOC_FW_CONTENT_CERT, .action = 0,
"soc-fw-cert", NULL, 0, NULL }, .action_arg = NULL
{ "Trusted OS Firmware content certificate", UUID_TRUSTED_OS_FW_CONTENT_CERT, },
"tos-fw-cert", NULL, 0, NULL }, {
{ "Non-Trusted Firmware content certificate", UUID_NON_TRUSTED_FW_CONTENT_CERT, .name = "SCP Firmware content certificate",
"nt-fw-cert", NULL, 0, NULL }, .uuid = UUID_SCP_FW_CONTENT_CERT,
{ NULL, { 0 }, NULL, NULL, 0, NULL } .cmdline_name = "scp-fw-cert",
.action = 0,
.action_arg = NULL
},
{
.name = "SoC Firmware content certificate",
.uuid = UUID_SOC_FW_CONTENT_CERT,
.cmdline_name = "soc-fw-cert",
.action = 0,
.action_arg = NULL
},
{
.name = "Trusted OS Firmware content certificate",
.uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
.cmdline_name = "tos-fw-cert",
.action = 0,
.action_arg = NULL
},
{
.name = "Non-Trusted Firmware content certificate",
.uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
.cmdline_name = "nt-fw-cert",
.action = 0,
.action_arg = NULL
},
{
.name = NULL,
.uuid = { 0 },
.cmdline_name = NULL,
.action = 0,
.action_arg = NULL
}
}; };
size_t toc_entries_len = sizeof(toc_entries) / sizeof(toc_entries[0]); size_t toc_entries_len = sizeof(toc_entries) / sizeof(toc_entries[0]);
...@@ -42,7 +42,6 @@ typedef struct toc_entry { ...@@ -42,7 +42,6 @@ typedef struct toc_entry {
const char *name; const char *name;
uuid_t uuid; uuid_t uuid;
const char *cmdline_name; const char *cmdline_name;
struct image *image;
int action; int action;
char *action_arg; char *action_arg;
} toc_entry_t; } toc_entry_t;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment