[coreboot] Patch set updated for coreboot: 175fbae cbfstool: Add cbfs_image new CBFS image manipulation API.

Hung-Te Lin (hungte@chromium.org) gerrit at coreboot.org
Mon Jan 28 20:03:06 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/2194

-gerrit

commit 175fbae895525bcfcff7f09d23be8c8ec94eb244
Author: Hung-Te Lin <hungte at chromium.org>
Date:   Tue Jan 29 01:56:17 2013 +0800

    cbfstool: Add cbfs_image new CBFS image manipulation API.
    
    Current cbfstool implementation is based on x86 architecture, and is not easy to
    be used on platforms without top-aligned memory mapping. This CL is the first
    step to start a new cbfstool, including reading and writing existing CBFS ROM
    image files (and to find file entries in a ROM file).
    
    Read cbfs_image.h for detail usage of each API function.
    
    Change-Id: I28c737c8f290e51332119188248ac9e28042024c
    Signed-off-by: Hung-Te Lin <hungte at chromium.org>
---
 util/cbfstool/Makefile     |   2 +-
 util/cbfstool/Makefile.inc |   1 +
 util/cbfstool/cbfs.h       |   2 +
 util/cbfstool/cbfs_image.c | 128 +++++++++++++++++++++++++++++++++++++++++++++
 util/cbfstool/cbfs_image.h |  65 +++++++++++++++++++++++
 5 files changed, 197 insertions(+), 1 deletion(-)

diff --git a/util/cbfstool/Makefile b/util/cbfstool/Makefile
index 17b00a7..3ace744 100644
--- a/util/cbfstool/Makefile
+++ b/util/cbfstool/Makefile
@@ -7,7 +7,7 @@ CFLAGS   += -D_7ZIP_ST
 
 BINARY:=$(obj)/cbfstool
 
-COMMON:=cbfstool.o common.o compress.o
+COMMON:=cbfstool.o common.o cbfs_image.o compress.o
 COMMON+=cbfs-mkstage.o cbfs-mkpayload.o
 # LZMA
 COMMON+=lzma/lzma.o
diff --git a/util/cbfstool/Makefile.inc b/util/cbfstool/Makefile.inc
index 5795507..2cee794 100644
--- a/util/cbfstool/Makefile.inc
+++ b/util/cbfstool/Makefile.inc
@@ -2,6 +2,7 @@ cbfsobj :=
 cbfsobj += cbfstool.o
 cbfsobj += common.o
 cbfsobj += compress.o
+cbfsobj += cbfs_image.o
 cbfsobj += cbfs-mkstage.o
 cbfsobj += cbfs-mkpayload.o
 # LZMA
diff --git a/util/cbfstool/cbfs.h b/util/cbfstool/cbfs.h
index 3dbeefd..4a3ff94 100644
--- a/util/cbfstool/cbfs.h
+++ b/util/cbfstool/cbfs.h
@@ -42,6 +42,8 @@ struct cbfs_header {
 #define CBFS_ARCHITECTURE_X86      0x00000001
 #define CBFS_ARCHITECTURE_ARMV7    0x00000010
 
+#define CBFS_FILE_MAGIC "LARCHIVE"
+
 struct cbfs_file {
 	uint8_t magic[8];
 	uint32_t len;
diff --git a/util/cbfstool/cbfs_image.c b/util/cbfstool/cbfs_image.c
new file mode 100644
index 0000000..569d108
--- /dev/null
+++ b/util/cbfstool/cbfs_image.c
@@ -0,0 +1,128 @@
+/*
+ * CBFS Image Manipulation
+ *
+ * Copyright (C) 2013 The ChromiumOS Authors.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "common.h"
+#include "cbfs_image.h"
+
+/* The file name align is not defined in CBFS spec -- only a preference by
+ * (old) cbfstool. */
+#define CBFS_FILENAME_ALIGN	(16)
+
+/* To make CBFS more friendly to ROM, fill -1 (0xFF) instead of zero. */
+#define CBFS_CONTENT_DEFAULT_VALUE	(-1)
+
+static uint32_t align_up(uint32_t value, uint32_t align) {
+	if (value % align)
+		value += align - (value % align);
+	return value;
+}
+
+int cbfs_image_from_file(struct cbfs_image *image, const char *filename) {
+	if (buffer_from_file(&image->buffer, filename) != 0)
+		return -1;
+	DEBUG("read_cbfs_image: %s (%zd bytes)\n", image->buffer.name,
+	      image->buffer.size);
+	image->header = cbfs_find_header(image->buffer.data,
+					 image->buffer.size);
+	if (!image->header) {
+		ERROR("%s does not have CBFS master header.\n", filename);
+		cbfs_image_delete(image);
+		return -1;
+	}
+
+	return 0;
+}
+
+int cbfs_image_write_file(struct cbfs_image *image, const char *filename) {
+	assert(image && image->buffer.data);
+	return buffer_write_file(&image->buffer, filename);
+}
+
+int cbfs_image_delete(struct cbfs_image *image) {
+	buffer_delete(&image->buffer);
+	image->header = NULL;
+	return 0;
+}
+
+struct cbfs_header *cbfs_find_header(char *data, size_t size) {
+	size_t offset;
+	int found = 0;
+	uint32_t x86sig;
+	struct cbfs_header *header, *result = NULL;
+
+	// Try x86 style (check signature in bottom) header first.
+	x86sig = *(uint32_t *)(data + size - sizeof(uint32_t));
+	offset = (x86sig + (uint32_t)size);
+	DEBUG("x86sig: 0x%x, offset: 0x%zx\n", x86sig, offset);
+	if (offset >= size - sizeof(*header) ||
+	    ntohl(((struct cbfs_header *)(data + offset))->magic) !=
+	    CBFS_HEADER_MAGIC)
+		offset = 0;
+
+	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?
+			continue;
+		}
+		found++;
+		result = header;
+	}
+	if (found > 1) {
+		ERROR("multiple (%d) CBFS headers found!\n",
+		       found);
+		result = NULL;
+	}
+	return result;
+}
+
+
+struct cbfs_file *cbfs_find_first_entry(struct cbfs_image *image) {
+	assert(image && image->header);
+	return (struct cbfs_file *)(image->buffer.data +
+				   ntohl(image->header->offset));
+}
+
+struct cbfs_file *cbfs_find_next_entry(struct cbfs_image *image,
+				       struct cbfs_file *entry) {
+	uint32_t addr = cbfs_get_entry_addr(image, entry);
+	int align = ntohl(image->header->align);
+	assert(entry && cbfs_is_valid_entry(entry));
+	addr += ntohl(entry->offset) + ntohl(entry->len);
+	addr = align_up(addr, align);
+	return (struct cbfs_file *)(image->buffer.data + addr);
+}
+
+uint32_t cbfs_get_entry_addr(struct cbfs_image *image, struct cbfs_file *entry) {
+	assert(image && image->buffer.data && entry);
+	return (int32_t)((char *)entry - image->buffer.data);
+}
+
+int cbfs_is_valid_entry(struct cbfs_file *entry) {
+	return (entry &&memcmp(entry->magic, CBFS_FILE_MAGIC,
+			       sizeof(entry->magic)) == 0);
+}
+
diff --git a/util/cbfstool/cbfs_image.h b/util/cbfstool/cbfs_image.h
new file mode 100644
index 0000000..617a716
--- /dev/null
+++ b/util/cbfstool/cbfs_image.h
@@ -0,0 +1,65 @@
+/*
+ * CBFS Image Manipulation
+ *
+ * Copyright (C) 2013 The ChromiumOS Authors.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
+ */
+
+#ifndef __CBFS_IMAGE_H
+#define __CBFS_IMAGE_H
+#include "common.h"
+#include "cbfs.h"
+
+/* CBFS image processing */
+
+struct cbfs_image {
+	struct buffer buffer;
+	struct cbfs_header *header;
+};
+
+/* 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);
+
+/* 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);
+
+/* Releases the CBFS image. Returns 0 on success, otherwise non-zero. */
+int cbfs_image_delete(struct cbfs_image *image);
+
+/* Primitive CBFS utilities */
+
+/* Returns a pointer to the only valid CBFS header in give buffer, otherwise
+ * 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);
+
+/* Returns the first cbfs_file entry in CBFS image by CBFS header (no matter if
+ * the entry has valid content or not), otherwise NULL. */
+struct cbfs_file *cbfs_find_first_entry(struct cbfs_image *image);
+
+/* Returns next cbfs_file entry (no matter if its content is valid or not), or
+ * NULL on failure. */
+struct cbfs_file *cbfs_find_next_entry(struct cbfs_image *image,
+				       struct cbfs_file *entry);
+
+/* Returns ROM address (offset) of entry.
+ * This is different from entry->offset (pointer to content). */
+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);
+
+#endif



More information about the coreboot mailing list