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: dp-arm <dimitris.papastamos@arm.com>
This commit is contained in:
dp-arm 2016-08-30 14:18:58 +01:00
parent 6bb37adc20
commit b04efccece
4 changed files with 193 additions and 87 deletions

View File

@ -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;
@ -197,6 +197,19 @@ static toc_entry_t *get_entry_lookup_from_uuid(const uuid_t *uuid)
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)
{
struct stat st;
@ -268,16 +281,6 @@ static int parse_fip(char *filename, fip_toc_header_t *toc_header_out)
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);
toc_entry++;
@ -290,12 +293,14 @@ static int parse_fip(char *filename, fip_toc_header_t *toc_header_out)
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;
image_t *image;
FILE *fp;
assert(uuid != NULL);
fp = fopen(filename, "r");
if (fp == NULL)
log_err("fopen %s", filename);
@ -307,7 +312,7 @@ static image_t *read_image_from_file(toc_entry_t *toc_entry, char *filename)
if (image == NULL)
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);
if (image->buffer == NULL)
@ -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)
log_errx("Failed to read %s", filename);
image->size = st.st_size;
image->toc_entry = toc_entry;
fclose(fp);
return image;
@ -391,18 +395,21 @@ static int info_cmd(int argc, char *argv[])
(sizeof(fip_toc_entry_t) * (nr_images + 1));
for (i = 0; i < nr_images; i++) {
toc_entry_t *toc_entry;
image = images[i];
if (image->toc_entry != NULL)
printf("%s: ", image->toc_entry->name);
toc_entry = lookup_entry_from_uuid(&image->uuid);
if (toc_entry != NULL)
printf("%s: ", toc_entry->name);
else
printf("Unknown entry: ");
image_size = image->size;
printf("offset=0x%llX, size=0x%llX",
(unsigned long long)image_offset,
(unsigned long long)image_size);
if (image->toc_entry != NULL)
if (toc_entry != NULL)
printf(", cmdline=\"--%s\"",
image->toc_entry->cmdline_name);
toc_entry->cmdline_name);
if (verbose) {
unsigned char md[SHA256_DIGEST_LENGTH];
@ -505,7 +512,7 @@ static int pack_images(char *filename, uint64_t toc_flags)
static void update_fip(void)
{
toc_entry_t *toc_entry;
image_t *image;
image_t *new_image, *old_image;
/* Add or replace images in the FIP file. */
for (toc_entry = toc_entries;
@ -514,21 +521,21 @@ static void update_fip(void)
if (toc_entry->action != DO_PACK)
continue;
image = read_image_from_file(toc_entry, toc_entry->action_arg);
if (toc_entry->image != NULL) {
new_image = read_image_from_file(&toc_entry->uuid,
toc_entry->action_arg);
old_image = lookup_image_from_uuid(&toc_entry->uuid);
if (old_image != NULL) {
if (verbose)
log_dbgx("Replacing image %s.bin with %s",
toc_entry->cmdline_name,
toc_entry->action_arg);
replace_image(toc_entry->image, image);
replace_image(old_image, new_image);
} else {
if (verbose)
log_dbgx("Adding image %s",
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);
toc_entry->action_arg = NULL;
@ -758,23 +765,13 @@ static int unpack_cmd(int argc, char *argv[])
if (chdir(outdir) == -1)
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. */
for (toc_entry = toc_entries;
toc_entry->cmdline_name != NULL;
toc_entry++) {
if (toc_entry->action != DO_UNPACK)
image_t *image;
if (!unpack_all && toc_entry->action != DO_UNPACK)
continue;
/* Build filename. */
@ -785,9 +782,11 @@ static int unpack_cmd(int argc, char *argv[])
snprintf(file, sizeof(file), "%s",
toc_entry->action_arg);
if (toc_entry->image == NULL) {
log_warnx("Requested image %s is not in %s",
file, argv[0]);
image = lookup_image_from_uuid(&toc_entry->uuid);
if (image == NULL) {
if (!unpack_all)
log_warnx("Requested image %s is not in %s",
file, argv[0]);
free(toc_entry->action_arg);
toc_entry->action_arg = NULL;
continue;
@ -796,7 +795,7 @@ static int unpack_cmd(int argc, char *argv[])
if (access(file, F_OK) != 0 || fflag) {
if (verbose)
log_dbgx("Unpacking %s", file);
write_image_to_file(toc_entry->image, file);
write_image_to_file(image, file);
} else {
log_warnx("File %s already exists, use --force to overwrite it",
file);
@ -885,13 +884,16 @@ static int remove_cmd(int argc, char *argv[])
for (toc_entry = toc_entries;
toc_entry->cmdline_name != NULL;
toc_entry++) {
image_t *image;
if (toc_entry->action != DO_REMOVE)
continue;
if (toc_entry->image != NULL) {
image = lookup_image_from_uuid(&toc_entry->uuid);
if (image != NULL) {
if (verbose)
log_dbgx("Removing %s.bin",
toc_entry->cmdline_name);
remove_image(toc_entry->image);
remove_image(image);
} else {
log_warnx("Requested image %s.bin is not in %s",
toc_entry->cmdline_name, argv[0]);

View File

@ -57,7 +57,6 @@ typedef struct image {
uuid_t uuid;
size_t size;
void *buffer;
struct toc_entry *toc_entry;
} image_t;
typedef struct cmd {

View File

@ -35,49 +35,155 @@
/* The images used depends on the platform. */
toc_entry_t toc_entries[] = {
{ "SCP Firmware Updater Configuration FWU SCP_BL2U", UUID_TRUSTED_UPDATE_FIRMWARE_SCP_BL2U,
"scp-fwu-cfg", NULL, 0, NULL },
{ "AP Firmware Updater Configuration BL2U", UUID_TRUSTED_UPDATE_FIRMWARE_BL2U,
"ap-fwu-cfg", NULL, 0, NULL },
{ "Firmware Updater NS_BL2U", UUID_TRUSTED_UPDATE_FIRMWARE_NS_BL2U,
"fwu", NULL, 0, NULL },
{ "Non-Trusted Firmware Updater certificate", UUID_TRUSTED_FWU_CERT,
"fwu-cert", NULL, 0, NULL },
{ "Trusted Boot Firmware BL2", UUID_TRUSTED_BOOT_FIRMWARE_BL2,
"tb-fw", NULL, 0, NULL },
{ "SCP Firmware SCP_BL2", UUID_SCP_FIRMWARE_SCP_BL2,
"scp-fw", NULL, 0, NULL },
{ "EL3 Runtime Firmware BL31", UUID_EL3_RUNTIME_FIRMWARE_BL31,
"soc-fw", NULL, 0, NULL },
{ "Secure Payload BL32 (Trusted OS)", UUID_SECURE_PAYLOAD_BL32,
"tos-fw", NULL, 0, NULL },
{ "Non-Trusted Firmware BL33", UUID_NON_TRUSTED_FIRMWARE_BL33,
"nt-fw", NULL, 0, NULL },
{
.name = "SCP Firmware Updater Configuration FWU SCP_BL2U",
.uuid = UUID_TRUSTED_UPDATE_FIRMWARE_SCP_BL2U,
.cmdline_name = "scp-fwu-cfg",
.action = 0,
.action_arg = NULL
},
{
.name = "AP Firmware Updater Configuration BL2U",
.uuid = UUID_TRUSTED_UPDATE_FIRMWARE_BL2U,
.cmdline_name = "ap-fwu-cfg",
.action = 0,
.action_arg = NULL
},
{
.name = "Firmware Updater NS_BL2U",
.uuid = UUID_TRUSTED_UPDATE_FIRMWARE_NS_BL2U,
.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 */
{ "Root Of Trust key certificate", UUID_ROT_KEY_CERT,
"rot-cert", NULL, 0, NULL },
{ "Trusted key certificate", UUID_TRUSTED_KEY_CERT,
"trusted-key-cert", NULL, 0, NULL },
{ "SCP Firmware key certificate", UUID_SCP_FW_KEY_CERT,
"scp-fw-key-cert", NULL, 0, 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,
"tos-fw-key-cert", NULL, 0, NULL },
{ "Non-Trusted Firmware key certificate", UUID_NON_TRUSTED_FW_KEY_CERT,
"nt-fw-key-cert", NULL, 0, NULL },
{
.name = "Root Of Trust key certificate",
.uuid = UUID_ROT_KEY_CERT,
.cmdline_name = "rot-cert",
.action = 0,
.action_arg = NULL
},
{
.name = "Trusted key certificate",
.uuid = UUID_TRUSTED_KEY_CERT,
.cmdline_name = "trusted-key-cert",
.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 */
{ "Trusted Boot Firmware BL2 certificate", UUID_TRUSTED_BOOT_FW_CERT,
"tb-fw-cert", NULL, 0, NULL },
{ "SCP Firmware content certificate", UUID_SCP_FW_CONTENT_CERT,
"scp-fw-cert", NULL, 0, NULL },
{ "SoC Firmware content certificate", UUID_SOC_FW_CONTENT_CERT,
"soc-fw-cert", NULL, 0, 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,
"nt-fw-cert", NULL, 0, NULL },
{ NULL, { 0 }, NULL, NULL, 0, NULL }
{
.name = "Trusted Boot Firmware BL2 certificate",
.uuid = UUID_TRUSTED_BOOT_FW_CERT,
.cmdline_name = "tb-fw-cert",
.action = 0,
.action_arg = NULL
},
{
.name = "SCP Firmware content certificate",
.uuid = UUID_SCP_FW_CONTENT_CERT,
.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]);

View File

@ -42,7 +42,6 @@ typedef struct toc_entry {
const char *name;
uuid_t uuid;
const char *cmdline_name;
struct image *image;
int action;
char *action_arg;
} toc_entry_t;