Hung-Te Lin (hun...@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 <hun...@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 <hun...@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

-- 
coreboot mailing list: coreboot@coreboot.org
http://www.coreboot.org/mailman/listinfo/coreboot

Reply via email to