[coreboot-gerrit] Patch set updated for coreboot: cd3a8a2 cbfstool: allow user to explicitly specify header location

Patrick Georgi (pgeorgi@google.com) gerrit at coreboot.org
Fri Apr 17 10:40:42 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/9741

-gerrit

commit cd3a8a2fdc09bfaa99319438a6797c05a7189dcb
Author: Vadim Bendebury <vbendeb at chromium.org>
Date:   Tue Dec 23 15:10:12 2014 -0800

    cbfstool: allow user to explicitly specify header location
    
    There potentially could be multiple CBFS instances present in the
    firmware image. cbfstool should be able to operate on any of them, not
    just the first one present.
    
    To accomplish that, allow all CBFS commands to accept the -H parameter
    (which specifies the exact CBFS header location in the image).
    
    If this parameter is specified, the image is not searched for the CBFS
    header, only the specified location is checked for validity, If the
    location is valid, it is considered to be the CBFS header, if not -
    the tool exits with an error status.
    
    Note, that default behavior of the tool does not change.
    
    BRANCH=storm
    BUG=chrome-os-partner:34161, chromium:445938
    TEST=run the following experiments:
    
      - examined an image with three CBFS instances, was able to print all
        of them.
    
      - built a rambi coreboot image and tried the following (cbfstool output abbreviated):
    
      $ ./util/cbfstool/cbfstool /build/rambi/firmware/coreboot.rom print
      coreboot.rom: 8192 kB, bootblocksize 2448, romsize 8388608, offset 0x700000
      alignment: 64 bytes, architecture: x86
    
      Name                           Offset     Type         Size
      cmos_layout.bin                0x700000   cmos_layout  1164
      ...
      (empty)                        0x7ec600   null         77848
      $ \od -tx4 -Ax /build/rambi/firmware/coreboot.rom | tail -2
      7ffff0 fff67de9 000000ff fff6dfe9 fffff650
      800000
      $ ./util/cbfstool/cbfstool /build/rambi/firmware/coreboot.rom print  -H 0x7ff650
      coreboot.rom: 8192 kB, bootblocksize 2448, romsize 8388608, offset 0x700000
      alignment: 64 bytes, architecture: x86
    
      Name                           Offset     Type         Size
      cmos_layout.bin                0x700000   cmos_layout  1164
      ...
      (empty)                        0x7ec600   null         77848
      $ ./util/cbfstool/cbfstool /build/rambi/firmware/coreboot.rom print  -H 0x7ff654
      E: /build/rambi/firmware/coreboot.rom does not have CBFS master header.
      E: Could not load ROM image '/build/rambi/firmware/coreboot.rom'.
      $
    
    Change-Id: I64cbdc79096f3c7a113762b641305542af7bbd60
    Signed-off-by: Patrick Georgi <pgeorgi at chromium.org>
    Original-Commit-Id: 86b88222df6eed25bb176d653305e2e57e18b73a
    Original-Change-Id: I486092e222c96c65868ae7d41a9e8976ffcc93c4
    Original-Signed-off-by: Vadim Bendebury <vbendeb at chromium.org>
    Original-Reviewed-on: https://chromium-review.googlesource.com/237485
    Original-Reviewed-by: David Hendricks <dhendrix at chromium.org>
    Original-Reviewed-by: Patrick Georgi <pgeorgi at chromium.org>
    Original-Reviewed-by: Stefan Reinauer <reinauer at google.com>
---
 util/cbfstool/cbfs_image.c | 40 +++++++++++++++++++++++---------
 util/cbfstool/cbfs_image.h |  6 +++--
 util/cbfstool/cbfstool.c   | 58 ++++++++++++++++++++++++++++------------------
 3 files changed, 69 insertions(+), 35 deletions(-)

diff --git a/util/cbfstool/cbfs_image.c b/util/cbfstool/cbfs_image.c
index 0230d80..621a35d 100644
--- a/util/cbfstool/cbfs_image.c
+++ b/util/cbfstool/cbfs_image.c
@@ -267,7 +267,8 @@ int cbfs_image_create(struct cbfs_image *image,
 	return 0;
 }
 
-int cbfs_image_from_file(struct cbfs_image *image, const char *filename)
+int cbfs_image_from_file(struct cbfs_image *image,
+			 const char *filename, uint32_t offset)
 {
 	void *header_loc;
 
@@ -275,7 +276,9 @@ int cbfs_image_from_file(struct cbfs_image *image, const char *filename)
 		return -1;
 	DEBUG("read_cbfs_image: %s (%zd bytes)\n", image->buffer.name,
 	      image->buffer.size);
-	header_loc = cbfs_find_header(image->buffer.data, image->buffer.size);
+	header_loc = cbfs_find_header(image->buffer.data,
+					 image->buffer.size,
+					 offset);
 	if (!header_loc) {
 		ERROR("%s does not have CBFS master header.\n", filename);
 		cbfs_image_delete(image);
@@ -767,21 +770,41 @@ int cbfs_walk(struct cbfs_image *image, cbfs_entry_callback callback,
 	return count;
 }
 
-struct cbfs_header *cbfs_find_header(char *data, size_t size)
+static int cbfs_header_valid(struct cbfs_header *header, size_t size)
+{
+	if ((ntohl(header->magic) == CBFS_HEADER_MAGIC) &&
+	    ((ntohl(header->version) == CBFS_HEADER_VERSION1) ||
+	     (ntohl(header->version) == CBFS_HEADER_VERSION2)) &&
+	    (ntohl(header->romsize) <= size) &&
+	    (ntohl(header->offset) < ntohl(header->romsize)))
+		return 1;
+	return 0;
+}
+
+struct cbfs_header *cbfs_find_header(char *data, size_t size,
+				     uint32_t forced_offset)
 {
 	size_t offset;
 	int found = 0;
 	int32_t rel_offset;
 	struct cbfs_header *header, *result = NULL;
 
+	if (forced_offset < (size - sizeof(struct cbfs_header))) {
+		/* Check if the forced header is valid. */
+		header = (struct cbfs_header *)(data + forced_offset);
+		if (cbfs_header_valid(header, size))
+			return header;
+		return NULL;
+	}
+
 	// Try finding relative offset of master header at end of file first.
 	rel_offset = *(int32_t *)(data + size - sizeof(int32_t));
 	offset = size + rel_offset;
 	DEBUG("relative offset: %#zx(-%#zx), offset: %#zx\n",
 	      (size_t)rel_offset, (size_t)-rel_offset, offset);
+
 	if (offset >= size - sizeof(*header) ||
-	    ntohl(((struct cbfs_header *)(data + offset))->magic) !=
-	    CBFS_HEADER_MAGIC) {
+	    !cbfs_header_valid((struct cbfs_header *)(data + offset), size)) {
 		// Some use cases append non-CBFS data to the end of the ROM.
 		DEBUG("relative offset seems wrong, scanning whole image...\n");
 		offset = 0;
@@ -789,13 +812,8 @@ struct cbfs_header *cbfs_find_header(char *data, size_t size)
 
 	for (; offset + sizeof(*header) < size; offset++) {
 		header = (struct cbfs_header *)(data + offset);
-		if (ntohl(header->magic) !=(CBFS_HEADER_MAGIC))
-		    continue;
-		if (ntohl(header->version) != CBFS_HEADER_VERSION1 &&
-		    ntohl(header->version) != CBFS_HEADER_VERSION2) {
-			// Probably not a real CBFS header?
+		if (!cbfs_header_valid(header, size))
 			continue;
-		}
 		if (!found++)
 			result = header;
 	}
diff --git a/util/cbfstool/cbfs_image.h b/util/cbfstool/cbfs_image.h
index 0a05eb2..2c1be3d 100644
--- a/util/cbfstool/cbfs_image.h
+++ b/util/cbfstool/cbfs_image.h
@@ -52,7 +52,8 @@ int cbfs_image_create(struct cbfs_image *image,
 		      int32_t entries_offset);
 
 /* Loads a CBFS image from file. Returns 0 on success, otherwise non-zero. */
-int cbfs_image_from_file(struct cbfs_image *image, const char *filename);
+int cbfs_image_from_file(struct cbfs_image *image,
+			 const char *filename, uint32_t offset);
 
 /* Writes a CBFS image into file. Returns 0 on success, otherwise non-zero. */
 int cbfs_image_write_file(struct cbfs_image *image, const char *filename);
@@ -106,7 +107,8 @@ int cbfs_walk(struct cbfs_image *image, cbfs_entry_callback callback, void *arg)
  * NULL (including when multiple headers were found). If there is a X86 ROM
  * style signature (pointer at 0xfffffffc) found in ROM, it will be selected as
  * the only header.*/
-struct cbfs_header *cbfs_find_header(char *data, size_t size);
+struct cbfs_header *cbfs_find_header(char *data, size_t size,
+				     uint32_t forced_offset);
 
 /* Returns the first cbfs_file entry in CBFS image by CBFS header (no matter if
  * the entry has valid content or not), otherwise NULL. */
diff --git a/util/cbfstool/cbfstool.c b/util/cbfstool/cbfstool.c
index 9c61119..20e5e0c 100644
--- a/util/cbfstool/cbfstool.c
+++ b/util/cbfstool/cbfstool.c
@@ -66,6 +66,7 @@ static struct param {
 	/* All variables not listed are initialized as zero. */
 	.arch = CBFS_ARCHITECTURE_UNKNOWN,
 	.algo = CBFS_COMPRESS_NONE,
+	.headeroffset = ~0,
 };
 
 typedef int (*convert_buffer_t)(struct buffer *buffer, uint32_t *offset);
@@ -73,7 +74,8 @@ typedef int (*convert_buffer_t)(struct buffer *buffer, uint32_t *offset);
 static int cbfs_add_integer_component(const char *cbfs_name,
 			      const char *name,
 			      uint64_t u64val,
-			      uint32_t offset) {
+			      uint32_t offset,
+			      uint32_t headeroffset) {
 	struct cbfs_image image;
 	struct buffer buffer;
 	int i, ret = 1;
@@ -89,7 +91,7 @@ static int cbfs_add_integer_component(const char *cbfs_name,
 	for (i = 0; i < 8; i++)
 		buffer.data[i] = (u64val >> i*8) & 0xff;
 
-	if (cbfs_image_from_file(&image, cbfs_name) != 0) {
+	if (cbfs_image_from_file(&image, cbfs_name, headeroffset) != 0) {
 		ERROR("Could not load ROM image '%s'.\n", cbfs_name);
 		buffer_delete(&buffer);
 		return 1;
@@ -119,6 +121,7 @@ static int cbfs_add_component(const char *cbfs_name,
 			      const char *name,
 			      uint32_t type,
 			      uint32_t offset,
+			      uint32_t headeroffset,
 			      convert_buffer_t convert)
 {
 	struct cbfs_image image;
@@ -139,7 +142,7 @@ static int cbfs_add_component(const char *cbfs_name,
 		return 1;
 	}
 
-	if (cbfs_image_from_file(&image, cbfs_name) != 0) {
+	if (cbfs_image_from_file(&image, cbfs_name, headeroffset) != 0) {
 		ERROR("Could not load ROM image '%s'.\n", cbfs_name);
 		return 1;
 	}
@@ -249,6 +252,7 @@ static int cbfs_add(void)
 				  param.name,
 				  param.type,
 				  param.baseaddress,
+				  param.headeroffset,
 				  NULL);
 }
 
@@ -259,6 +263,7 @@ static int cbfs_add_stage(void)
 				  param.name,
 				  CBFS_COMPONENT_STAGE,
 				  param.baseaddress,
+				  param.headeroffset,
 				  cbfstool_convert_mkstage);
 }
 
@@ -269,6 +274,7 @@ static int cbfs_add_payload(void)
 				  param.name,
 				  CBFS_COMPONENT_PAYLOAD,
 				  param.baseaddress,
+				  param.headeroffset,
 				  cbfstool_convert_mkpayload);
 }
 
@@ -289,6 +295,7 @@ static int cbfs_add_flat_binary(void)
 				  param.name,
 				  CBFS_COMPONENT_PAYLOAD,
 				  param.baseaddress,
+				  param.headeroffset,
 				  cbfstool_convert_mkflatpayload);
 }
 
@@ -297,7 +304,8 @@ static int cbfs_add_integer(void)
 	return cbfs_add_integer_component(param.cbfs_name,
 				  param.name,
 				  param.u64val,
-				  param.baseaddress);
+				  param.baseaddress,
+				  param.headeroffset);
 }
 
 static int cbfs_remove(void)
@@ -309,7 +317,8 @@ static int cbfs_remove(void)
 		return 1;
 	}
 
-	if (cbfs_image_from_file(&image, param.cbfs_name) != 0) {
+	if (cbfs_image_from_file(&image, param.cbfs_name,
+		param.headeroffset) != 0) {
 		ERROR("Could not load ROM image '%s'.\n",
 			param.cbfs_name);
 		return 1;
@@ -433,7 +442,8 @@ static int cbfs_locate(void)
 		return 1;
 	}
 
-	if (cbfs_image_from_file(&image, param.cbfs_name) != 0) {
+	if (cbfs_image_from_file(&image, param.cbfs_name,
+		param.headeroffset) != 0) {
 		ERROR("Failed to load %s.\n", param.cbfs_name);
 		return 1;
 	}
@@ -469,7 +479,8 @@ static int cbfs_locate(void)
 static int cbfs_print(void)
 {
 	struct cbfs_image image;
-	if (cbfs_image_from_file(&image, param.cbfs_name) != 0) {
+	if (cbfs_image_from_file(&image, param.cbfs_name,
+		param.headeroffset) != 0) {
 		ERROR("Could not load ROM image '%s'.\n",
 			param.cbfs_name);
 		return 1;
@@ -494,7 +505,8 @@ static int cbfs_extract(void)
 		return 1;
 	}
 
-	if (cbfs_image_from_file(&image, param.cbfs_name) != 0) {
+	if (cbfs_image_from_file(&image, param.cbfs_name,
+		param.headeroffset) != 0) {
 		ERROR("Could not load ROM image '%s'.\n",
 			param.cbfs_name);
 		result = 1;
@@ -523,7 +535,8 @@ static int cbfs_update_fit(void)
 		return 1;
 	}
 
-	if (cbfs_image_from_file(&image, param.cbfs_name) != 0) {
+	if (cbfs_image_from_file(&image, param.cbfs_name,
+		param.headeroffset) != 0) {
 		ERROR("Could not load ROM image '%s'.\n",
 			param.cbfs_name);
 		return 1;
@@ -538,17 +551,17 @@ static int cbfs_update_fit(void)
 }
 
 static const struct command commands[] = {
-	{"add", "f:n:t:b:vh?", cbfs_add},
-	{"add-payload", "f:n:t:c:b:vh?C:I:", cbfs_add_payload},
-	{"add-stage", "f:n:t:c:b:S:vh?", cbfs_add_stage},
-	{"add-flat-binary", "f:n:l:e:c:b:vh?", cbfs_add_flat_binary},
-	{"add-int", "i:n:b:vh?", cbfs_add_integer},
-	{"remove", "n:vh?", cbfs_remove},
+	{"add", "H;f:n:t:b:vh?", cbfs_add},
+	{"add-payload", "H:f:n:t:c:b:vh?C:I:", cbfs_add_payload},
+	{"add-stage", "H:f:n:t:c:b:S:vh?", cbfs_add_stage},
+	{"add-flat-binary", "H:f:n:l:e:c:b:vh?", cbfs_add_flat_binary},
+	{"add-int", "H:i:n:b:vh?", cbfs_add_integer},
+	{"remove", "H:n:vh?", cbfs_remove},
 	{"create", "s:B:b:H:a:o:m:vh?", cbfs_create},
-	{"locate", "f:n:P:a:Tvh?", cbfs_locate},
-	{"print", "vh?", cbfs_print},
-	{"extract", "n:f:vh?", cbfs_extract},
-	{"update-fit", "n:x:vh?", cbfs_update_fit},
+	{"locate", "H:f:n:P:a:Tvh?", cbfs_locate},
+	{"print", "H:vh?", cbfs_print},
+	{"extract", "H:n:f:vh?", cbfs_extract},
+	{"update-fit", "H:n:x:vh?", cbfs_update_fit},
 };
 
 static struct option long_options[] = {
@@ -583,9 +596,10 @@ static void usage(char *name)
 	    ("cbfstool: Management utility for CBFS formatted ROM images\n\n"
 	     "USAGE:\n" " %s [-h]\n"
 	     " %s FILE COMMAND [-v] [PARAMETERS]...\n\n" "OPTIONs:\n"
-	     "  -T              Output top-aligned memory address\n"
-	     "  -v              Provide verbose output\n"
-	     "  -h              Display this help message\n\n"
+	     "  -H header_offset  Do not search for header, use this offset\n"
+	     "  -T                Output top-aligned memory address\n"
+	     "  -v                Provide verbose output\n"
+	     "  -h                Display this help message\n\n"
 	     "COMMANDs:\n"
 	     " add -f FILE -n NAME -t TYPE [-b base-address]               "
 			"Add a component\n"



More information about the coreboot-gerrit mailing list