diff --git a/util/cbfstool/cbfs.h b/util/cbfstool/cbfs.h index d77504a2bb..641c6a141f 100644 --- a/util/cbfstool/cbfs.h +++ b/util/cbfstool/cbfs.h @@ -1,6 +1,7 @@ /* * Copyright (C) 2009 coresystems GmbH * written by Patrick Georgi + * Copyright (C) 2016 Siemens AG * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -108,6 +109,8 @@ struct cbfs_file_attribute { #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 */ struct cbfs_file_attr_compression { uint32_t tag; @@ -125,6 +128,18 @@ struct cbfs_file_attr_hash { 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; diff --git a/util/cbfstool/cbfstool.c b/util/cbfstool/cbfstool.c index 6d887d8eca..0ac1eecc5e 100644 --- a/util/cbfstool/cbfstool.c +++ b/util/cbfstool/cbfstool.c @@ -4,6 +4,7 @@ * Copyright (C) 2009 coresystems GmbH * written by Patrick Georgi * Copyright (C) 2012 Google, Inc. + * Copyright (C) 2016 Siemens AG * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -73,6 +74,7 @@ static struct param { bool fill_partial_downward; bool show_immutable; bool stage_xip; + bool autogen_attr; int fit_empty_entries; enum comp_algo compression; enum vb2_hash_algorithm hash; @@ -152,6 +154,13 @@ static int do_cbfs_locate(int32_t *cbfs_addr, size_t metadata_size) /* Include cbfs_file size along with space for with name. */ metadata_size += cbfs_calculate_file_header_size(param.name); + /* Adjust metadata_size if additional attributes were added */ + if (param.autogen_attr) { + if (param.alignment) + metadata_size += sizeof(struct cbfs_file_attr_align); + if (param.baseaddress_assigned || param.stage_xip) + metadata_size += sizeof(struct cbfs_file_attr_position); + } int32_t address = cbfs_locate_entry(&image, buffer.size, param.pagesize, param.alignment, metadata_size); @@ -352,6 +361,42 @@ static int cbfs_add_component(const char *filename, return 1; } + if (param.autogen_attr) { + /* Add position attribute if assigned */ + if (param.baseaddress_assigned || param.stage_xip) { + struct cbfs_file_attr_position *attrs = + (struct cbfs_file_attr_position *) + cbfs_add_file_attr(header, + CBFS_FILE_ATTR_TAG_POSITION, + sizeof(struct cbfs_file_attr_position)); + if (attrs == NULL) + return -1; + /* If we add a stage or a payload, we need to take */ + /* 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) + attrs->position = htonl(offset + + sizeof(struct cbfs_stage)); + else if (type == CBFS_COMPONENT_PAYLOAD) + attrs->position = htonl(offset + + sizeof(struct cbfs_payload)); + else + attrs->position = htonl(offset); + } + /* Add alignment attribute if used */ + if (param.alignment) { + struct cbfs_file_attr_align *attrs = + (struct cbfs_file_attr_align *) + cbfs_add_file_attr(header, + CBFS_FILE_ATTR_TAG_ALIGNMENT, + sizeof(struct cbfs_file_attr_align)); + if (attrs == NULL) + return -1; + attrs->alignment = htonl(param.alignment); + } + } + if (IS_TOP_ALIGNED_ADDRESS(offset)) offset = convert_to_from_top_aligned(param.image_region, -offset); @@ -1003,12 +1048,14 @@ static int cbfs_copy(void) } static const struct command commands[] = { - {"add", "H:r:f:n:t:c:b:a:vA:h?", cbfs_add, true, true}, - {"add-flat-binary", "H:r:f:n:l:e:c:b:vA:h?", cbfs_add_flat_binary, true, - true}, - {"add-payload", "H:r:f:n:t:c:b:C:I:vA:h?", cbfs_add_payload, true, true}, - {"add-stage", "a:H:r:f:n:t:c:b:P:S:yvA:h?", cbfs_add_stage, true, true}, - {"add-int", "H:r:i:n:b:vh?", cbfs_add_integer, true, true}, + {"add", "H:r:f:n:t:c:b:a:vA:gh?", cbfs_add, true, true}, + {"add-flat-binary", "H:r:f:n:l:e:c:b:vA:gh?", cbfs_add_flat_binary, + true, true}, + {"add-payload", "H:r:f:n:t:c:b:C:I:vA:gh?", cbfs_add_payload, + true, true}, + {"add-stage", "a:H:r:f:n:t:c:b:P:S:yvA:gh?", cbfs_add_stage, + true, true}, + {"add-int", "H:r:i:n:b:vgh?", cbfs_add_integer, true, true}, {"add-master-header", "H:r:vh?", cbfs_add_master_header, true, true}, {"copy", "r:R:h?", cbfs_copy, true, true}, {"create", "M:r:s:B:b:H:o:m:vh?", cbfs_create, true, true}, @@ -1053,6 +1100,7 @@ static struct option long_options[] = { {"verbose", no_argument, 0, 'v' }, {"with-readonly", no_argument, 0, 'w' }, {"xip", no_argument, 0, 'y' }, + {"gen-attribute", no_argument, 0, 'g' }, {NULL, 0, 0, 0 } }; @@ -1117,6 +1165,7 @@ static void usage(char *name) " -T Output top-aligned memory address\n" " -u Accept short data; fill upward/from bottom\n" " -d Accept short data; fill downward/from top\n" + " -g Generate potition and alignment arguments\n" " -v Provide verbose output\n" " -h Display this help message\n\n" "COMMANDs:\n" @@ -1351,6 +1400,9 @@ int main(int argc, char **argv) case 'y': param.stage_xip = true; break; + case 'g': + param.autogen_attr = true; + break; case 'h': case '?': usage(argv[0]);