Author: oxygene Date: Thu Jan 13 10:09:21 2011 New Revision: 6250 URL: https://tracker.coreboot.org/trac/coreboot/changeset/6250
Log: Add "cbfstool extract" function.
It dumps everything you ask for, but you might not get what you expect if the file is compressed or otherwise converted (eg. payloads in SELF format). (Originally it would only extract "raw" files. This is a change by me, as filetypes are commonly used to differentiate raw data files --Patrick)
Signed-off-by: Aurelien Guillaume aurelien@iwi.me Signed-off-by: Patrick Georgi patrick.georgi@secunet.com Acked-by: Patrick Georgi patrick.georgi@secunet.com
Modified: trunk/util/cbfstool/cbfstool.c trunk/util/cbfstool/common.c trunk/util/cbfstool/common.h
Modified: trunk/util/cbfstool/cbfstool.c ============================================================================== --- trunk/util/cbfstool/cbfstool.c Wed Jan 12 22:09:25 2011 (r6249) +++ trunk/util/cbfstool/cbfstool.c Thu Jan 13 10:09:21 2011 (r6250) @@ -29,7 +29,8 @@ CMD_ADD_STAGE, CMD_CREATE, CMD_LOCATE, - CMD_PRINT + CMD_PRINT, + CMD_EXTRACT, } cmd_t;
struct command { @@ -244,13 +245,34 @@ return 0; }
+static int cbfs_extract(int argc, char **argv) +{ + char *romname = argv[1]; + char *cmd = argv[2]; + void *rom = loadrom(romname); + + if (rom == NULL) { + printf("Could not load ROM image '%s'.\n", romname); + return 1; + } + + if (argc != 5) + { + printf("Error: you must specify a CBFS name and a file to dump it in.\n"); + return 1; + } + + return extract_file_from_cbfs(romname, argv[3], argv[4]); +} + struct command commands[] = { {CMD_ADD, "add", cbfs_add}, {CMD_ADD_PAYLOAD, "add-payload", cbfs_add_payload}, {CMD_ADD_STAGE, "add-stage", cbfs_add_stage}, {CMD_CREATE, "create", cbfs_create}, {CMD_LOCATE, "locate", cbfs_locate}, - {CMD_PRINT, "print", cbfs_print} + {CMD_PRINT, "print", cbfs_print}, + {CMD_EXTRACT, "extract", cbfs_extract}, };
void usage(void) @@ -266,7 +288,8 @@ " add-stage FILE NAME [COMP] [base] Add a stage to the ROM\n" " create SIZE BOOTBLOCK [ALIGN] Create a ROM file\n" " locate FILE NAME ALIGN Find a place for a file of that size\n" - " print Show the contents of the ROM\n\n" + " print Show the contents of the ROM\n" + " extract NAME FILE Extracts a raw payload from ROM\n\n" "TYPEs:\n" ); print_supported_filetypes();
Modified: trunk/util/cbfstool/common.c ============================================================================== --- trunk/util/cbfstool/common.c Wed Jan 12 22:09:25 2011 (r6249) +++ trunk/util/cbfstool/common.c Thu Jan 13 10:09:21 2011 (r6250) @@ -207,6 +207,69 @@ } }
+int extract_file_from_cbfs(const char *filename, const char *payloadname, const char *outpath) +{ + // Identify the coreboot image. + printf( + "%s: %d kB, bootblocksize %d, romsize %d, offset 0x%x\nAlignment: %d bytes\n\n", + basename((char *)filename), romsize / 1024, ntohl(master_header->bootblocksize), + romsize, ntohl(master_header->offset), align); + + FILE *outfile = NULL; + uint32_t current = phys_start; + while (current < phys_end) { + if (!cbfs_file_header(current)) { + current += align; + continue; + } + + // Locate the file start struct + struct cbfs_file *thisfile = + (struct cbfs_file *)phys_to_virt(current); + // And its length + uint32_t length = ntohl(thisfile->len); + // Locate the file name + char *fname = (char *)(phys_to_virt(current) + sizeof(struct cbfs_file)); + // It's not the file we are looking for.. + if (strcmp(fname, payloadname) != 0) + { + current = + ALIGN(current + ntohl(thisfile->len) + + ntohl(thisfile->offset), align); + continue; + } + + // Else, it's our file. + printf("Found %.30s payload at 0x%x, type %.12s, size %d\n", fname, + current - phys_start, strfiletype(ntohl(thisfile->type)), + length); + + // If we are not dumping to stdout, open the out file. + outfile = fopen(outpath, "wb"); + if (!outfile) + { + printf("Could not open the file %s for writing. Aborting.\n", outpath); + return 1; + } + + if (ntohl(thisfile->type) != CBFS_COMPONENT_RAW) + { + printf("Warning: only 'raw' files are safe to extract.\n"); + } + + fwrite(((char *)thisfile) + + ntohl(thisfile->offset), length, 1, outfile); + + fclose(outfile); + printf("Successfully dumped the payload.\n"); + + // We'll only dump one file. + return 0; + } + +} + + int add_file_to_cbfs(void *content, uint32_t contentsize, uint32_t location) { uint32_t current = phys_start;
Modified: trunk/util/cbfstool/common.h ============================================================================== --- trunk/util/cbfstool/common.h Wed Jan 12 22:09:25 2011 (r6249) +++ trunk/util/cbfstool/common.h Thu Jan 13 10:09:21 2011 (r6250) @@ -68,6 +68,7 @@
int add_file_to_cbfs(void *content, uint32_t contentsize, uint32_t location); void print_cbfs_directory(const char *filename); +int extract_file_from_cbfs(const char *filename, const char *payloadname, const char *outpath);
uint32_t cbfs_find_location(const char *romfile, uint32_t filesize, const char *filename, uint32_t align);