Patrick Georgi (pgeorgi@google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/18102
-gerrit
commit 9d1ce762b2bf722ddd6a22961c643ee3ce5cd16f Author: Patrick Georgi pgeorgi@chromium.org Date: Wed Jan 11 18:38:11 2017 +0100
util/cbfstool: Enable adding precompressed files to cbfs
cbfstool ... add ... -c precompression assumes the input file to be created by cbfs-compression-tool's compress command and uses that to add the file with correct metadata.
When adding the locale_*.bin files to Chrome OS images, this provides a nice speedup (since we can parallelize the precompression and avoid compressing everything twice) while creating a bit-identical file.
Change-Id: Iadd106672c505909528b55e2cd43c914b95b6c6d Signed-off-by: Patrick Georgi pgeorgi@chromium.org --- util/cbfstool/cbfstool.c | 68 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 23 deletions(-)
diff --git a/util/cbfstool/cbfstool.c b/util/cbfstool/cbfstool.c index de50ff3..e875b5b 100644 --- a/util/cbfstool/cbfstool.c +++ b/util/cbfstool/cbfstool.c @@ -79,6 +79,7 @@ static struct param { bool machine_parseable; int fit_empty_entries; enum comp_algo compression; + int precompression; enum vb2_hash_algorithm hash; /* for linux payloads */ char *initrd; @@ -439,33 +440,50 @@ static int cbfstool_convert_raw(struct buffer *buffer, unused uint32_t *offset, struct cbfs_file *header) { char *compressed; - int compressed_size; - - comp_func_ptr compress = compression_function(param.compression); - if (!compress) - return -1; - compressed = calloc(buffer->size, 1); - - if (compress(buffer->data, buffer->size, - compressed, &compressed_size)) { - WARN("Compression failed - disabled\n"); + int decompressed_size, compressed_size; + comp_func_ptr compress; + + decompressed_size = buffer->size; + if (param.precompression) { + param.compression = ((uint32_t *)buffer->data)[0]; + decompressed_size = ((uint32_t *)buffer->data)[1]; + if (is_big_endian()) { + param.compression = swab32(param.compression); + decompressed_size = swab32(decompressed_size); + } + compressed_size = buffer->size - 8; + compressed = malloc(compressed_size); + if (!compressed) + return -1; + memcpy(compressed, buffer->data + 8, compressed_size); } else { - struct cbfs_file_attr_compression *attrs = - (struct cbfs_file_attr_compression *) - cbfs_add_file_attr(header, - CBFS_FILE_ATTR_TAG_COMPRESSION, - sizeof(struct cbfs_file_attr_compression)); - if (attrs == NULL) + compress = compression_function(param.compression); + if (!compress) return -1; - attrs->compression = htonl(param.compression); - attrs->decompressed_size = htonl(buffer->size); - - free(buffer->data); - buffer->data = compressed; - buffer->size = compressed_size; + compressed = calloc(buffer->size, 1);
- header->len = htonl(buffer->size); + if (compress(buffer->data, buffer->size, + compressed, &compressed_size)) { + WARN("Compression failed - disabled\n"); + return 0; + } } + + struct cbfs_file_attr_compression *attrs = + (struct cbfs_file_attr_compression *) + cbfs_add_file_attr(header, + CBFS_FILE_ATTR_TAG_COMPRESSION, + sizeof(struct cbfs_file_attr_compression)); + if (attrs == NULL) + return -1; + attrs->compression = htonl(param.compression); + attrs->decompressed_size = htonl(decompressed_size); + + free(buffer->data); + buffer->data = compressed; + buffer->size = compressed_size; + + header->len = htonl(buffer->size); return 0; }
@@ -1347,6 +1365,10 @@ int main(int argc, char **argv) optarg); break; case 'c': { + if (strcmp(optarg, "precompression") == 0) { + param.precompression = 1; + break; + } int algo = cbfs_parse_comp_algo(optarg); if (algo >= 0) param.compression = algo;