[coreboot-gerrit] Patch set updated for coreboot: cbfstool: allow compression at file header level

Patrick Georgi (pgeorgi@google.com) gerrit at coreboot.org
Thu Jul 16 15:36:31 CEST 2015


Patrick Georgi (pgeorgi at google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/10935

-gerrit

commit cd71f05a434ac3b362eaf2ddd1d118a1efad6cab
Author: Daisuke Nojiri <dnojiri at chromium.org>
Date:   Thu Jul 9 15:07:45 2015 -0700

    cbfstool: allow compression at file header level
    
    Currently, compression is only allowed at subheader level (e.g. cbfs_stage,
    cbfs_payload_segment). This change adds compression field to each file's
    header so that any cbfs file can be compressed.
    
    With the necessary additions in coreboot and libpayload, the following sample
    code can load a compressed file:
    
    	const char *name = "foo.bmp";
    	struct cbfs_file *file = cbfs_get_file(media, name);
    	void *dst = malloc(ntohl(file->uncompressed_size));
    	dst = cbfs_get_file_content(media, name, type, file, dst);
    
    cbfs_stage and cbfs_payload_segment continue to support compression at
    subheader level because stages and payloads have to be decompressed to the load
    address, which is stored in the subheader. For these, file level compression
    should be turned off.
    
    Change-Id: I9a00ec99dfc68ffb2771bb4a3cc5ba6ba8a326f4
    Signed-off-by: Daisuke Nojiri <dnojiri at chromium.org>
    Signed-off-by: Patrick Georgi <pgeorgi at chromium.org>
---
 util/cbfstool/cbfs.h       |  3 +++
 util/cbfstool/cbfs_image.c |  9 ++++++++-
 util/cbfstool/cbfs_image.h |  3 ++-
 util/cbfstool/cbfstool.c   | 40 ++++++++++++++++++++++++++++++++++------
 4 files changed, 47 insertions(+), 8 deletions(-)

diff --git a/util/cbfstool/cbfs.h b/util/cbfstool/cbfs.h
index c7a5bd6..abe87a0 100644
--- a/util/cbfstool/cbfs.h
+++ b/util/cbfstool/cbfs.h
@@ -86,6 +86,9 @@ _Static_assert(sizeof(struct cbfs_file) == 24, "cbfs_file size mismatch");
 struct cbfs_file_attributes {
 	/* size of this structure, to test if a given element is available */
 	uint32_t len;
+	/* whole file compression format. 0 if no compression. */
+	uint32_t compression;
+	uint32_t decompressed_size;
 } __PACKED;
 
 struct cbfs_stage {
diff --git a/util/cbfstool/cbfs_image.c b/util/cbfstool/cbfs_image.c
index 48cf7b2..bbc5141 100644
--- a/util/cbfstool/cbfs_image.c
+++ b/util/cbfstool/cbfs_image.c
@@ -537,7 +537,8 @@ static int cbfs_add_entry_at(struct cbfs_image *image,
 }
 
 int cbfs_add_entry(struct cbfs_image *image, struct buffer *buffer,
-		   const char *name, uint32_t type, uint32_t content_offset)
+		   const char *name, uint32_t type, uint32_t content_offset,
+		   enum comp_algo compression, uint32_t decompressed_size)
 {
 	assert(image);
 	assert(buffer);
@@ -587,6 +588,10 @@ int cbfs_add_entry(struct cbfs_image *image, struct buffer *buffer,
 			      buffer->size);
 			cbfs_create_empty_entry(entry, buffer->size, name);
 			entry->type = htonl(type);
+			struct cbfs_file_attributes *attr =
+				CBFS_FILE_ATTRIBUTES(entry);
+			attr->compression = htonl(compression);
+			attr->decompressed_size = htonl(decompressed_size);
 			memcpy(CBFS_SUBHEADER(entry), buffer->data, buffer->size);
 			if (verbose)
 				cbfs_print_entry_info(image, entry, stderr);
@@ -1047,6 +1052,8 @@ int cbfs_create_empty_entry(struct cbfs_file *entry,
 
 	struct cbfs_file_attributes *attr = CBFS_FILE_ATTRIBUTES(entry);
 	attr->len = sizeof(struct cbfs_file_attributes);
+	attr->compression = 0;
+	attr->decompressed_size = 0;
 	return 0;
 }
 
diff --git a/util/cbfstool/cbfs_image.h b/util/cbfstool/cbfs_image.h
index cb2935b..7da7621 100644
--- a/util/cbfstool/cbfs_image.h
+++ b/util/cbfstool/cbfs_image.h
@@ -93,7 +93,8 @@ int cbfs_export_entry(struct cbfs_image *image, const char *entry_name,
  * Never pass this function a top-aligned address: convert it to an offset.
  * Returns 0 on success, otherwise non-zero. */
 int cbfs_add_entry(struct cbfs_image *image, struct buffer *buffer,
-		   const char *name, uint32_t type, uint32_t content_offset);
+		   const char *name, uint32_t type, uint32_t content_offset,
+		   enum comp_algo algo, uint32_t decompressed_size);
 
 /* Removes an entry from CBFS image. Returns 0 on success, otherwise non-zero. */
 int cbfs_remove_entry(struct cbfs_image *image, const char *name);
diff --git a/util/cbfstool/cbfstool.c b/util/cbfstool/cbfstool.c
index b6a486f..1637089 100644
--- a/util/cbfstool/cbfstool.c
+++ b/util/cbfstool/cbfstool.c
@@ -76,6 +76,8 @@ static struct param {
 	bool show_immutable;
 	int fit_empty_entries;
 	enum comp_algo compression;
+	enum comp_algo file_compression;
+	uint32_t decompressed_size;
 	/* for linux payloads */
 	char *initrd;
 	char *cmdline;
@@ -83,6 +85,7 @@ static struct param {
 	/* All variables not listed are initialized as zero. */
 	.arch = CBFS_ARCHITECTURE_UNKNOWN,
 	.compression = CBFS_COMPRESS_NONE,
+	.file_compression = CBFS_COMPRESS_NONE,
 	.headeroffset = ~0,
 	.region_name = SECTION_NAME_PRIMARY_CBFS,
 };
@@ -150,8 +153,8 @@ static int cbfs_add_integer_component(const char *name,
 		offset = convert_to_from_top_aligned(param.image_region,
 								-offset);
 
-	if (cbfs_add_entry(&image, &buffer, name, CBFS_COMPONENT_RAW, offset) !=
-									0) {
+	if (cbfs_add_entry(&image, &buffer, name, CBFS_COMPONENT_RAW, offset,
+		0, 0) != 0) {
 		ERROR("Failed to add %llu into ROM image as '%s'.\n",
 					(long long unsigned)u64val, name);
 		goto done;
@@ -212,7 +215,9 @@ static int cbfs_add_component(const char *filename,
 		offset = convert_to_from_top_aligned(param.image_region,
 								-offset);
 
-	if (cbfs_add_entry(&image, &buffer, name, type, offset) != 0) {
+	if (cbfs_add_entry(&image, &buffer, name, type, offset,
+			   param.file_compression,
+			   param.decompressed_size) != 0) {
 		ERROR("Failed to add '%s' into ROM image.\n", filename);
 		buffer_delete(&buffer);
 		return 1;
@@ -222,6 +227,29 @@ static int cbfs_add_component(const char *filename,
 	return 0;
 }
 
+static int cbfstool_convert_raw(struct buffer *buffer, unused uint32_t *offset)
+{
+	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");
+	} else {
+		param.file_compression = param.compression;
+		free(buffer->data);
+		buffer->data = compressed;
+		param.decompressed_size = buffer->size;
+		buffer->size = compressed_size;
+	}
+	return 0;
+}
+
 static int cbfstool_convert_mkstage(struct buffer *buffer, uint32_t *offset)
 {
 	struct buffer output;
@@ -289,7 +317,7 @@ static int cbfs_add(void)
 				  param.type,
 				  param.baseaddress,
 				  param.headeroffset,
-				  NULL);
+				  cbfstool_convert_raw);
 }
 
 static int cbfs_add_stage(void)
@@ -735,7 +763,7 @@ static bool cbfs_is_legacy_format(struct buffer *buffer)
 }
 
 static const struct command commands[] = {
-	{"add", "H:r:f:n:t:b:vh?", cbfs_add, true, true},
+	{"add", "H:r:f:n:t:c:b:vh?", cbfs_add, true, true},
 	{"add-flat-binary", "H:r:f:n:l:e:c:b:vh?", cbfs_add_flat_binary, true,
 									true},
 	{"add-payload", "H:r:f:n:t:c:b:C:I:vh?", cbfs_add_payload, true, true},
@@ -850,7 +878,7 @@ static void usage(char *name)
 	     "  -h               Display this help message\n\n"
 	     "COMMANDs:\n"
 	     " add [-r image,regions] -f FILE -n NAME -t TYPE \\\n"
-	     "        [-b base-address]                                    "
+	     "        [-c compression] [-b base-address]                   "
 			"Add a component\n"
 	     " add-payload [-r image,regions] -f FILE -n NAME \\\n"
 	     "        [-c compression] [-b base-address]                   "



More information about the coreboot-gerrit mailing list