diff options
author | Patrick Georgi <pgeorgi@chromium.org> | 2015-09-10 15:28:27 +0200 |
---|---|---|
committer | Patrick Georgi <pgeorgi@google.com> | 2015-09-21 16:03:48 +0000 |
commit | 59e52b975e3ffe29709f82e57849ccf8254b9cd1 (patch) | |
tree | 97d07360c5d1a51f54a9e2c7c8afdc35dbb2926b | |
parent | a9992d3da5d28dc9f8423fe17497231f894fa9d9 (diff) | |
download | coreboot-59e52b975e3ffe29709f82e57849ccf8254b9cd1.tar.xz |
cbfstool: add new add-master-header command
The command adds a new cbfs file, fills in the CBFS meta data in cbfs
master header format, then points the master header pointer (which
resides at the last 4 bytes of the CBFS region) to the data area of the
new file.
This can leak some space in CBFS if an old-style CBFS with native master
header gets the treatment, because a new header is created and pointed
at. flashmap based images have no such header, and the attempt to create
a second file with the (hardcoded) name will fail.
Change-Id: I5bc7fbcb5962b35a95261f30f0c93008e760680d
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Reviewed-on: http://review.coreboot.org/11628
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
-rw-r--r-- | util/cbfstool/cbfstool.c | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/util/cbfstool/cbfstool.c b/util/cbfstool/cbfstool.c index c45f316f6f..ed6e898f5d 100644 --- a/util/cbfstool/cbfstool.c +++ b/util/cbfstool/cbfstool.c @@ -19,6 +19,7 @@ * Foundation, Inc. */ +#include <endian.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -211,6 +212,76 @@ done: return ret; } +static int cbfs_add_master_header(void) +{ + const char * const name = "cbfs master header"; + struct cbfs_image image; + struct cbfs_file *header = NULL; + struct buffer buffer; + int ret = 1; + + if (cbfs_image_from_buffer(&image, param.image_region, + param.headeroffset)) { + ERROR("Selected image region is not a CBFS.\n"); + return 1; + } + + if (cbfs_get_entry(&image, name)) { + ERROR("'%s' already in ROM image.\n", name); + return 1; + } + + if (buffer_create(&buffer, sizeof(struct cbfs_header), name) != 0) + return 1; + + struct cbfs_header *h = (struct cbfs_header *)buffer.data; + h->magic = htonl(CBFS_HEADER_MAGIC); + h->version = htonl(CBFS_HEADER_VERSION); + h->romsize = htonl(param.image_region->size); + /* The 4 bytes are left out for two reasons: + * 1. the cbfs master header pointer resides there + * 2. some cbfs implementations assume that an image that resides + * below 4GB has a bootblock and get confused when the end of the + * image is at 4GB == 0. + */ + h->bootblocksize = htonl(4); + h->align = htonl(CBFS_ENTRY_ALIGNMENT); + /* offset relative to romsize above, which covers precisely the CBFS + * region. + */ + h->offset = htonl(0); + h->architecture = htonl(CBFS_ARCHITECTURE_UNKNOWN); + + header = cbfs_create_file_header(CBFS_COMPONENT_CBFSHEADER, + buffer_size(&buffer), name); + if (cbfs_add_entry(&image, &buffer, 0, header) != 0) { + ERROR("Failed to add cbfs master header into ROM image.\n"); + goto done; + } + + struct cbfs_file *entry; + if ((entry = cbfs_get_entry(&image, name)) == NULL) { + ERROR("'%s' not in ROM image?!?\n", name); + goto done; + } + + uint32_t header_offset = CBFS_SUBHEADER(entry) - + buffer_get(&image.buffer); + header_offset = -(buffer_size(&image.buffer) - header_offset); + + // TODO: when we have a BE target, we'll need to store this as BE + *(uint32_t *)(buffer_get(&image.buffer) + + buffer_size(&image.buffer) - 4) = + htole32(header_offset); + + ret = 0; + +done: + free(header); + buffer_delete(&buffer); + return ret; +} + static int cbfs_add_component(const char *filename, const char *name, uint32_t type, @@ -831,6 +902,7 @@ static const struct command commands[] = { {"add-payload", "H:r:f:n:t:c:b:C:I:vh?", cbfs_add_payload, true, true}, {"add-stage", "a:H:r:f:n:t:c:b:P:S:yvh?", cbfs_add_stage, true, true}, {"add-int", "H:r:i:n:b:vh?", cbfs_add_integer, true, true}, + {"add-master-header", "H:r:vh?", cbfs_add_master_header, true, true}, {"copy", "H:D:s:h?", cbfs_copy, true, true}, {"create", "M:r:s:B:b:H:o:m:vh?", cbfs_create, true, true}, {"extract", "H:r:n:f:vh?", cbfs_extract, true, false}, @@ -956,6 +1028,8 @@ static void usage(char *name) "Add a 32bit flat mode binary\n" " add-int [-r image,regions] -i INTEGER -n NAME [-b base] " "Add a raw 64-bit integer value\n" + " add-master-header [-r image,regions] " + "Add a legacy CBFS master header\n" " remove [-r image,regions] -n NAME " "Remove a component\n" " copy -D new_header_offset -s region size \\\n" |