[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