[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