[coreboot-gerrit] New patch to review for coreboot: ifwitool: Support subpart add operation for bootblock

Furquan Shaikh (furquan@google.com) gerrit at coreboot.org
Tue May 24 20:48:18 CEST 2016


Furquan Shaikh (furquan at google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/14957

-gerrit

commit a637f29de1ee99003129313e734cd815e1122b0a
Author: Furquan Shaikh <furquan at google.com>
Date:   Tue May 24 11:45:27 2016 -0700

    ifwitool: Support subpart add operation for bootblock
    
    Change-Id: Iee86d6291c71958e4d8e68afaa984a05010dcaaf
    Signed-off-by: Furquan Shaikh <furquan at google.com>
---
 util/cbfstool/ifwitool.c | 235 +++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 208 insertions(+), 27 deletions(-)

diff --git a/util/cbfstool/ifwitool.c b/util/cbfstool/ifwitool.c
index 50846bb..b3b7dee 100644
--- a/util/cbfstool/ifwitool.c
+++ b/util/cbfstool/ifwitool.c
@@ -85,6 +85,62 @@ struct subpart {
 #define SUBPART_SIZE(c)			(SUBPART_HEADER_SIZE +  (c) * \
 						 SUBPART_ENTRY_SIZE)
 
+struct manifest_header {
+	uint32_t header_type;
+	uint32_t header_length;
+	uint32_t header_version;
+	uint32_t flags;
+	uint32_t vendor;
+	uint32_t date;
+	uint32_t size;
+	uint32_t id;
+	uint32_t rsvd;
+	uint64_t version;
+	uint32_t svn;
+	uint64_t rsvd1;
+	uint8_t rsvd2[64];
+	uint32_t modulus_size;
+	uint32_t exponent_size;
+	uint8_t public_key[256];
+	uint32_t exponent;
+	uint8_t signature[256];
+} __attribute__((packed));
+
+#define DWORD_SIZE				4
+#define MANIFEST_HDR_SIZE			(sizeof(struct manifest_header))
+#define MANIFEST_ID_MAGIC			(0x324e4d24)
+
+struct module {
+	uint8_t name[12];
+	uint8_t type;
+	uint8_t hash_alg;
+	uint16_t hash_size;
+	uint32_t metadata_size;
+	uint8_t metadata_hash[32];
+} __attribute__((packed));
+
+#define MODULE_SIZE				(sizeof(struct module))
+
+struct signed_pkg_info_ext {
+	uint32_t ext_type;
+	uint32_t ext_length;
+	uint8_t name[4];
+	uint32_t vcn;
+	uint8_t bitmap[16];
+	uint32_t svn;
+	uint8_t rsvd[16];
+} __attribute__((packed));
+
+#define SIGNED_PKG_INFO_EXT_TYPE		0x15
+#define SIGNED_PKG_INFO_EXT_SIZE		\
+	(sizeof(struct signed_pkg_info_ext))
+
+#define MANIFEST_SIZE(c)			(MANIFEST_HDR_SIZE + \
+						 SIGNED_PKG_INFO_EXT_SIZE + \
+						 MODULE_SIZE * c)
+
+#define EXT_SIZE(c)				(SIGNED_PKG_INFO_EXT_SIZE + \
+						 MODULE_SIZE * c)
 /*
  * Attributes for various IFWI components.
  * LIES_WITHIN_BPDT_4K = Component should lie within the same 4K block as BPDT.
@@ -191,6 +247,8 @@ struct cbp_ops {
 	enum ifwi_ret (*cbp_add)(int);
 };
 
+static enum ifwi_ret ibb_cbp_add(int);
+
 struct bpdt_comp {
 	const char *name;
 	uint32_t attr;
@@ -208,7 +266,7 @@ struct bpdt_comp {
 	/* uCode */
 	[UCODE_TYPE] = {"uCODE", CONTAINS_SUBPART, "UCOD", {NULL}},
 	/* IBB */
-	[IBB_TYPE] = {"bootblock", CONTAINS_SUBPART, "IBBP", {NULL}},
+	[IBB_TYPE] = {"bootblock", CONTAINS_SUBPART, "IBBP", {ibb_cbp_add}},
 	/* S-BPDT */
 	[S_BPDT_TYPE] = {"S_BPDT", AUTO_GENERATED | MANDATORY_BPDT_ENTRY,
 			 NULL, {NULL}},
@@ -1111,6 +1169,155 @@ static void ifwi_repack(void)
 	ifwi_write(param.image_name);
 }
 
+static void init_subpart_header(struct subpart_header *hdr, size_t count,
+				const char *name)
+{
+	memset(hdr, 0, sizeof(*hdr));
+
+	hdr->marker = SUBPART_MARKER;
+	hdr->num_entries = count;
+	hdr->header_version = SUBPART_HEADER_VERSION_SUPPORTED;
+	hdr->entry_version = SUBPART_ENTRY_VERSION_SUPPORTED;
+	hdr->header_length = SUBPART_HEADER_SIZE;
+	memcpy(hdr->name, name, sizeof(hdr->name));
+}
+
+static size_t init_subpart_entry(struct subpart_entry *e, struct buffer *b,
+				 size_t offset)
+{
+	memset(e, 0, sizeof(*e));
+
+	assert(strlen(b->name) <= sizeof(e->name));
+	strncpy((char *)e->name, (char *)b->name, sizeof(e->name));
+	e->offset = offset;
+	e->length = buffer_size(b);
+
+	return (offset + buffer_size(b));
+}
+
+static void init_manifest_header(struct manifest_header *hdr, size_t size)
+{
+	memset(hdr, 0, sizeof(*hdr));
+
+	hdr->header_type = 0x4;
+	assert((MANIFEST_HDR_SIZE % DWORD_SIZE) == 0);
+	hdr->header_length = MANIFEST_HDR_SIZE / DWORD_SIZE;
+	hdr->header_version = 0x10000;
+	hdr->vendor = 0x8086;
+	/* TODO(furquan): Set date in BCD format. */
+	assert((size % DWORD_SIZE) == 0);
+	hdr->size = size / DWORD_SIZE;
+	hdr->id = MANIFEST_ID_MAGIC;
+}
+
+static void init_signed_pkg_info_ext(struct signed_pkg_info_ext *ext,
+				     size_t count, const char *name)
+{
+	memset(ext, 0, sizeof(*ext));
+
+	ext->ext_type = SIGNED_PKG_INFO_EXT_TYPE;
+	ext->ext_length = EXT_SIZE(count);
+	memcpy(ext->name, name, sizeof(ext->name));
+}
+
+static void subpart_fixup_write_buffer(struct buffer *buf)
+{
+	struct subpart *s = buffer_get(buf);
+	struct subpart_header *h = &s->h;
+	struct subpart_entry *e = &s->e[0];
+
+	size_t count = h->num_entries;
+	size_t offset = 0;
+
+	FIX_MEMBER(h->marker);
+	FIX_MEMBER(h->num_entries);
+	FIX_MEMBER(h->header_version);
+	FIX_MEMBER(h->entry_version);
+	FIX_MEMBER(h->header_length);
+	FIX_MEMBER(h->checksum);
+	offset += sizeof(h->name);
+
+	uint32_t i;
+	for (i = 0; i < count; i++) {
+		offset += sizeof(e[i].name);
+		FIX_MEMBER(e[i].offset);
+		FIX_MEMBER(e[i].length);
+		FIX_MEMBER(e[i].rsvd);
+	}
+}
+
+static void create_subpart(struct buffer *dst, struct buffer *info[],
+			   size_t count, const char *name)
+{
+	alloc_buffer(&ifwi_image.subpart, SUBPART_SIZE(count), "subpart");
+	struct subpart_header *h = buffer_get(&ifwi_image.subpart);
+	struct subpart_entry *e = (struct subpart_entry *)(h + 1);
+
+	init_subpart_header(h, count, name);
+
+	size_t curr_offset = SUBPART_SIZE(count);
+	size_t i;
+
+	for (i = 0; i < count; i++) {
+		curr_offset = init_subpart_entry(&e[i], info[i],
+						 curr_offset);
+	}
+
+	alloc_buffer(dst, curr_offset, name);
+	uint8_t *data = buffer_get(dst);
+
+	for (i = 0; i < count; i++) {
+		memcpy(data + e[i].offset, buffer_get(info[i]),
+		       buffer_size(info[i]));
+	}
+
+	h->checksum = calc_checksum((struct subpart *)h);
+
+	print_subpart(name);
+
+	subpart_fixup_write_buffer(&ifwi_image.subpart);
+	memcpy(data, buffer_get(&ifwi_image.subpart),
+	       buffer_size(&ifwi_image.subpart));
+}
+
+static enum ifwi_ret ibb_cbp_add(int type)
+{
+#define DUMMY_IBB_SIZE			(4 * KiB)
+
+	assert (type == IBB_TYPE);
+
+	/* Entry # 1 - IBBP.man */
+	struct buffer manifest;
+	alloc_buffer(&manifest, MANIFEST_SIZE(0), "IBBP.man");
+
+	struct manifest_header *man_hdr = buffer_get(&manifest);
+	init_manifest_header(man_hdr, MANIFEST_SIZE(0));
+
+	struct signed_pkg_info_ext *ext;
+	ext = (struct signed_pkg_info_ext *)(man_hdr + 1);
+
+	init_signed_pkg_info_ext(ext, 0, comp[type].name);
+
+	/* Entry # 2 - IBBL */
+	struct buffer ibbl;
+	if (buffer_from_file(&ibbl, param.file_name))
+		return COMM_ERR;
+
+	/* Entry # 3 - IBB */
+	struct buffer ibb;
+	alloc_buffer(&ibb, DUMMY_IBB_SIZE, "IBB");
+	memset(buffer_get(&ibb), 0xFF, DUMMY_IBB_SIZE);
+
+	/* Create subpartition. */
+	struct buffer *info[] = {
+		&manifest, &ibbl, &ibb,
+	};
+	create_subpart(&ifwi_image.comp_buf[type], &info[0], ARRAY_SIZE(info),
+		       comp[type].subpart_name);
+
+	return REPACK_REQUIRED;
+}
+
 static enum ifwi_ret ifwi_raw_add(int type)
 {
 	if (buffer_from_file(&ifwi_image.comp_buf[type], param.file_name))
@@ -1320,32 +1527,6 @@ static enum ifwi_ret ifwi_raw_replace(int type)
 	return ifwi_raw_add(type);
 }
 
-static void subpart_fixup_write_buffer(struct buffer *buf)
-{
-	struct subpart *s = buffer_get(buf);
-	struct subpart_header *h = &s->h;
-	struct subpart_entry *e = &s->e[0];
-
-	size_t count = h->num_entries;
-	size_t offset = 0;
-
-	FIX_MEMBER(h->marker);
-	FIX_MEMBER(h->num_entries);
-	FIX_MEMBER(h->header_version);
-	FIX_MEMBER(h->entry_version);
-	FIX_MEMBER(h->header_length);
-	FIX_MEMBER(h->checksum);
-	offset += sizeof(h->name);
-
-	uint32_t i;
-	for (i = 0; i < count; i++) {
-		offset += sizeof(e[i].name);
-		FIX_MEMBER(e[i].offset);
-		FIX_MEMBER(e[i].length);
-		FIX_MEMBER(e[i].rsvd);
-	}
-}
-
 static enum ifwi_ret ifwi_cbp_replace(int type)
 {
 	if (buffer_size(&ifwi_image.comp_buf[type]) == 0) {



More information about the coreboot-gerrit mailing list