Add an optional sub-parameter to the -i parameter to allow building the
image to be written from multiple files. This will also allow regions to
be read from flash and written to separate image files in a later patch.
Existing function read_buf_from_file() is refined and reused to read the file.

based on chromiumos'
d0ea9ed71e7f86bb8e8db2ca7c32a96de25343d8
Signed-off-by: David Hendricks <[email protected]>
Signed-off-by: Stefan Tauner <[email protected]>
---
 cli_classic.c  |  9 ++++---
 dummyflasher.c |  2 +-
 flash.h        |  2 +-
 flashrom.c     | 18 +++++++++-----
 layout.c       | 78 ++++++++++++++++++++++++++++++++++++++++++++--------------
 5 files changed, 78 insertions(+), 31 deletions(-)

diff --git a/cli_classic.c b/cli_classic.c
index a0c2d64..ed6d6aa 100644
--- a/cli_classic.c
+++ b/cli_classic.c
@@ -40,8 +40,8 @@ static void cli_classic_usage(const char *name)
 #if CONFIG_PRINT_WIKI == 1
               "-z|"
 #endif
-              "-p <programmername>[:<parameters>] [-c <chipname>]\n"
-              "[-E|(-r|-w|-v) <file>] [-l <layoutfile> [-i <imagename>]...] 
[-n] [-f]]\n"
+              "-p <programmername>[:<parameter>[,<parameter>]...] [-c 
<chipname>]\n"
+              "[-E|(-r|-w|-v) <imagefile>] [-l <layoutfile> [-i 
<region>[:<regionfile>]...] [-n] [-f]]\n"
               "[-V[V[V]]] [-o <logfile>]\n\n", name);
 
        printf(" -h | --help                        print this help text\n"
@@ -54,8 +54,9 @@ static void cli_classic_usage(const char *name)
               " -c | --chip <chipname>             probe only for specified 
flash chip\n"
               " -f | --force                       force specific operations 
(see man page)\n"
               " -n | --noverify                    don't auto-verify\n"
-              " -l | --layout <layoutfile>         read ROM layout from 
<layoutfile>\n"
-              " -i | --image <name>                only flash image <name> 
from flash layout\n"
+              " -l | --layout <layoutfile>         read layout from 
<layoutfile>\n"
+              " -i | --include <region>[<:file>]   only flash image <region> 
from layout \n"
+              "                                    (optionally with data from 
<file>)\n"
               " -o | --output <logfile>            log output to <logfile>\n"
               " -L | --list-supported              print supported devices\n"
 #if CONFIG_PRINT_WIKI == 1
diff --git a/dummyflasher.c b/dummyflasher.c
index 9c0d868..90d2261 100644
--- a/dummyflasher.c
+++ b/dummyflasher.c
@@ -389,7 +389,7 @@ int dummy_init(void)
                        msg_pdbg("matches.\n");
                        msg_pdbg("Reading %s\n", emu_persistent_image);
                        read_buf_from_file(flashchip_contents, emu_chip_size,
-                                          emu_persistent_image);
+                                          emu_persistent_image, NULL);
                } else {
                        msg_pdbg("doesn't match.\n");
                }
diff --git a/flash.h b/flash.h
index a942b9b..be5918b 100644
--- a/flash.h
+++ b/flash.h
@@ -261,7 +261,7 @@ void print_banner(void);
 void list_programmers_linebreak(int startcol, int cols, int paren);
 int selfcheck(void);
 int doit(struct flashctx *flash, int force, const char *filename, int read_it, 
int write_it, int erase_it, int verify_it);
-int read_buf_from_file(unsigned char *buf, unsigned long size, const char 
*filename);
+int read_buf_from_file(unsigned char *buf, unsigned long size, const char 
*filename, const char *size_msg);
 int write_buf_to_file(unsigned char *buf, unsigned long size, const char 
*filename);
 
 /* helpers.c */
diff --git a/flashrom.c b/flashrom.c
index afab57c..7db2696 100644
--- a/flashrom.c
+++ b/flashrom.c
@@ -1165,8 +1165,7 @@ notfound:
        return chip - flashchips;
 }
 
-int read_buf_from_file(unsigned char *buf, unsigned long size,
-                      const char *filename)
+int read_buf_from_file(unsigned char *buf, unsigned long size, const char 
*filename, const char *size_msg)
 {
 #ifdef __LIBPAYLOAD__
        msg_gerr("Error: No file I/O support in libpayload\n");
@@ -1186,8 +1185,10 @@ int read_buf_from_file(unsigned char *buf, unsigned long 
size,
                return 1;
        }
        if (image_stat.st_size != size) {
-               msg_gerr("Error: Image size (%jd B) doesn't match the flash 
chip's size (%lu B)!\n",
-                        (intmax_t)image_stat.st_size, size);
+               if (size_msg == NULL)
+                       size_msg = "the expected size";
+               msg_gerr("Error: Image size (%jd B) doesn't match %s (%lu 
B)!\n",
+                        (intmax_t)image_stat.st_size, size_msg, size);
                fclose(image);
                return 1;
        }
@@ -1968,7 +1969,7 @@ int doit(struct flashctx *flash, int force, const char 
*filename, int read_it,
        }
 
        if (write_it || verify_it) {
-               if (read_buf_from_file(newcontents, size, filename)) {
+               if (read_buf_from_file(newcontents, size, filename, "the flash 
chip's size")) {
                        ret = 1;
                        goto out;
                }
@@ -2002,7 +2003,12 @@ int doit(struct flashctx *flash, int force, const char 
*filename, int read_it,
        msg_cinfo("done.\n");
 
        /* Build a new image taking the given layout into account. */
-       build_new_image(flash, oldcontents, newcontents);
+       if (build_new_image(flash, oldcontents, newcontents)) {
+               msg_gerr("Could not prepare the data to be written due to 
problems with the layout,\n"
+                        "aborting.\n");
+               ret = 1;
+               goto out;
+       }
 
        // ////////////////////////////////////////////////////////////
 
diff --git a/layout.c b/layout.c
index 08cc776..7e2e904 100644
--- a/layout.c
+++ b/layout.c
@@ -33,6 +33,7 @@ typedef struct {
        chipoff_t end;
        unsigned int included;
        char name[256];
+       char *file;
 } romentry_t;
 
 /* rom_entries store the entries specified in a layout file and associated 
run-time data */
@@ -54,7 +55,7 @@ int read_romlayout(char *name)
        romlayout = fopen(name, "r");
 
        if (!romlayout) {
-               msg_gerr("ERROR: Could not open ROM layout (%s).\n",
+               msg_gerr("ERROR: Could not open layout file (%s).\n",
                        name);
                return -1;
        }
@@ -63,8 +64,7 @@ int read_romlayout(char *name)
                char *tstr1, *tstr2;
 
                if (num_rom_entries >= MAX_ROMLAYOUT) {
-                       msg_gerr("Maximum number of ROM images (%i) in layout "
-                                "file reached.\n", MAX_ROMLAYOUT);
+                       msg_gerr("Maximum number of entries (%i) in layout file 
reached.\n", MAX_ROMLAYOUT);
                        return 1;
                }
                if (2 != fscanf(romlayout, "%s %s\n", tempstr, 
rom_entries[num_rom_entries].name))
@@ -85,6 +85,7 @@ int read_romlayout(char *name)
                rom_entries[num_rom_entries].start = strtol(tstr1, (char 
**)NULL, 16);
                rom_entries[num_rom_entries].end = strtol(tstr2, (char **)NULL, 
16);
                rom_entries[num_rom_entries].included = 0;
+               rom_entries[num_rom_entries].file = NULL;
                num_rom_entries++;
        }
 
@@ -138,14 +139,9 @@ int register_include_arg(char *name)
 static int find_romentry(char *name)
 {
        int i;
-
-       if (num_rom_entries == 0)
-               return -1;
-
        msg_gspew("Looking for region \"%s\"... ", name);
        for (i = 0; i < num_rom_entries; i++) {
-               if (!strcmp(rom_entries[i].name, name)) {
-                       rom_entries[i].included = 1;
+               if (strcmp(rom_entries[i].name, name) == 0) {
                        msg_gspew("found.\n");
                        return i;
                }
@@ -165,27 +161,61 @@ int process_include_args(void)
        if (num_include_args == 0)
                return 0;
 
-       /* User has specified an area, but no layout file is loaded. */
+       /* User has specified an include argument, but no layout file is 
loaded. */
        if (num_rom_entries == 0) {
-               msg_gerr("Region requested (with -i \"%s\"), "
-                        "but no layout data is available.\n",
+               msg_gerr("Region requested (with -i/--include \"%s\"),\n"
+                        "but no layout data is available. To include one use 
the -l/--layout syntax).\n",
                         include_args[0]);
                return 1;
        }
 
        for (i = 0; i < num_include_args; i++) {
-               if (find_romentry(include_args[i]) < 0) {
-                       msg_gerr("Invalid region specified: \"%s\".\n",
-                                include_args[i]);
+               char *file;
+               char *name = include_args[i];
+               int ret = unquote_string(&name, &file, ":"); /* -i 
<region>[:<file>] */
+               if (ret != 0) {
+                       msg_gerr("Invalid include argument specified: 
\"%s\".\n", name);
                        return 1;
                }
+               int idx = find_romentry(name);
+               if (idx < 0) {
+                       msg_gerr("Invalid region name specified: \"%s\".\n", 
name);
+                       return 1;
+               }
+               rom_entries[idx].included = 1;
                found++;
+
+               if (file[0] != '\0') {
+                       /* The remaining characters are interpreted as possible 
quoted filename.  */
+                       ret = unquote_string(&file, NULL, NULL);
+                       if (ret != 0) {
+                               msg_gerr("Invalid region file name specified: 
\"%s\".\n", file);
+                               return 1;
+                       }
+#ifdef __LIBPAYLOAD__
+                       msg_gerr("Error: No file I/O support in libpayload\n");
+                       return 1;
+#else
+                       file = strdup(file);
+                       if (file == NULL) {
+                               msg_gerr("Out of memory!\n");
+                               return 1;
+                       }
+                       rom_entries[idx].file = file;
+#endif
+               }
        }
 
-       msg_ginfo("Using region%s: \"%s\"", num_include_args > 1 ? "s" : "",
-                 include_args[0]);
-       for (i = 1; i < num_include_args; i++)
-               msg_ginfo(", \"%s\"", include_args[i]);
+       msg_ginfo("Using region%s: ", num_rom_entries > 1 ? "s" : "");
+       bool first = true;
+       for (i = 0; i < num_rom_entries; i++)
+               if (rom_entries[i].included) {
+                       if (first)
+                               first = false;
+                       else
+                               msg_ginfo(", ");
+                       msg_ginfo("\"%s\"", rom_entries[i].name);
+       }
        msg_ginfo(".\n");
        return 0;
 }
@@ -200,6 +230,8 @@ void layout_cleanup(void)
        num_include_args = 0;
 
        for (i = 0; i < num_rom_entries; i++) {
+               free(rom_entries[i].file);
+               rom_entries[i].file = NULL;
                rom_entries[i].included = 0;
        }
        num_rom_entries = 0;
@@ -283,6 +315,14 @@ int build_new_image(const struct flashctx *flash, uint8_t 
*oldcontents, uint8_t
                if (entry->start > start)
                        memcpy(newcontents + start, oldcontents + start,
                               entry->start - start);
+               /* If a file name is specified for this region, read the file 
contents and
+                * overwrite @newcontents in the range specified by @entry. */
+               if (entry->file != NULL) {
+                       if (read_buf_from_file(newcontents + entry->start, 
entry->end - entry->start + 1,
+                           entry->file, "the region's size") != 0)
+                               return 1;
+               }
+
                /* Skip to location after current romentry. */
                start = entry->end + 1;
                /* Catch overflow. */
-- 
Kind regards, Stefan Tauner


_______________________________________________
flashrom mailing list
[email protected]
http://www.flashrom.org/mailman/listinfo/flashrom

Reply via email to