diff options
Diffstat (limited to 'util/cbfstool')
-rw-r--r-- | util/cbfstool/Makefile.inc | 1 | ||||
-rw-r--r-- | util/cbfstool/cbfs-mkpayload.c | 8 | ||||
-rw-r--r-- | util/cbfstool/cbfs-mkstage.c | 4 | ||||
-rw-r--r-- | util/cbfstool/cbfs-payload-linux.c | 6 | ||||
-rw-r--r-- | util/cbfstool/cbfs.h | 252 | ||||
-rw-r--r-- | util/cbfstool/cbfs_image.c | 128 | ||||
-rw-r--r-- | util/cbfstool/cbfs_image.h | 2 | ||||
-rw-r--r-- | util/cbfstool/cbfscomptool.c | 1 | ||||
-rw-r--r-- | util/cbfstool/cbfstool.c | 32 | ||||
-rw-r--r-- | util/cbfstool/common.h | 36 | ||||
-rw-r--r-- | util/cbfstool/compress.c | 4 |
11 files changed, 129 insertions, 345 deletions
diff --git a/util/cbfstool/Makefile.inc b/util/cbfstool/Makefile.inc index ca1d79e8bb..536aef5094 100644 --- a/util/cbfstool/Makefile.inc +++ b/util/cbfstool/Makefile.inc @@ -101,6 +101,7 @@ TOOLCPPFLAGS += -I$(top)/src/commonlib/include -I$(top)/src/commonlib/bsd/includ TOOLCPPFLAGS += -include $(top)/src/commonlib/bsd/include/commonlib/bsd/compiler.h TOOLCPPFLAGS += -I$(VBOOT_SOURCE)/firmware/include TOOLCPPFLAGS += -I$(VBOOT_SOURCE)/firmware/2lib/include +TOOLCPPFLAGS += -I$(VBOOT_SOURCE)/host/include # UEFI header file support. It's not pretty, but that's what we currently # have right now. TOOLCPPFLAGS += -I$(top)/src diff --git a/util/cbfstool/cbfs-mkpayload.c b/util/cbfstool/cbfs-mkpayload.c index 86aa8e54a3..ae875f3634 100644 --- a/util/cbfstool/cbfs-mkpayload.c +++ b/util/cbfstool/cbfs-mkpayload.c @@ -51,7 +51,7 @@ void xdr_get_seg(struct cbfs_payload_segment *out, } int parse_elf_to_payload(const struct buffer *input, struct buffer *output, - enum comp_algo algo) + enum cbfs_compression algo) { Elf64_Phdr *phdr; Elf64_Ehdr ehdr; @@ -232,7 +232,7 @@ int parse_flat_binary_to_payload(const struct buffer *input, struct buffer *output, uint32_t loadaddress, uint32_t entrypoint, - enum comp_algo algo) + enum cbfs_compression algo) { comp_func_ptr compress; struct cbfs_payload_segment segs[2] = { {0} }; @@ -277,7 +277,7 @@ int parse_flat_binary_to_payload(const struct buffer *input, } int parse_fv_to_payload(const struct buffer *input, struct buffer *output, - enum comp_algo algo) + enum cbfs_compression algo) { comp_func_ptr compress; struct cbfs_payload_segment segs[2] = { {0} }; @@ -405,7 +405,7 @@ int parse_fv_to_payload(const struct buffer *input, struct buffer *output, } int parse_fit_to_payload(const struct buffer *input, struct buffer *output, - enum comp_algo algo) + enum cbfs_compression algo) { struct fdt_header *fdt_h; diff --git a/util/cbfstool/cbfs-mkstage.c b/util/cbfstool/cbfs-mkstage.c index bfdffbfeea..bfe7bf8c33 100644 --- a/util/cbfstool/cbfs-mkstage.c +++ b/util/cbfstool/cbfs-mkstage.c @@ -73,7 +73,7 @@ static Elf64_Shdr *find_ignored_section_header(struct parsed_elf *pelf, return NULL; } -static void fill_cbfs_stage(struct buffer *outheader, enum comp_algo algo, +static void fill_cbfs_stage(struct buffer *outheader, enum cbfs_compression algo, uint64_t entry, uint64_t loadaddr, uint32_t filesize, uint32_t memsize) { @@ -93,7 +93,7 @@ static void fill_cbfs_stage(struct buffer *outheader, enum comp_algo algo, * works for all elf files, not just the restricted set. */ int parse_elf_to_stage(const struct buffer *input, struct buffer *output, - enum comp_algo algo, uint32_t *location, + enum cbfs_compression algo, uint32_t *location, const char *ignore_section) { struct parsed_elf pelf; diff --git a/util/cbfstool/cbfs-payload-linux.c b/util/cbfstool/cbfs-payload-linux.c index 706f3a0253..9a29e68d9e 100644 --- a/util/cbfstool/cbfs-payload-linux.c +++ b/util/cbfstool/cbfs-payload-linux.c @@ -34,14 +34,14 @@ struct bzpayload { struct buffer cmdline; struct buffer initrd; /* Output variables. */ - enum comp_algo algo; + enum cbfs_compression algo; comp_func_ptr compress; struct buffer output; size_t offset; struct cbfs_payload_segment *out_seg; }; -static int bzp_init(struct bzpayload *bzp, enum comp_algo algo) +static int bzp_init(struct bzpayload *bzp, enum cbfs_compression algo) { memset(bzp, 0, sizeof(*bzp)); @@ -186,7 +186,7 @@ static void bzp_output_segment(struct bzpayload *bzp, struct buffer *b, */ int parse_bzImage_to_payload(const struct buffer *input, struct buffer *output, const char *initrd_name, - char *cmdline, enum comp_algo algo) + char *cmdline, enum cbfs_compression algo) { struct bzpayload bzp; unsigned int initrd_base = 64*1024*1024; diff --git a/util/cbfstool/cbfs.h b/util/cbfstool/cbfs.h index e58dfae009..9b4d7ae316 100644 --- a/util/cbfstool/cbfs.h +++ b/util/cbfstool/cbfs.h @@ -4,235 +4,59 @@ #define __CBFS_H #include "common.h" -#include <stdint.h> - -#include <vb2_api.h> - -/* cbfstool will fail when trying to build a cbfs_file header that's larger - * than MAX_CBFS_FILE_HEADER_BUFFER. 1K should give plenty of room. */ -#define MAX_CBFS_FILE_HEADER_BUFFER 1024 - -/* create a magic number in host-byte order. - * b3 is the high order byte. - * in the coreboot tools, we go with the 32-bit - * magic number convention. - * This was an inline func but that breaks anything - * that uses it in a case statement. - */ - -#define makemagic(b3, b2, b1, b0)\ - (((b3)<<24) | ((b2) << 16) | ((b1) << 8) | (b0)) +#include <commonlib/bsd/cbfs_serialized.h> /* To make CBFS more friendly to ROM, fill -1 (0xFF) instead of zero. */ #define CBFS_CONTENT_DEFAULT_VALUE (-1) -// Alignment (in bytes) to be used when no master header is present -#define CBFS_ENTRY_ALIGNMENT 64 - -#define CBFS_HEADER_MAGIC 0x4F524243 #define CBFS_HEADPTR_ADDR_X86 0xFFFFFFFC -#define CBFS_HEADER_VERSION1 0x31313131 -#define CBFS_HEADER_VERSION2 0x31313132 -#define CBFS_HEADER_VERSION CBFS_HEADER_VERSION2 - -#define CBFS_ALIGNMENT 64 - -struct cbfs_header { - uint32_t magic; - uint32_t version; - uint32_t romsize; - uint32_t bootblocksize; - uint32_t align; /* hard coded to 64 byte */ - uint32_t offset; - uint32_t architecture; /* Version 2 */ - uint32_t pad[1]; -} __packed; - -#define CBFS_ARCHITECTURE_UNKNOWN 0xFFFFFFFF -#define CBFS_ARCHITECTURE_X86 0x00000001 -#define CBFS_ARCHITECTURE_ARM 0x00000010 -#define CBFS_ARCHITECTURE_AARCH64 0x0000aa64 -#define CBFS_ARCHITECTURE_MIPS 0x00000100 /* deprecated */ -#define CBFS_ARCHITECTURE_RISCV 0xc001d0de -#define CBFS_ARCHITECTURE_PPC64 0x407570ff - -#define CBFS_FILE_MAGIC "LARCHIVE" - -struct cbfs_file { - uint8_t magic[8]; - /* length of file data */ - uint32_t len; - uint32_t type; - /* offset to struct cbfs_file_attribute or 0 */ - uint32_t attributes_offset; - /* length of header incl. variable data */ - uint32_t offset; - char filename[]; -} __packed; - -#if defined __GNUC__ && (__GNUC__ * 100 + __GNUC_MINOR__) >= 406 -_Static_assert(sizeof(struct cbfs_file) == 24, "cbfs_file size mismatch"); -#endif - -/* The common fields of extended cbfs file attributes. - Attributes are expected to start with tag/len, then append their - specific fields. */ -struct cbfs_file_attribute { - uint32_t tag; - /* len covers the whole structure, incl. tag and len */ - uint32_t len; - uint8_t data[0]; -} __packed; - -/* Depending on how the header was initialized, it may be backed with 0x00 or - * 0xff. Support both. */ -#define CBFS_FILE_ATTR_TAG_UNUSED 0 -#define CBFS_FILE_ATTR_TAG_UNUSED2 0xffffffff -#define CBFS_FILE_ATTR_TAG_COMPRESSION 0x42435a4c -#define CBFS_FILE_ATTR_TAG_HASH 0x68736148 -#define CBFS_FILE_ATTR_TAG_POSITION 0x42435350 /* PSCB */ -#define CBFS_FILE_ATTR_TAG_ALIGNMENT 0x42434c41 /* ALCB */ -#define CBFS_FILE_ATTR_TAG_PADDING 0x47444150 /* PDNG */ -#define CBFS_FILE_ATTR_TAG_IBB 0x32494242 /* Initial BootBlock */ - -struct cbfs_file_attr_compression { - uint32_t tag; - uint32_t len; - /* whole file compression format. 0 if no compression. */ - uint32_t compression; - uint32_t decompressed_size; -} __packed; - -struct cbfs_file_attr_hash { - uint32_t tag; - uint32_t len; - uint32_t hash_type; - /* hash_data is len - sizeof(struct) bytes */ - uint8_t hash_data[]; -} __packed; -struct cbfs_file_attr_position { - uint32_t tag; - uint32_t len; - uint32_t position; -} __packed; - -struct cbfs_file_attr_align { - uint32_t tag; - uint32_t len; - uint32_t alignment; -} __packed; - -struct cbfs_stage { - uint32_t compression; - uint64_t entry; - uint64_t load; - uint32_t len; - uint32_t memlen; -} __packed; - -#define PAYLOAD_SEGMENT_CODE makemagic('C', 'O', 'D', 'E') -#define PAYLOAD_SEGMENT_DATA makemagic('D', 'A', 'T', 'A') -#define PAYLOAD_SEGMENT_BSS makemagic('B', 'S', 'S', ' ') -#define PAYLOAD_SEGMENT_PARAMS makemagic('P', 'A', 'R', 'A') -#define PAYLOAD_SEGMENT_ENTRY makemagic('E', 'N', 'T', 'R') - -struct cbfs_payload_segment { +struct typedesc_t { uint32_t type; - uint32_t compression; - uint32_t offset; - uint64_t load_addr; - uint32_t len; - uint32_t mem_len; -} __packed; - -struct cbfs_payload { - struct cbfs_payload_segment segments; -} __packed; - -/** These are standard component types for well known - components (i.e - those that coreboot needs to consume. - Users are welcome to use any other value for their - components */ - -#define CBFS_COMPONENT_BOOTBLOCK 0x01 -#define CBFS_COMPONENT_CBFSHEADER 0x02 -#define CBFS_COMPONENT_STAGE 0x10 -#define CBFS_COMPONENT_SELF 0x20 -#define CBFS_COMPONENT_FIT 0x21 -#define CBFS_COMPONENT_OPTIONROM 0x30 -#define CBFS_COMPONENT_BOOTSPLASH 0x40 -#define CBFS_COMPONENT_RAW 0x50 -#define CBFS_COMPONENT_VSA 0x51 -#define CBFS_COMPONENT_MBI 0x52 -#define CBFS_COMPONENT_MICROCODE 0x53 -#define CBFS_COMPONENT_FSP 0x60 -#define CBFS_COMPONENT_MRC 0x61 -#define CBFS_COMPONENT_MMA 0x62 -#define CBFS_COMPONENT_EFI 0x63 -#define CBFS_COMPONENT_STRUCT 0x70 -#define CBFS_COMPONENT_CMOS_DEFAULT 0xaa -#define CBFS_COMPONENT_SPD 0xab -#define CBFS_COMPONENT_MRC_CACHE 0xac -#define CBFS_COMPONENT_CMOS_LAYOUT 0x01aa - -/* The deleted type is chosen to be a value - * that can be written in a FLASH from all other - * values. - */ -#define CBFS_COMPONENT_DELETED 0 - -/* for all known FLASH, this value can be changed - * to all other values. This allows NULL files to be - * changed without a block erase - */ -#define CBFS_COMPONENT_NULL 0xFFFFFFFF - -static struct typedesc_t filetypes[] unused = { - {CBFS_COMPONENT_BOOTBLOCK, "bootblock"}, - {CBFS_COMPONENT_CBFSHEADER, "cbfs header"}, - {CBFS_COMPONENT_STAGE, "stage"}, - {CBFS_COMPONENT_SELF, "simple elf"}, - {CBFS_COMPONENT_FIT, "fit"}, - {CBFS_COMPONENT_OPTIONROM, "optionrom"}, - {CBFS_COMPONENT_BOOTSPLASH, "bootsplash"}, - {CBFS_COMPONENT_RAW, "raw"}, - {CBFS_COMPONENT_VSA, "vsa"}, - {CBFS_COMPONENT_MBI, "mbi"}, - {CBFS_COMPONENT_MICROCODE, "microcode"}, - {CBFS_COMPONENT_FSP, "fsp"}, - {CBFS_COMPONENT_MRC, "mrc"}, - {CBFS_COMPONENT_CMOS_DEFAULT, "cmos_default"}, - {CBFS_COMPONENT_CMOS_LAYOUT, "cmos_layout"}, - {CBFS_COMPONENT_SPD, "spd"}, - {CBFS_COMPONENT_MRC_CACHE, "mrc_cache"}, - {CBFS_COMPONENT_MMA, "mma"}, - {CBFS_COMPONENT_EFI, "efi"}, - {CBFS_COMPONENT_STRUCT, "struct"}, - {CBFS_COMPONENT_DELETED, "deleted"}, - {CBFS_COMPONENT_NULL, "null"}, - {0, NULL} + const char *name; }; -static const struct typedesc_t types_cbfs_hash[] unused = { - {VB2_HASH_INVALID, "none"}, - {VB2_HASH_SHA1, "sha1"}, - {VB2_HASH_SHA256, "sha256"}, - {VB2_HASH_SHA512, "sha512"}, - {0, NULL} +static const struct typedesc_t types_cbfs_compression[] = { + {CBFS_COMPRESS_NONE, "none"}, + {CBFS_COMPRESS_LZMA, "LZMA"}, + {CBFS_COMPRESS_LZ4, "LZ4"}, + {0, NULL}, }; -static size_t widths_cbfs_hash[] unused = { - [VB2_HASH_INVALID] = 0, - [VB2_HASH_SHA1] = 20, - [VB2_HASH_SHA256] = 32, - [VB2_HASH_SHA512] = 64, +static struct typedesc_t filetypes[] unused = { + {CBFS_TYPE_BOOTBLOCK, "bootblock"}, + {CBFS_TYPE_CBFSHEADER, "cbfs header"}, + {CBFS_TYPE_STAGE, "stage"}, + {CBFS_TYPE_SELF, "simple elf"}, + {CBFS_TYPE_FIT, "fit"}, + {CBFS_TYPE_OPTIONROM, "optionrom"}, + {CBFS_TYPE_BOOTSPLASH, "bootsplash"}, + {CBFS_TYPE_RAW, "raw"}, + {CBFS_TYPE_VSA, "vsa"}, + {CBFS_TYPE_MBI, "mbi"}, + {CBFS_TYPE_MICROCODE, "microcode"}, + {CBFS_TYPE_FSP, "fsp"}, + {CBFS_TYPE_MRC, "mrc"}, + {CBFS_TYPE_CMOS_DEFAULT, "cmos_default"}, + {CBFS_TYPE_CMOS_LAYOUT, "cmos_layout"}, + {CBFS_TYPE_SPD, "spd"}, + {CBFS_TYPE_MRC_CACHE, "mrc_cache"}, + {CBFS_TYPE_MMA, "mma"}, + {CBFS_TYPE_EFI, "efi"}, + {CBFS_TYPE_STRUCT, "struct"}, + {CBFS_TYPE_DELETED, "deleted"}, + {CBFS_TYPE_NULL, "null"}, + {0, NULL} }; -#define CBFS_NUM_SUPPORTED_HASHES ARRAY_SIZE(widths_cbfs_hash) - #define CBFS_SUBHEADER(_p) ( (void *) ((((uint8_t *) (_p)) + ntohl((_p)->offset))) ) +static inline size_t cbfs_file_attr_hash_size(enum vb2_hash_algorithm algo) +{ + return offsetof(struct cbfs_file_attr_hash, hash.raw) + + vb2_digest_size(algo); +} + /* cbfs_image.c */ uint32_t get_cbfs_entry_type(const char *name, uint32_t default_value); uint32_t get_cbfs_compression(const char *name, uint32_t unknown); diff --git a/util/cbfstool/cbfs_image.c b/util/cbfstool/cbfs_image.c index a042f0dac8..793713f336 100644 --- a/util/cbfstool/cbfs_image.c +++ b/util/cbfstool/cbfs_image.c @@ -65,16 +65,6 @@ int cbfs_parse_comp_algo(const char *name) return lookup_type_by_name(types_cbfs_compression, name); } -static const char *get_hash_attr_name(uint16_t hash_type) -{ - return lookup_name_by_type(types_cbfs_hash, hash_type, "(invalid)"); -} - -int cbfs_parse_hash_algo(const char *name) -{ - return lookup_type_by_name(types_cbfs_hash, name); -} - /* CBFS image */ size_t cbfs_calculate_file_header_size(const char *name) @@ -212,7 +202,7 @@ int cbfs_image_create(struct cbfs_image *image, size_t entries_size) size_t empty_header_len = cbfs_calculate_file_header_size(""); uint32_t entries_offset = 0; - uint32_t align = CBFS_ENTRY_ALIGNMENT; + uint32_t align = CBFS_ALIGNMENT; if (image->has_header) { entries_offset = image->header.offset; @@ -251,7 +241,7 @@ int cbfs_image_create(struct cbfs_image *image, size_t entries_size) size_t capacity = entries_size - empty_header_len; LOG("Created CBFS (capacity = %zu bytes)\n", capacity); - return cbfs_create_empty_entry(entry_header, CBFS_COMPONENT_NULL, + return cbfs_create_empty_entry(entry_header, CBFS_TYPE_NULL, capacity, ""); } @@ -387,7 +377,7 @@ int cbfs_copy_instance(struct cbfs_image *image, struct buffer *dst) size_t copy_end = buffer_size(dst); - align = CBFS_ENTRY_ALIGNMENT; + align = CBFS_ALIGNMENT; dst_entry = (struct cbfs_file *)buffer_get(dst); @@ -397,9 +387,9 @@ int cbfs_copy_instance(struct cbfs_image *image, struct buffer *dst) src_entry = cbfs_find_next_entry(image, src_entry)) { size_t entry_size; - if ((src_entry->type == htonl(CBFS_COMPONENT_NULL)) || - (src_entry->type == htonl(CBFS_COMPONENT_CBFSHEADER)) || - (src_entry->type == htonl(CBFS_COMPONENT_DELETED))) + if ((src_entry->type == htonl(CBFS_TYPE_NULL)) || + (src_entry->type == htonl(CBFS_TYPE_CBFSHEADER)) || + (src_entry->type == htonl(CBFS_TYPE_DELETED))) continue; entry_size = htonl(src_entry->len) + htonl(src_entry->offset); @@ -425,7 +415,7 @@ int cbfs_copy_instance(struct cbfs_image *image, struct buffer *dst) if (last_entry_size < 0) WARN("No room to create the last entry!\n") else - cbfs_create_empty_entry(dst_entry, CBFS_COMPONENT_NULL, + cbfs_create_empty_entry(dst_entry, CBFS_TYPE_NULL, last_entry_size, ""); return 0; @@ -461,7 +451,7 @@ int cbfs_expand_to_region(struct buffer *region) cbfs_calculate_file_header_size("") - sizeof(int32_t); if (last_entry_size > 0) { - cbfs_create_empty_entry(entry, CBFS_COMPONENT_NULL, + cbfs_create_empty_entry(entry, CBFS_TYPE_NULL, last_entry_size, ""); /* If the last entry was an empty file, merge them. */ cbfs_walk(&image, cbfs_merge_empty_entry, NULL); @@ -495,8 +485,8 @@ int cbfs_truncate_space(struct buffer *region, uint32_t *size) * maximum size. */ if ((strlen(trailer->filename) != 0) && - (trailer->type != htonl(CBFS_COMPONENT_NULL)) && - (trailer->type != htonl(CBFS_COMPONENT_DELETED))) { + (trailer->type != htonl(CBFS_TYPE_NULL)) && + (trailer->type != htonl(CBFS_TYPE_DELETED))) { /* nothing to truncate. Return de-facto CBFS size in case it * was already truncated. */ *size = (uint8_t *)entry - (uint8_t *)buffer_get(region); @@ -550,8 +540,8 @@ int cbfs_compact_instance(struct cbfs_image *image) uint32_t type = htonl(cur->type); /* Current entry is empty. Kepp track of it. */ - if ((type == htonl(CBFS_COMPONENT_NULL)) || - (type == htonl(CBFS_COMPONENT_DELETED))) { + if ((type == htonl(CBFS_TYPE_NULL)) || + (type == htonl(CBFS_TYPE_DELETED))) { prev = cur; continue; } @@ -612,7 +602,7 @@ int cbfs_compact_instance(struct cbfs_image *image) prev_size -= spill_size + empty_metadata_size; /* Create new empty file. */ - cbfs_create_empty_entry(cur, CBFS_COMPONENT_NULL, + cbfs_create_empty_entry(cur, CBFS_TYPE_NULL, prev_size, ""); /* Merge any potential empty entries together. */ @@ -652,7 +642,7 @@ static int cbfs_add_entry_at(struct cbfs_image *image, uint32_t min_entry_size = cbfs_calculate_file_header_size(""); uint32_t len, header_offset; uint32_t align = image->has_header ? image->header.align : - CBFS_ENTRY_ALIGNMENT; + CBFS_ALIGNMENT; uint32_t header_size = ntohl(header->offset); header_offset = content_offset - header_size; @@ -667,7 +657,7 @@ static int cbfs_add_entry_at(struct cbfs_image *image, if (header_offset - addr > min_entry_size) { DEBUG("|min|...|header|content|... <create new entry>\n"); len = header_offset - addr - min_entry_size; - cbfs_create_empty_entry(entry, CBFS_COMPONENT_NULL, len, ""); + cbfs_create_empty_entry(entry, CBFS_TYPE_NULL, len, ""); if (verbose > 1) cbfs_print_entry_info(image, entry, stderr); entry = cbfs_find_next_entry(image, entry); addr = cbfs_get_entry_addr(image, entry); @@ -726,7 +716,7 @@ static int cbfs_add_entry_at(struct cbfs_image *image, buffer_size(&image->buffer) - sizeof(int32_t)) { len -= sizeof(int32_t); } - cbfs_create_empty_entry(entry, CBFS_COMPONENT_NULL, len, ""); + cbfs_create_empty_entry(entry, CBFS_TYPE_NULL, len, ""); if (verbose > 1) cbfs_print_entry_info(image, entry, stderr); return 0; } @@ -762,7 +752,7 @@ int cbfs_add_entry(struct cbfs_image *image, struct buffer *buffer, entry = cbfs_find_next_entry(image, entry)) { entry_type = ntohl(entry->type); - if (entry_type != CBFS_COMPONENT_NULL) + if (entry_type != CBFS_TYPE_NULL) continue; addr = cbfs_get_entry_addr(image, entry); @@ -1337,10 +1327,10 @@ int cbfs_export_entry(struct cbfs_image *image, const char *entry_name, if (do_processing) { int (*make_elf)(struct buffer *, uint32_t) = NULL; switch (ntohl(entry->type)) { - case CBFS_COMPONENT_STAGE: + case CBFS_TYPE_STAGE: make_elf = cbfs_stage_make_elf; break; - case CBFS_COMPONENT_SELF: + case CBFS_TYPE_SELF: make_elf = cbfs_payload_make_elf; break; } @@ -1374,7 +1364,7 @@ int cbfs_remove_entry(struct cbfs_image *image, const char *name) } DEBUG("cbfs_remove_entry: Removed %s @ 0x%x\n", entry->filename, cbfs_get_entry_addr(image, entry)); - entry->type = htonl(CBFS_COMPONENT_DELETED); + entry->type = htonl(CBFS_TYPE_DELETED); cbfs_walk(image, cbfs_merge_empty_entry, NULL); return 0; } @@ -1498,28 +1488,21 @@ int cbfs_print_entry_info(struct cbfs_image *image, struct cbfs_file *entry, decompressed_size ); - struct cbfs_file_attr_hash *hash = NULL; - while ((hash = cbfs_file_get_next_hash(entry, hash)) != NULL) { - unsigned int hash_type = ntohl(hash->hash_type); - if (hash_type >= CBFS_NUM_SUPPORTED_HASHES) { - fprintf(fp, "invalid hash type %d\n", hash_type); + struct cbfs_file_attr_hash *attr = NULL; + while ((attr = cbfs_file_get_next_hash(entry, attr)) != NULL) { + size_t hash_len = vb2_digest_size(attr->hash.algo); + if (!hash_len) { + fprintf(fp, "invalid/unsupported hash algorithm: %d\n", + attr->hash.algo); break; } - size_t hash_len = widths_cbfs_hash[hash_type]; - char *hash_str = bintohex(hash->hash_data, hash_len); - uint8_t local_hash[hash_len]; - if (vb2_digest_buffer(CBFS_SUBHEADER(entry), - ntohl(entry->len), hash_type, local_hash, - hash_len) != VB2_SUCCESS) { - fprintf(fp, "failed to hash '%s'\n", name); - free(hash_str); - break; - } - int valid = memcmp(local_hash, hash->hash_data, hash_len) == 0; + char *hash_str = bintohex(attr->hash.raw, hash_len); + int valid = vb2_hash_verify(CBFS_SUBHEADER(entry), + ntohl(entry->len), &attr->hash) == VB2_SUCCESS; const char *valid_str = valid ? "valid" : "invalid"; fprintf(fp, " hash %s:%s %s\n", - get_hash_attr_name(hash_type), + vb2_get_hash_algorithm_name(attr->hash.algo), hash_str, valid_str); free(hash_str); } @@ -1534,12 +1517,12 @@ int cbfs_print_entry_info(struct cbfs_image *image, struct cbfs_file *entry, /* note the components of the subheader may be in host order ... */ switch (ntohl(entry->type)) { - case CBFS_COMPONENT_STAGE: + case CBFS_TYPE_STAGE: cbfs_print_stage_info((struct cbfs_stage *) CBFS_SUBHEADER(entry), fp); break; - case CBFS_COMPONENT_SELF: + case CBFS_TYPE_SELF: payload = (struct cbfs_payload_segment *) CBFS_SUBHEADER(entry); while (payload) { @@ -1635,8 +1618,8 @@ int cbfs_merge_empty_entry(struct cbfs_image *image, struct cbfs_file *entry, /* Loop until non-empty entry is found, starting from the current entry. After the loop, next_addr points to the next non-empty entry. */ next = entry; - while (ntohl(next->type) == CBFS_COMPONENT_DELETED || - ntohl(next->type) == CBFS_COMPONENT_NULL) { + while (ntohl(next->type) == CBFS_TYPE_DELETED || + ntohl(next->type) == CBFS_TYPE_NULL) { next = cbfs_find_next_entry(image, next); if (!next) break; @@ -1657,7 +1640,7 @@ int cbfs_merge_empty_entry(struct cbfs_image *image, struct cbfs_file *entry, uint32_t addr = cbfs_get_entry_addr(image, entry); size_t len = next_addr - addr - cbfs_calculate_file_header_size(""); DEBUG("join_empty_entry: [0x%x, 0x%x) len=%zu\n", addr, next_addr, len); - cbfs_create_empty_entry(entry, CBFS_COMPONENT_NULL, len, ""); + cbfs_create_empty_entry(entry, CBFS_TYPE_NULL, len, ""); return 0; } @@ -1751,8 +1734,7 @@ 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 = image->has_header ? image->header.align : - CBFS_ENTRY_ALIGNMENT; + int align = image->has_header ? image->header.align : CBFS_ALIGNMENT; assert(entry && cbfs_is_valid_entry(image, entry)); addr += ntohl(entry->offset) + ntohl(entry->len); addr = align_up(addr, align); @@ -1793,8 +1775,8 @@ int cbfs_is_valid_entry(struct cbfs_image *image, struct cbfs_file *entry) struct cbfs_file *cbfs_create_file_header(int type, size_t len, const char *name) { - struct cbfs_file *entry = malloc(MAX_CBFS_FILE_HEADER_BUFFER); - memset(entry, CBFS_CONTENT_DEFAULT_VALUE, MAX_CBFS_FILE_HEADER_BUFFER); + struct cbfs_file *entry = malloc(CBFS_METADATA_MAX_SIZE); + memset(entry, CBFS_CONTENT_DEFAULT_VALUE, CBFS_METADATA_MAX_SIZE); memcpy(entry->magic, CBFS_FILE_MAGIC, sizeof(entry->magic)); entry->type = htonl(type); entry->len = htonl(len); @@ -1867,7 +1849,7 @@ struct cbfs_file_attribute *cbfs_add_file_attr(struct cbfs_file *header, next = cbfs_file_next_attr(header, attr); } while (next != NULL); uint32_t header_size = ntohl(header->offset) + size; - if (header_size > MAX_CBFS_FILE_HEADER_BUFFER) { + if (header_size > CBFS_METADATA_MAX_SIZE) { DEBUG("exceeding allocated space for cbfs_file headers"); return NULL; } @@ -1889,35 +1871,31 @@ struct cbfs_file_attribute *cbfs_add_file_attr(struct cbfs_file *header, ntohl(attr->len)); } header->offset = htonl(header_size); - memset(attr, CBFS_CONTENT_DEFAULT_VALUE, size); + /* Attributes are expected to be small (much smaller than a flash page) + and not really meant to be overwritten in-place. To avoid surprising + values in reserved fields of attribute structures, initialize them to + 0, not 0xff. */ + memset(attr, 0, size); attr->tag = htonl(tag); attr->len = htonl(size); return attr; } int cbfs_add_file_hash(struct cbfs_file *header, struct buffer *buffer, - enum vb2_hash_algorithm hash_type) + enum vb2_hash_algorithm alg) { - uint32_t hash_index = hash_type; - - if (hash_index >= CBFS_NUM_SUPPORTED_HASHES) + if (!vb2_digest_size(alg)) return -1; - unsigned hash_size = widths_cbfs_hash[hash_type]; - if (hash_size == 0) - return -1; - - struct cbfs_file_attr_hash *attrs = + struct cbfs_file_attr_hash *attr = (struct cbfs_file_attr_hash *)cbfs_add_file_attr(header, - CBFS_FILE_ATTR_TAG_HASH, - sizeof(struct cbfs_file_attr_hash) + hash_size); + CBFS_FILE_ATTR_TAG_HASH, cbfs_file_attr_hash_size(alg)); - if (attrs == NULL) + if (attr == NULL) return -1; - attrs->hash_type = htonl(hash_type); - if (vb2_digest_buffer(buffer_get(buffer), buffer_size(buffer), - hash_type, attrs->hash_data, hash_size) != VB2_SUCCESS) + if (vb2_hash_calculate(buffer_get(buffer), buffer_size(buffer), + alg, &attr->hash) != VB2_SUCCESS) return -1; return 0; @@ -1969,7 +1947,7 @@ int32_t cbfs_locate_entry(struct cbfs_image *image, size_t size, size, page_size); size_t image_align = image->has_header ? image->header.align : - CBFS_ENTRY_ALIGNMENT; + CBFS_ALIGNMENT; if (page_size % image_align) WARN("%s: Page size (%#zx) not aligned with CBFS image (%#zx).\n", __func__, page_size, image_align); @@ -2005,7 +1983,7 @@ int32_t cbfs_locate_entry(struct cbfs_image *image, size_t size, entry = cbfs_find_next_entry(image, entry)) { uint32_t type = ntohl(entry->type); - if (type != CBFS_COMPONENT_NULL) + if (type != CBFS_TYPE_NULL) continue; addr = cbfs_get_entry_addr(image, entry); diff --git a/util/cbfstool/cbfs_image.h b/util/cbfstool/cbfs_image.h index c57a153d99..cd44438db2 100644 --- a/util/cbfstool/cbfs_image.h +++ b/util/cbfstool/cbfs_image.h @@ -42,7 +42,7 @@ int cbfs_image_create(struct cbfs_image *image, size_t entries_size); /* Creates an empty CBFS image by given size, and description to its content * (bootblock, align, header location, starting offset of CBFS entries). * The output image will contain a valid cbfs_header, with one cbfs_file - * entry with type CBFS_COMPONENT_NULL, with max available size. + * entry with type CBFS_TYPE_NULL, with max available size. * Only call this if you want a legacy CBFS with a master header. * Returns 0 on success, otherwise nonzero. */ int cbfs_legacy_image_create(struct cbfs_image *image, diff --git a/util/cbfstool/cbfscomptool.c b/util/cbfstool/cbfscomptool.c index 3ea87ad449..5745093165 100644 --- a/util/cbfstool/cbfscomptool.c +++ b/util/cbfstool/cbfscomptool.c @@ -7,6 +7,7 @@ #include <strings.h> #include <time.h> +#include "cbfs.h" #include "common.h" const char *usage_text = "cbfs-compression-tool benchmark\n" diff --git a/util/cbfstool/cbfstool.c b/util/cbfstool/cbfstool.c index c7a6079333..2fd8eaa6db 100644 --- a/util/cbfstool/cbfstool.c +++ b/util/cbfstool/cbfstool.c @@ -17,6 +17,7 @@ #include <commonlib/fsp.h> #include <commonlib/endian.h> #include <commonlib/helpers.h> +#include <vboot_host.h> #define SECTION_WITH_FIT_TABLE "BOOTBLOCK" @@ -70,7 +71,7 @@ static struct param { bool machine_parseable; bool unprocessed; bool ibb; - enum comp_algo compression; + enum cbfs_compression compression; int precompression; enum vb2_hash_algorithm hash; /* For linux payloads */ @@ -194,7 +195,7 @@ static int do_cbfs_locate(int32_t *cbfs_addr, size_t metadata_size, /* Take care of the hash attribute if it is used */ if (param.hash != VB2_HASH_INVALID) - metadata_size += sizeof(struct cbfs_file_attr_hash); + metadata_size += cbfs_file_attr_hash_size(param.hash); int32_t address = cbfs_locate_entry(&image, data_size, param.pagesize, param.alignment, metadata_size); @@ -246,7 +247,7 @@ static int cbfs_add_integer_component(const char *name, offset = convert_to_from_top_aligned(param.image_region, -offset); - header = cbfs_create_file_header(CBFS_COMPONENT_RAW, + header = cbfs_create_file_header(CBFS_TYPE_RAW, buffer.size, name); if (cbfs_add_entry(&image, &buffer, offset, header, 0) != 0) { ERROR("Failed to add %llu into ROM image as '%s'.\n", @@ -347,7 +348,7 @@ static int cbfs_add_master_header(void) * image is at 4GB == 0. */ h->bootblocksize = htonl(4); - h->align = htonl(CBFS_ENTRY_ALIGNMENT); + h->align = htonl(CBFS_ALIGNMENT); /* The offset and romsize fields within the master header are absolute * values within the boot media. As such, romsize needs to relfect * the end 'offset' for a CBFS. To achieve that the current buffer @@ -361,7 +362,7 @@ static int cbfs_add_master_header(void) h->offset = htonl(offset); h->architecture = htonl(CBFS_ARCHITECTURE_UNKNOWN); - header = cbfs_create_file_header(CBFS_COMPONENT_CBFSHEADER, + header = cbfs_create_file_header(CBFS_TYPE_CBFSHEADER, buffer_size(&buffer), name); if (cbfs_add_entry(&image, &buffer, 0, header, 0) != 0) { ERROR("Failed to add cbfs master header into ROM image.\n"); @@ -483,7 +484,7 @@ static int cbfs_add_component(const char *filename, * Check if Intel CPU topswap is specified this will require a * second bootblock to be added. */ - if (type == CBFS_COMPONENT_BOOTBLOCK && param.topswap_size) + if (type == CBFS_TYPE_BOOTBLOCK && param.topswap_size) if (add_topswap_bootblock(&buffer, &offset)) return 1; @@ -518,10 +519,10 @@ static int cbfs_add_component(const char *filename, /* care about the additional metadata that is added */ /* to the cbfs file and therefore set the position */ /* the real beginning of the data. */ - if (type == CBFS_COMPONENT_STAGE) + if (type == CBFS_TYPE_STAGE) attrs->position = htonl(offset + sizeof(struct cbfs_stage)); - else if (type == CBFS_COMPONENT_SELF) + else if (type == CBFS_TYPE_SELF) attrs->position = htonl(offset + sizeof(struct cbfs_payload)); else @@ -756,7 +757,7 @@ static int cbfstool_convert_mkpayload(struct buffer *buffer, if (ret != 0) { ret = parse_fit_to_payload(buffer, &output, param.compression); if (ret == 0) - header->type = htonl(CBFS_COMPONENT_FIT); + header->type = htonl(CBFS_TYPE_FIT); } /* If it's not an FIT, see if it's a UEFI FV */ @@ -814,7 +815,7 @@ static int cbfs_add(void) /* Set the alignment to 4KiB minimum for FSP blobs when no base address * is provided so that relocation can occur. */ - if (param.type == CBFS_COMPONENT_FSP) { + if (param.type == CBFS_TYPE_FSP) { if (!param.baseaddress_assigned) param.alignment = 4*1024; convert = cbfstool_convert_fsp; @@ -855,7 +856,7 @@ static int cbfs_add_stage(void) return cbfs_add_component(param.filename, param.name, - CBFS_COMPONENT_STAGE, + CBFS_TYPE_STAGE, param.baseaddress, param.headeroffset, cbfstool_convert_mkstage); @@ -865,7 +866,7 @@ static int cbfs_add_payload(void) { return cbfs_add_component(param.filename, param.name, - CBFS_COMPONENT_SELF, + CBFS_TYPE_SELF, param.baseaddress, param.headeroffset, cbfstool_convert_mkpayload); @@ -885,7 +886,7 @@ static int cbfs_add_flat_binary(void) } return cbfs_add_component(param.filename, param.name, - CBFS_COMPONENT_SELF, + CBFS_TYPE_SELF, param.baseaddress, param.headeroffset, cbfstool_convert_mkflatpayload); @@ -1576,10 +1577,7 @@ int main(int argc, char **argv) break; } case 'A': { - int algo = cbfs_parse_hash_algo(optarg); - if (algo >= 0) - param.hash = algo; - else { + if (!vb2_lookup_hash_alg(optarg, ¶m.hash)) { ERROR("Unknown hash algorithm '%s'.\n", optarg); return 1; diff --git a/util/cbfstool/common.h b/util/cbfstool/common.h index 7dbc1f575d..f1287e299f 100644 --- a/util/cbfstool/common.h +++ b/util/cbfstool/common.h @@ -9,10 +9,10 @@ #include <string.h> #include <assert.h> +#include <commonlib/bsd/cbfs_serialized.h> #include <commonlib/helpers.h> #include <console/console.h> -/* Endianness */ #include "swab.h" #define IS_TOP_ALIGNED_ADDRESS(x) ((uint32_t)(x) > 0x80000000) @@ -147,47 +147,29 @@ typedef int (*comp_func_ptr) (char *in, int in_len, char *out, int *out_len); typedef int (*decomp_func_ptr) (char *in, int in_len, char *out, int out_len, size_t *actual_size); -enum comp_algo { - CBFS_COMPRESS_NONE = 0, - CBFS_COMPRESS_LZMA = 1, - CBFS_COMPRESS_LZ4 = 2, -}; - -struct typedesc_t { - uint32_t type; - const char *name; -}; - -static const struct typedesc_t types_cbfs_compression[] = { - {CBFS_COMPRESS_NONE, "none"}, - {CBFS_COMPRESS_LZMA, "LZMA"}, - {CBFS_COMPRESS_LZ4, "LZ4"}, - {0, NULL}, -}; - -comp_func_ptr compression_function(enum comp_algo algo); -decomp_func_ptr decompression_function(enum comp_algo algo); +comp_func_ptr compression_function(enum cbfs_compression algo); +decomp_func_ptr decompression_function(enum cbfs_compression algo); uint64_t intfiletype(const char *name); /* cbfs-mkpayload.c */ int parse_elf_to_payload(const struct buffer *input, struct buffer *output, - enum comp_algo algo); + enum cbfs_compression algo); int parse_fv_to_payload(const struct buffer *input, struct buffer *output, - enum comp_algo algo); + enum cbfs_compression algo); int parse_fit_to_payload(const struct buffer *input, struct buffer *output, - enum comp_algo algo); + enum cbfs_compression algo); int parse_bzImage_to_payload(const struct buffer *input, struct buffer *output, const char *initrd, - char *cmdline, enum comp_algo algo); + char *cmdline, enum cbfs_compression algo); int parse_flat_binary_to_payload(const struct buffer *input, struct buffer *output, uint32_t loadaddress, uint32_t entrypoint, - enum comp_algo algo); + enum cbfs_compression algo); /* cbfs-mkstage.c */ int parse_elf_to_stage(const struct buffer *input, struct buffer *output, - enum comp_algo algo, uint32_t *location, + enum cbfs_compression algo, uint32_t *location, const char *ignore_section); /* location is TOP aligned. */ int parse_elf_to_xip_stage(const struct buffer *input, struct buffer *output, diff --git a/util/cbfstool/compress.c b/util/cbfstool/compress.c index f926db510c..37fac224cc 100644 --- a/util/cbfstool/compress.c +++ b/util/cbfstool/compress.c @@ -66,7 +66,7 @@ static int none_decompress(char *in, int in_len, char *out, unused int out_len, return 0; } -comp_func_ptr compression_function(enum comp_algo algo) +comp_func_ptr compression_function(enum cbfs_compression algo) { comp_func_ptr compress; switch (algo) { @@ -86,7 +86,7 @@ comp_func_ptr compression_function(enum comp_algo algo) return compress; } -decomp_func_ptr decompression_function(enum comp_algo algo) +decomp_func_ptr decompression_function(enum cbfs_compression algo) { decomp_func_ptr decompress; switch (algo) { |