summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--util/cbfstool/cbfstool.c29
-rw-r--r--util/cbfstool/common.c63
-rw-r--r--util/cbfstool/common.h1
3 files changed, 90 insertions, 3 deletions
diff --git a/util/cbfstool/cbfstool.c b/util/cbfstool/cbfstool.c
index e1b9fca58b..507edc255e 100644
--- a/util/cbfstool/cbfstool.c
+++ b/util/cbfstool/cbfstool.c
@@ -29,7 +29,8 @@ typedef enum {
CMD_ADD_STAGE,
CMD_CREATE,
CMD_LOCATE,
- CMD_PRINT
+ CMD_PRINT,
+ CMD_EXTRACT,
} cmd_t;
struct command {
@@ -244,13 +245,34 @@ static int cbfs_print(int argc, char **argv)
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 @@ void usage(void)
" 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();
diff --git a/util/cbfstool/common.c b/util/cbfstool/common.c
index 8478c5a492..a42585b776 100644
--- a/util/cbfstool/common.c
+++ b/util/cbfstool/common.c
@@ -207,6 +207,69 @@ void print_cbfs_directory(const char *filename)
}
}
+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;
diff --git a/util/cbfstool/common.h b/util/cbfstool/common.h
index 8d1b4d845d..8f397d8e65 100644
--- a/util/cbfstool/common.h
+++ b/util/cbfstool/common.h
@@ -68,6 +68,7 @@ int create_cbfs_image(const char *romfile, uint32_t romsize,
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);