Add "cbfstool extract" function.
authorAurelien Guillaume <aurelien@iwi.me>
Thu, 13 Jan 2011 09:09:21 +0000 (09:09 +0000)
committerPatrick Georgi <patrick.georgi@coresystems.de>
Thu, 13 Jan 2011 09:09:21 +0000 (09:09 +0000)
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>
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@6250 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1

util/cbfstool/cbfstool.c
util/cbfstool/common.c
util/cbfstool/common.h

index e1b9fca58bb8b3d0ab3a472da2a32ddd321628c4..507edc255e8486fb113baf787182b2605d9eb8b8 100644 (file)
@@ -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();
index 8478c5a492cc69005dc6acdc593db6fc9f4609ef..a42585b7761b6e7f107ba395baccd86ed354be47 100644 (file)
@@ -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;
index 8d1b4d845d2142f9adbee8352b58f05de1048697..8f397d8e65690632dbbfda1815bd07231d383a79 100644 (file)
@@ -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);