[coreboot] Patch set updated for coreboot: 2fa2bce cbfstool: Use cbfs_image API for "print" command.

Hung-Te Lin (hungte@chromium.org) gerrit at coreboot.org
Tue Jan 29 02:55:25 CET 2013


Hung-Te Lin (hungte at chromium.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2206

-gerrit

commit 2fa2bce828421d0dd1dff66a8f0690e5cc10f7da
Author: Hung-Te Lin <hungte at chromium.org>
Date:   Tue Jan 29 02:15:49 2013 +0800

    cbfstool: Use cbfs_image API for "print" command.
    
    First attempt to process CBFS ROM image by cbfs_image API.
    To verify, run "cbfstool coreboot.rom print -v" and compare with old cbfstool.
    
    Change-Id: I3a5a9ef176596d825e6cdba28a8ad732f69f5600
    Signed-off-by: Hung-Te Lin <hungte at chromium.org>
---
 util/cbfstool/cbfs.h       |   1 +
 util/cbfstool/cbfs_image.c | 209 +++++++++++++++++++++++++++++++++++++++++++++
 util/cbfstool/cbfs_image.h |  17 ++++
 util/cbfstool/cbfstool.c   |  13 ++-
 4 files changed, 232 insertions(+), 8 deletions(-)

diff --git a/util/cbfstool/cbfs.h b/util/cbfstool/cbfs.h
index 4a3ff94..35d0670 100644
--- a/util/cbfstool/cbfs.h
+++ b/util/cbfstool/cbfs.h
@@ -108,6 +108,7 @@ struct cbfs_payload {
 #define CBFS_COMPONENT_NULL 0xFFFFFFFF
 
 int cbfs_file_header(unsigned long physaddr);
+#define CBFS_NAME(_c) (((char *) (_c)) + sizeof(struct cbfs_file))
 #define CBFS_SUBHEADER(_p) ( (void *) ((((uint8_t *) (_p)) + ntohl((_p)->offset))) )
 
 struct cbfs_file *cbfs_create_empty_file(uint32_t physaddr, uint32_t size);
diff --git a/util/cbfstool/cbfs_image.c b/util/cbfstool/cbfs_image.c
index 569d108..d16ca0f 100644
--- a/util/cbfstool/cbfs_image.c
+++ b/util/cbfstool/cbfs_image.c
@@ -17,6 +17,7 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
  */
 
+#include <inttypes.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -37,6 +38,65 @@ static uint32_t align_up(uint32_t value, uint32_t align) {
 	return value;
 }
 
+/* Type and format */
+
+struct typedesc_t {
+	uint32_t type;
+	const char *name;
+};
+
+static struct typedesc_t types_cbfs_entry[] = {
+	{CBFS_COMPONENT_STAGE, "stage"},
+	{CBFS_COMPONENT_PAYLOAD, "payload"},
+	{CBFS_COMPONENT_OPTIONROM, "optionrom"},
+	{CBFS_COMPONENT_BOOTSPLASH, "bootsplash"},
+	{CBFS_COMPONENT_RAW, "raw"},
+	{CBFS_COMPONENT_VSA, "vsa"},
+	{CBFS_COMPONENT_MBI, "mbi"},
+	{CBFS_COMPONENT_MICROCODE, "microcode"},
+	{CBFS_COMPONENT_CMOS_DEFAULT, "cmos_default"},
+	{CBFS_COMPONENT_CMOS_LAYOUT, "cmos_layout"},
+	{CBFS_COMPONENT_DELETED, "deleted"},
+	{CBFS_COMPONENT_NULL, "null"},
+	{0, NULL},
+};
+
+static struct typedesc_t types_cbfs_compression[] = {
+	{CBFS_COMPRESS_NONE, "none"},
+	{CBFS_COMPRESS_LZMA, "LZMA"},
+	{0, NULL},
+};
+
+uint32_t lookup_type_by_name(struct typedesc_t *desc, const char *name,
+			     uint32_t default_value) {
+	int i;
+	for (i = 0; desc[i].name; i++)
+		if (strcmp(desc[i].name, name) == 0)
+			return desc[i].type;
+	return default_value;
+}
+
+const char *lookup_name_by_type(struct typedesc_t *desc, uint32_t type,
+				const char *default_value) {
+	int i;
+	for (i = 0; desc[i].name; i++)
+		if (desc[i].type == type)
+			return desc[i].name;
+	return default_value;
+}
+
+uint32_t get_cbfs_entry_type(const char *name, uint32_t default_value) {
+	return lookup_type_by_name(types_cbfs_entry, name, default_value);
+}
+
+const char *get_cbfs_entry_type_name(uint32_t type) {
+	return lookup_name_by_type(types_cbfs_entry, type, "(unknown)");
+}
+
+uint32_t get_cbfs_compression(const char *name, uint32_t unknown) {
+	return lookup_type_by_name(types_cbfs_compression, name, unknown);
+}
+
 int cbfs_image_from_file(struct cbfs_image *image, const char *filename) {
 	if (buffer_from_file(&image->buffer, filename) != 0)
 		return -1;
@@ -64,6 +124,155 @@ int cbfs_image_delete(struct cbfs_image *image) {
 	return 0;
 }
 
+int cbfs_print_header_info(struct cbfs_image *image) {
+	assert(image && image->header);
+	printf("%s: %zd kB, bootblocksize %d, romsize %d, offset 0x%x\n"
+	       "alignment: %d bytes\n\n",
+	       simple_basename(image->buffer.name),
+	       image->buffer.size / 1024,
+	       ntohl(image->header->bootblocksize),
+	       ntohl(image->header->romsize),
+	       ntohl(image->header->offset),
+	       ntohl(image->header->align));
+	return 0;
+}
+
+static int cbfs_print_stage_info(struct cbfs_stage *stage, FILE* fp) {
+	fprintf(fp,
+		"    %s compression, entry: 0x%" PRIx64 ", load: 0x%" PRIx64 ", "
+		"length: %d/%d\n",
+		lookup_name_by_type(types_cbfs_compression,
+				    stage->compression, "(unknown)"),
+		stage->entry,
+		stage->load,
+		stage->len,
+		stage->memlen);
+	return 0;
+}
+
+static int cbfs_print_payload_segment_info(struct cbfs_payload_segment *payload,
+					   FILE *fp)
+{
+	switch(payload->type) {
+		case PAYLOAD_SEGMENT_CODE:
+		case PAYLOAD_SEGMENT_DATA:
+			fprintf(fp, "    %s (%s compression, offset: 0x%x, "
+				"load: 0x%" PRIx64 ", length: %d/%d)\n",
+				(payload->type == PAYLOAD_SEGMENT_CODE ?
+				 "code " : "data"),
+				lookup_name_by_type(types_cbfs_compression,
+						    ntohl(payload->compression),
+						    "(unknown)"),
+				ntohl(payload->offset),
+				ntohll(payload->load_addr),
+				ntohl(payload->len), ntohl(payload->mem_len));
+			break;
+
+		case PAYLOAD_SEGMENT_ENTRY:
+			fprintf(fp, "    entry (0x%" PRIx64 ")\n",
+				ntohll(payload->load_addr));
+			break;
+
+		case PAYLOAD_SEGMENT_BSS:
+			fprintf(fp, "    BSS (address 0x%016" PRIx64 ", "
+				"length 0x%x)\n",
+				ntohll(payload->load_addr),
+				ntohl(payload->len));
+			break;
+
+		case PAYLOAD_SEGMENT_PARAMS:
+			fprintf(fp, "    parameters\n");
+			break;
+
+		default:
+			fprintf(fp, "   0x%x (%s compression, offset: 0x%x, "
+				"load: 0x%" PRIx64 ", length: %d/%d\n",
+				payload->type,
+				lookup_name_by_type(types_cbfs_compression,
+						    payload->compression,
+						    "(unknown)"),
+				ntohl(payload->offset),
+				ntohll(payload->load_addr),
+				ntohl(payload->len),
+				ntohl(payload->mem_len));
+			break;
+	}
+	return 0;
+}
+
+int cbfs_print_entry_info(struct cbfs_image *image, struct cbfs_file *entry,
+			  void *arg) {
+	const char *name = CBFS_NAME(entry);
+	struct cbfs_payload_segment *payload;
+	FILE *fp = (FILE *)arg;
+
+	if (!cbfs_is_valid_entry(entry)) {
+		ERROR("cbfs_print_entry_info: Invalid entry at 0x%x\n",
+		      cbfs_get_entry_addr(image, entry));
+		return -1;
+	}
+	if (!fp)
+		fp = stdout;
+
+	fprintf(fp, "%-30s 0x%-8x %-12s %d\n",
+		*name ? name : "(empty)",
+		cbfs_get_entry_addr(image, entry),
+		get_cbfs_entry_type_name(ntohl(entry->type)),
+		ntohl(entry->len));
+
+	if (!verbose)
+		return 0;
+
+	DEBUG(" cbfs_file=0x%x, offset=0x%x, content_address=0x%x+0x%x\n",
+	      cbfs_get_entry_addr(image, entry), ntohl(entry->offset),
+	      cbfs_get_entry_addr(image, entry) + ntohl(entry->offset),
+	      ntohl(entry->len));
+
+	/* note the components of the subheader may be in host order ... */
+	switch (ntohl(entry->type)) {
+		case CBFS_COMPONENT_STAGE:
+			cbfs_print_stage_info((struct cbfs_stage *)
+					      CBFS_SUBHEADER(entry), fp);
+			break;
+
+		case CBFS_COMPONENT_PAYLOAD:
+			payload  = (struct cbfs_payload_segment *)
+					CBFS_SUBHEADER(entry);
+			while (payload) {
+				cbfs_print_payload_segment_info(payload, fp);
+				if (payload->type == PAYLOAD_SEGMENT_ENTRY)
+					break;
+				else
+					payload ++;
+			}
+			break;
+		default:
+			break;
+	}
+	return 0;
+}
+
+int cbfs_print_directory(struct cbfs_image *image) {
+	cbfs_print_header_info(image);
+	printf("%-30s %-10s %-12s Size\n", "Name", "Offset", "Type");
+	cbfs_walk(image, cbfs_print_entry_info, NULL);
+	return 0;
+}
+
+int cbfs_walk(struct cbfs_image *image, cbfs_entry_callback callback,
+	      void *arg) {
+	int count = 0;
+	struct cbfs_file *entry;
+	for (entry = cbfs_find_first_entry(image);
+	     entry && cbfs_is_valid_entry(entry);
+	     entry = cbfs_find_next_entry(image, entry)) {
+		count ++;
+		if (callback(image, entry, arg) != 0)
+			break;
+	}
+	return count;
+}
+
 struct cbfs_header *cbfs_find_header(char *data, size_t size) {
 	size_t offset;
 	int found = 0;
diff --git a/util/cbfstool/cbfs_image.h b/util/cbfstool/cbfs_image.h
index 617a716..ed8be5a 100644
--- a/util/cbfstool/cbfs_image.h
+++ b/util/cbfstool/cbfs_image.h
@@ -38,6 +38,17 @@ int cbfs_image_write_file(struct cbfs_image *image, const char *filename);
 /* Releases the CBFS image. Returns 0 on success, otherwise non-zero. */
 int cbfs_image_delete(struct cbfs_image *image);
 
+/* Callback function used by cbfs_walk.
+ * Returns 0 on success, or non-zero to stop further iteration. */
+typedef int (*cbfs_entry_callback)(struct cbfs_image *image,
+				   struct cbfs_file *file,
+				   void *arg);
+
+/* Iterates through all entries in CBFS image, and invoke with callback.
+ * Stops if callback returns non-zero values.
+ * Returns number of entries invoked. */
+int cbfs_walk(struct cbfs_image *image, cbfs_entry_callback callback, void *arg);
+
 /* Primitive CBFS utilities */
 
 /* Returns a pointer to the only valid CBFS header in give buffer, otherwise
@@ -62,4 +73,10 @@ uint32_t cbfs_get_entry_addr(struct cbfs_image *image, struct cbfs_file *entry);
 /* Returns 1 if entry has valid data (by checking magic number), otherwise 0. */
 int cbfs_is_valid_entry(struct cbfs_file *entry);
 
+/* Print CBFS component information. */
+int cbfs_print_directory(struct cbfs_image *image);
+int cbfs_print_header_info(struct cbfs_image *image);
+int cbfs_print_entry_info(struct cbfs_image *image, struct cbfs_file *entry,
+			  void *arg);
+
 #endif
diff --git a/util/cbfstool/cbfstool.c b/util/cbfstool/cbfstool.c
index edab7e3..5e4f8f1 100644
--- a/util/cbfstool/cbfstool.c
+++ b/util/cbfstool/cbfstool.c
@@ -27,6 +27,7 @@
 #include <getopt.h>
 #include "common.h"
 #include "cbfs.h"
+#include "cbfs_image.h"
 
 struct command {
 	const char *name;
@@ -388,18 +389,14 @@ static int cbfs_locate_stage(void)
 
 static int cbfs_print(void)
 {
-	void *rom;
-
-	rom = loadrom(param.cbfs_name);
-	if (rom == NULL) {
+	struct cbfs_image image;
+	if (cbfs_image_from_file(&image, param.cbfs_name) != 0) {
 		ERROR("Could not load ROM image '%s'.\n",
 			param.cbfs_name);
 		return 1;
 	}
-
-	print_cbfs_directory(param.cbfs_name);
-
-	free(rom);
+	cbfs_print_directory(&image);
+	cbfs_image_delete(&image);
 	return 0;
 }
 



More information about the coreboot mailing list