[coreboot-gerrit] Patch set updated for coreboot: cb733af YOU SHALL NOT MERGE!

Alexandru Gagniuc (mr.nuke.me@gmail.com) gerrit at coreboot.org
Sun Jan 26 06:49:08 CET 2014


Alexandru Gagniuc (mr.nuke.me at gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4810

-gerrit

commit cb733af72e3fd026c21fe6d8e85064c1918fa80a
Author: Alexandru Gagniuc <mr.nuke.me at gmail.com>
Date:   Fri Jan 24 19:49:07 2014 -0600

    YOU SHALL NOT MERGE!
    
        ,                      _,-
       (\                  _,-','
        \\              ,-"  ,'
         \\           ,'   ,'
          \\        _:.----__.-."-._,-._
           \\    .-".:--`:::::.:.:'  )  `-.
            \\   `. ::L .::::::'`-._  (  ) :
             \\    ":::::::'  `-.   `-_ ) ,'
              \\.._/_`:::,' `.     .  `-:
              :" _   "\"" `-_    .    `  `.
               "\\"":--\     `-.__ ` .     `.
                 \\'::  \    _-"__`--.__ `  . `.     _,--..-
                  \\ ::  \_-":)(        ""-._ ` `.-''
                   \\`:`-":::/ \\ .   .      `-.  :
                   :\\:::::::'  \\     `    .   `. :
                    :\\:':':'  . \\           `,  : :
                    : \\     .    \\      .       `. :       ,-
                   __`:\\      .   \\ .   `  ,'    ,: :   ,-'
            _,---""  :  \\ '        \\  .          :-"  ,'
        ,-""        :    \\:  .  :   \\  `  '     ,'   /
       '            :  :  \       .   \\   .   _,'  ,-'
                   :  .   '       :   :`   `,-' ,--'
                    :     :   :      ,'-._,' ,-'
                    _:     :        :8:  ,--'
                   :dd`-._,'-._.__-""' ,'
                                 ,----'
                          _.----'
                  __..--""
                ""
    
    cbfstool: add preliminary partitioning suport
    
    Based on Proposal 2 of my user page
    
    Change-Id: I6770a9f8a459b4f204f5a75b98897a502af3ac66
    Signed-off-by: Alexandru Gagniuc <mr.nuke.me at gmail.com>
---
 util/cbfstool/Makefile.inc     |   1 +
 util/cbfstool/cbfs.h           |  15 ++++++-
 util/cbfstool/cbfs_image.c     |  58 ++++++++++++++++++++++++
 util/cbfstool/cbfs_image.h     |   2 +
 util/cbfstool/cbfs_partition.c | 100 +++++++++++++++++++++++++++++++++++++++++
 util/cbfstool/cbfs_partition.h |  24 ++++++++++
 util/cbfstool/cbfstool.c       |   2 +
 7 files changed, 201 insertions(+), 1 deletion(-)

diff --git a/util/cbfstool/Makefile.inc b/util/cbfstool/Makefile.inc
index fc120f3..c5d284c 100644
--- a/util/cbfstool/Makefile.inc
+++ b/util/cbfstool/Makefile.inc
@@ -3,6 +3,7 @@ cbfsobj += cbfstool.o
 cbfsobj += common.o
 cbfsobj += compress.o
 cbfsobj += cbfs_image.o
+cbfsobj += cbfs_partition.o
 cbfsobj += cbfs-mkstage.o
 cbfsobj += cbfs-mkpayload.o
 cbfsobj += fit.o
diff --git a/util/cbfstool/cbfs.h b/util/cbfstool/cbfs.h
index 35d0670..423e903 100644
--- a/util/cbfstool/cbfs.h
+++ b/util/cbfstool/cbfs.h
@@ -35,13 +35,26 @@ struct cbfs_header {
 	uint32_t align;
 	uint32_t offset;
 	uint32_t architecture;	/* Version 2 */
-	uint32_t pad[1];
+	uint32_t ptable_offset;
 } __attribute__ ((packed));
 
 #define CBFS_ARCHITECTURE_UNKNOWN  0xFFFFFFFF
 #define CBFS_ARCHITECTURE_X86      0x00000001
 #define CBFS_ARCHITECTURE_ARMV7    0x00000010
 
+#define CBFS_PARTITION_MAGIC		0x43425054	/* "CBPT" in ASCII */
+#define CBFS_PARTITION_NAME_LEN		32
+#define CBFS_PARTITION_ENTRY_LEN	0x30
+#define CBFS_PARTITION_ENTRY_ALIGN	0x10
+
+struct cbfs_partition {
+	uint32_t magic;
+	uint32_t offset;
+	uint32_t size;
+	uint32_t flags;
+	char name[32];
+}; /* Don't fucking pack this. If you need this packed, you have a bug */
+
 #define CBFS_FILE_MAGIC "LARCHIVE"
 
 struct cbfs_file {
diff --git a/util/cbfstool/cbfs_image.c b/util/cbfstool/cbfs_image.c
index 401654e..966aeea 100644
--- a/util/cbfstool/cbfs_image.c
+++ b/util/cbfstool/cbfs_image.c
@@ -25,6 +25,7 @@
 
 #include "common.h"
 #include "cbfs_image.h"
+#include "cbfs_partition.h"
 
 /* The file name align is not defined in CBFS spec -- only a preference by
  * (old) cbfstool. */
@@ -145,10 +146,12 @@ int cbfs_image_create(struct cbfs_image *image,
 		      struct buffer *bootblock,
 		      int32_t bootblock_offset,
 		      int32_t header_offset,
+		      int32_t ptable_offset,
 		      int32_t entries_offset)
 {
 	struct cbfs_header *header;
 	struct cbfs_file *entry;
+	struct cbfs_partition part;
 	uint32_t cbfs_len;
 	size_t entry_header_len;
 
@@ -159,6 +162,8 @@ int cbfs_image_create(struct cbfs_image *image,
 
 	if (buffer_create(&image->buffer, size, "(new)") != 0)
 		return -1;
+	if ((image->ptable = malloc(sizeof(part) * 11)) == NULL)
+		return -1;
 	image->header = NULL;
 	memset(image->buffer.data, CBFS_CONTENT_DEFAULT_VALUE, size);
 
@@ -229,6 +234,33 @@ int cbfs_image_create(struct cbfs_image *image,
 	if (header_offset > entries_offset && header_offset < cbfs_len)
 		cbfs_len = header_offset;
 	cbfs_len -= entries_offset + align + entry_header_len;
+
+	/*
+	 * Now find space for the partition table.
+	 * Pre-allocate 10 entries for now. This should be sufficient for most
+	 * use-cases, and makes sure we don't have to reduce the final entry.
+	 * FIXME: Only works for bootblock on top. We really should listen to
+	 * the wisdom of the caller and put this where requested.
+	 */
+	ptable_offset = header_offset - cbfs_ptable_calc_size(10);
+	/* Align down */
+	ptable_offset &= ~(CBFS_PARTITION_ENTRY_ALIGN - 1);
+	cbfs_len -= (bootblock_offset - ptable_offset);
+	if (IS_TOP_ALIGNED_ADDRESS(header_offset))
+		header_offset += (int32_t) size;
+	header->ptable_offset = ntohl(ptable_offset);
+
+	LOG("pizdatable offset 0x%x\n", ptable_offset);
+
+	/* No, don't use ntohl shit here */
+	cbfs_partition_entry_init(&image->ptable[0],
+				  "coreboot", entries_offset, cbfs_len, 0);
+	/* Terminate ptable list */
+	image->ptable[1].magic = 0xFFFFFFFF;
+
+	cbfs_ptable_serialize(image->buffer.data + ptable_offset,
+			      image->ptable);
+
 	cbfs_create_empty_entry(image, entry, cbfs_len, "");
 	LOG("Created CBFS image (capacity = %d bytes)\n", cbfs_len);
 	return 0;
@@ -236,6 +268,9 @@ int cbfs_image_create(struct cbfs_image *image,
 
 int cbfs_image_from_file(struct cbfs_image *image, const char *filename)
 {
+	uint32_t ptable_offset;
+	size_t parts;
+
 	if (buffer_from_file(&image->buffer, filename) != 0)
 		return -1;
 	DEBUG("read_cbfs_image: %s (%zd bytes)\n", image->buffer.name,
@@ -247,6 +282,24 @@ int cbfs_image_from_file(struct cbfs_image *image, const char *filename)
 		cbfs_image_delete(image);
 		return -1;
 	}
+
+	ptable_offset = ntohl(image->header->ptable_offset);
+	if (ptable_offset == 0xffffffff) {
+		LOG("No partition table found. Old image format?\n");
+		image->ptable = NULL;
+	} else {
+		/* Make this a debug. We'll print more info later */
+		DEBUG("Partition table found at 0x" PRIu32 "\n", ptable_offset);
+		parts = cbfs_ptable_find_num_entries(image->buffer.data + ptable_offset,
+					     image->buffer.size - ptable_offset);
+		DEBUG("Found %lu entries\n", parts);
+		if (parts) {
+			image->ptable = malloc(CBFS_PARTITION_ENTRY_LEN * parts);
+			cbfs_ptable_deserialize(image->ptable, image->buffer.data + ptable_offset);
+		}
+
+	}
+
 	cbfs_fix_legacy_size(image);
 
 	return 0;
@@ -261,7 +314,10 @@ int cbfs_image_write_file(struct cbfs_image *image, const char *filename)
 int cbfs_image_delete(struct cbfs_image *image)
 {
 	buffer_delete(&image->buffer);
+	if (image->ptable)
+		free(image->ptable);
 	image->header = NULL;
+	image->ptable = NULL;
 	return 0;
 }
 
@@ -658,6 +714,8 @@ int cbfs_print_entry_info(struct cbfs_image *image, struct cbfs_file *entry,
 int cbfs_print_directory(struct cbfs_image *image)
 {
 	cbfs_print_header_info(image);
+	printf("%-30s %-10s Size\n", "Partition name", "Offset");
+	cbfs_print_partitions(image->ptable);
 	printf("%-30s %-10s %-12s Size\n", "Name", "Offset", "Type");
 	cbfs_walk(image, cbfs_print_entry_info, NULL);
 	return 0;
diff --git a/util/cbfstool/cbfs_image.h b/util/cbfstool/cbfs_image.h
index 7ad418a..847ee5d 100644
--- a/util/cbfstool/cbfs_image.h
+++ b/util/cbfstool/cbfs_image.h
@@ -29,6 +29,7 @@
 struct cbfs_image {
 	struct buffer buffer;
 	struct cbfs_header *header;
+	struct cbfs_partition *ptable;
 };
 
 /* Creates an empty CBFS image by given size, and description to its content
@@ -43,6 +44,7 @@ int cbfs_image_create(struct cbfs_image *image,
 		      struct buffer *bootblock,
 		      int32_t bootblock_offset,
 		      int32_t header_offset,
+		      int32_t ptable_offset,
 		      int32_t entries_offset);
 
 /* Loads a CBFS image from file. Returns 0 on success, otherwise non-zero. */
diff --git a/util/cbfstool/cbfs_partition.c b/util/cbfstool/cbfs_partition.c
new file mode 100644
index 0000000..3de71e1
--- /dev/null
+++ b/util/cbfstool/cbfs_partition.c
@@ -0,0 +1,100 @@
+/*
+ * Manipulators for CBFS partitions
+ *
+ * Copyright (C) 2014 Alexandru Gagniuc <mr.nuke.me at gmail.com>
+ * Subject to the GNU GPL v2, or (at your option) any later version.
+ */
+
+#include "cbfs_partition.h"
+#include "endian_stream.h"
+
+#include <stdio.h>
+#include <string.h>
+
+size_t cbfs_ptable_calc_size(size_t num_entries)
+{
+	/* The last 4 bytes are the table terminator */
+	return CBFS_PARTITION_ENTRY_LEN * num_entries + 4;
+}
+
+void cbfs_partition_entry_init(struct cbfs_partition *part, const char *name,
+			       uint32_t offset, uint32_t size, uint32_t fags)
+{
+	part->magic = CBFS_PARTITION_MAGIC;
+	part->offset = offset;
+	part->size = size;
+	part->flags = fags;
+	strncpy(part->name, name, CBFS_PARTITION_NAME_LEN);
+}
+
+void cbfs_partition_serialize(void *dest, const struct cbfs_partition *part)
+{
+	h_to_be32(part->magic, dest + 0);
+	h_to_be32(part->offset, dest + 4);
+	h_to_be32(part->size, dest + 8);
+	h_to_be32(part->flags, dest + 12);
+	memset(dest + 16, 0xff, CBFS_PARTITION_NAME_LEN);
+	strncpy(dest + 16, part->name, CBFS_PARTITION_NAME_LEN);
+}
+
+void cbfs_partition_deserialize(struct cbfs_partition *part, const void *src)
+{
+	part->magic = be32_to_h(src + 0);
+	part->offset = be32_to_h(src + 4);
+	part->size = be32_to_h(src + 8);
+	part->flags = be32_to_h(src + 12);
+	strncpy(part->name, src + 16, CBFS_PARTITION_NAME_LEN);
+}
+
+void cbfs_ptable_serialize(void *dest, const struct cbfs_partition *part)
+{
+	while (part->magic == CBFS_PARTITION_MAGIC) {
+		cbfs_partition_serialize(dest, part);
+		part++;
+		dest += CBFS_PARTITION_ENTRY_LEN;
+	}
+	/* Terminate the list */
+	h_to_be32(0xffffffff, dest);
+}
+
+void cbfs_ptable_deserialize(struct cbfs_partition *part, const void *src)
+{
+	do {
+		cbfs_partition_deserialize(part, src);
+		part++;
+		src += CBFS_PARTITION_ENTRY_LEN;
+	} while(part->magic == CBFS_PARTITION_MAGIC);
+}
+
+/*
+ * Find the number of partition table entries in a given memory block
+ */
+size_t cbfs_ptable_find_num_entries(void *ptable, size_t memlen)
+{
+	uint32_t magic;
+	size_t offset = 0, num_entries = 0;
+
+	while (be32_to_h(ptable + offset) == CBFS_PARTITION_MAGIC) {
+		/* Complete entry? */
+		if (offset + CBFS_PARTITION_ENTRY_LEN > memlen)
+			break;
+
+		offset += CBFS_PARTITION_ENTRY_LEN;
+		num_entries++;
+
+		if (offset > memlen)
+			break;
+	}
+	return num_entries;
+}
+
+void cbfs_print_partitions(const struct cbfs_partition *ptable)
+{
+	while (ptable->magic == CBFS_PARTITION_MAGIC) {
+		printf("%-30s 0x%-8x %d\n",
+			ptable->name,
+			ptable->offset,
+			ptable->size);
+		ptable++;
+	}
+}
diff --git a/util/cbfstool/cbfs_partition.h b/util/cbfstool/cbfs_partition.h
new file mode 100644
index 0000000..f1d8129
--- /dev/null
+++ b/util/cbfstool/cbfs_partition.h
@@ -0,0 +1,24 @@
+/*
+ * Prototypes for manipulating for CBFS partitions
+ *
+ * Copyright (C) 2014 Alexandru Gagniuc <mr.nuke.me at gmail.com>
+ * Subject to the GNU GPL v2, or (at your option) any later version.
+ */
+
+#ifndef __CBFS_PARTITION_H
+#define __CBFS_PARTITION_H
+
+#include "cbfs.h"
+#include <stddef.h>
+
+void cbfs_partition_entry_init(struct cbfs_partition *part, const char *name,
+			       uint32_t offset, uint32_t size, uint32_t flags);
+void cbfs_partition_serialize(void *dest, const struct cbfs_partition *part);
+void cbfs_partition_deserialize(struct cbfs_partition *part, const void *src);
+size_t cbfs_ptable_calc_size(size_t num_entries);
+void cbfs_ptable_serialize(void *dest, const struct cbfs_partition *part);
+void cbfs_ptable_deserialize(struct cbfs_partition *part, const void *src);
+size_t cbfs_ptable_find_num_entries(void *ptable, size_t memlen);
+
+void cbfs_print_partitions(const struct cbfs_partition *ptable);
+#endif	/* __CBFS_PARTITION_H */
diff --git a/util/cbfstool/cbfstool.c b/util/cbfstool/cbfstool.c
index 34002a9..0040a98 100644
--- a/util/cbfstool/cbfstool.c
+++ b/util/cbfstool/cbfstool.c
@@ -55,6 +55,7 @@ static struct param {
 	uint32_t pagesize;
 	uint32_t offset;
 	uint32_t top_aligned;
+	uint32_t ptable_offset;
 	int fit_empty_entries;
 	comp_algo algo;
 	/* for linux payloads */
@@ -373,6 +374,7 @@ static int cbfs_create(void)
 			      &bootblock,
 			      param.baseaddress,
 			      param.headeroffset,
+			      param.ptable_offset,
 			      param.offset) != 0) {
 		ERROR("Failed to create %s.\n", param.cbfs_name);
 		return 1;



More information about the coreboot-gerrit mailing list