util/cbfstool: add machine parseable print

In order to more easily process the output of 'cbfstool print'
with other tools provide a -k option which spits out the
tab-separated header and fields:

Name Offset Type Metadata Size Data Size Total Size

ALIGN_UP(Offset + Total Size, 64) would be the start
of the next entry. Also, one can analzye the overhead
and offsets of each file more easily.

Example output (note: tabs aren't in here):

$ ./coreboot-builds/sharedutils/cbfstool/cbfstool test.serial.bin print
-r FW_MAIN_A  -k
Performing operation on 'FW_MAIN_A' region...
Name	Offset	Type	Metadata Size	Data Size	Total Size
cmos_layout.bin	0x0	cmos_layout	0x38	0x48c	0x4c4
dmic-2ch-48khz-16b.bin	0x500	raw	0x48	0xb68	0xbb0
dmic-2ch-48khz-32b.bin	0x10c0	raw	0x48	0xb68	0xbb0
nau88l25-2ch-48khz-24b.bin	0x1c80	raw	0x48	0x54	0x9c
ssm4567-render-2ch-48khz-24b.bin	0x1d40	raw	0x58	0x54	0xac
ssm4567-capture-4ch-48khz-32b.bin	0x1e00	raw	0x58	0x54	0xac
vbt.bin	0x1ec0	optionrom	0x38	0x1000	0x1038
spd.bin	0x2f00	spd	0x38	0x600	0x638
config	0x3540	raw	0x38	0x1ab7	0x1aef
revision	0x5040	raw	0x38	0x25e	0x296
font.bin	0x5300	raw	0x38	0x77f	0x7b7
vbgfx.bin	0x5ac0	raw	0x38	0x32f8	0x3330
locales	0x8e00	raw	0x28	0x2	0x2a
locale_en.bin	0x8e40	raw	0x38	0x29f6	0x2a2e
u-boot.dtb	0xb880	mrc_cache	0x38	0xff1	0x1029
(empty)	0xc8c0	null	0x64	0xadf4	0xae58
fallback/ramstage	0x17740	stage	0x38	0x15238	0x15270
(empty)	0x2c9c0	null	0x64	0xd2c4	0xd328
fallback/payload	0x39d00	payload	0x38	0x12245	0x1227d
cpu_microcode_blob.bin	0x4bf80	microcode	0x60	0x17000	0x17060
(empty)	0x63000	null	0x28	0x37cf98	0x37cfc0

Change-Id: I1c5f8c1b5f2f980033d6c954c9840299c6268431
Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: https://review.coreboot.org/13475
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
This commit is contained in:
Aaron Durbin 2016-01-26 15:35:34 -06:00
parent 63eb917275
commit 5dc628a2ef
3 changed files with 66 additions and 3 deletions

View File

@ -1076,6 +1076,41 @@ int cbfs_print_entry_info(struct cbfs_image *image, struct cbfs_file *entry,
return 0;
}
static int cbfs_print_parseable_entry_info(struct cbfs_image *image,
struct cbfs_file *entry, void *arg)
{
FILE *fp = (FILE *)arg;
const char *name;
const char *type;
size_t offset;
size_t metadata_size;
size_t data_size;
const char *sep = "\t";
if (!cbfs_is_valid_entry(image, entry)) {
ERROR("cbfs_print_entry_info: Invalid entry at 0x%x\n",
cbfs_get_entry_addr(image, entry));
return -1;
}
name = entry->filename;
if (*name == '\0')
name = "(empty)";
type = get_cbfs_entry_type_name(ntohl(entry->type)),
metadata_size = ntohl(entry->offset);
data_size = ntohl(entry->len);
offset = cbfs_get_entry_addr(image, entry);
fprintf(fp, "%s%s", name, sep);
fprintf(fp, "0x%zx%s", offset, sep);
fprintf(fp, "%s%s", type, sep);
fprintf(fp, "0x%zx%s", metadata_size, sep);
fprintf(fp, "0x%zx%s", data_size, sep);
fprintf(fp, "0x%zx\n", metadata_size + data_size);
return 0;
}
int cbfs_print_directory(struct cbfs_image *image)
{
if (cbfs_is_legacy_cbfs(image))
@ -1085,6 +1120,26 @@ int cbfs_print_directory(struct cbfs_image *image)
return 0;
}
int cbfs_print_parseable_directory(struct cbfs_image *image)
{
int i;
const char *header[] = {
"Name",
"Offset",
"Type",
"Metadata Size",
"Data Size",
"Total Size",
};
const char *sep = "\t";
for (i = 0; i < ARRAY_SIZE(header) - 1; i++)
fprintf(stdout, "%s%s", header[i], sep);
fprintf(stdout, "%s\n", header[i]);
cbfs_walk(image, cbfs_print_parseable_entry_info, stdout);
return 0;
}
int cbfs_merge_empty_entry(struct cbfs_image *image, struct cbfs_file *entry,
unused void *arg)
{

View File

@ -158,6 +158,7 @@ int cbfs_is_valid_entry(struct cbfs_image *image, struct cbfs_file *entry);
/* Print CBFS component information. */
int cbfs_print_directory(struct cbfs_image *image);
int cbfs_print_parseable_directory(struct cbfs_image *image);
int cbfs_print_header_info(struct cbfs_image *image);
int cbfs_print_entry_info(struct cbfs_image *image, struct cbfs_file *entry,
void *arg);

View File

@ -75,6 +75,7 @@ static struct param {
bool show_immutable;
bool stage_xip;
bool autogen_attr;
bool machine_parseable;
int fit_empty_entries;
enum comp_algo compression;
enum vb2_hash_algorithm hash;
@ -838,8 +839,10 @@ static int cbfs_print(void)
if (cbfs_image_from_buffer(&image, param.image_region,
param.headeroffset))
return 1;
cbfs_print_directory(&image);
return 0;
if (param.machine_parseable)
return cbfs_print_parseable_directory(&image);
else
return cbfs_print_directory(&image);
}
/* Forward declared so there aren't type collisions with cbfstool proper
@ -1066,7 +1069,7 @@ static const struct command commands[] = {
{"hashcbfs", "r:R:A:vh?", cbfs_hash, true, true},
{"extract", "H:r:m:n:f:vh?", cbfs_extract, true, false},
{"layout", "wvh?", cbfs_layout, false, false},
{"print", "H:r:vh?", cbfs_print, true, false},
{"print", "H:r:vkh?", cbfs_print, true, false},
{"read", "r:f:vh?", cbfs_read, true, false},
{"remove", "H:r:n:vh?", cbfs_remove, true, true},
{"update-fit", "H:r:n:x:vh?", cbfs_update_fit, true, true},
@ -1105,6 +1108,7 @@ static struct option long_options[] = {
{"with-readonly", no_argument, 0, 'w' },
{"xip", no_argument, 0, 'y' },
{"gen-attribute", no_argument, 0, 'g' },
{"mach-parseable",no_argument, 0, 'k' },
{NULL, 0, 0, 0 }
};
@ -1407,6 +1411,9 @@ int main(int argc, char **argv)
case 'g':
param.autogen_attr = true;
break;
case 'k':
param.machine_parseable = true;
break;
case 'h':
case '?':
usage(argv[0]);