Previously using layout files was useful for write operations only, for reads it was ignored. This patch added layout handling for reads.
Based on the "Add -i <image>[:<file>] support" patch this one will output the selected regions to files. If the optional argument is given it is used as a file name, else the image name will be used.
--- TODO: man page
side note: the execution path of forced reads is wrong or at least worth a look. it does not use doit() but calls read_flash_to_file() directly.
Signed-off-by: Stefan Tauner stefan.tauner@student.tuwien.ac.at --- flash.h | 8 ++++++ flashrom.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------- layout.c | 8 ------ 3 files changed, 73 insertions(+), 18 deletions(-)
diff --git a/flash.h b/flash.h index 6151e1c..c4d747b 100644 --- a/flash.h +++ b/flash.h @@ -39,6 +39,13 @@ #define TIMEOUT_ERROR -101
typedef unsigned long chipaddr; +typedef struct { + unsigned int start; + unsigned int end; + unsigned int included; + char name[256]; + char file[256]; /* file == "" means not specified. */ +} romlayout_t;
int register_shutdown(int (*function) (void *data), void *data); void *programmer_map_flash_region(const char *descr, unsigned long phys_addr, @@ -292,6 +299,7 @@ int print(int type, const char *fmt, ...) __attribute__((format(printf, 2, 3))); int register_include_arg(char *name); int process_include_args(void); int read_romlayout(char *name); +romlayout_t *get_next_included_romentry(unsigned int start); int build_new_image(struct flashctx *flash, int oldcontents_valid, uint8_t *oldcontents, uint8_t *newcontents);
/* spi.c */ diff --git a/flashrom.c b/flashrom.c index 708dba0..2eec0d6 100644 --- a/flashrom.c +++ b/flashrom.c @@ -1069,7 +1069,7 @@ int read_buf_from_file(unsigned char *buf, unsigned long size, return 0; }
-int write_buf_to_file(unsigned char *buf, unsigned long size, +int write_dump_to_file(unsigned char *buf, unsigned long size, const char *filename) { unsigned long numbytes; @@ -1094,26 +1094,81 @@ int write_buf_to_file(unsigned char *buf, unsigned long size, return 0; }
+int write_buf_to_file(unsigned char *buf, unsigned long size, + const char *filename) +{ + romlayout_t *l; + int ret = 0; + + ret = write_dump_to_file(buf, size, filename); + if (ret) + return ret; + + l = get_next_included_romentry(0); + + while (l != NULL) { + const char* name = (l->file[0] == '\0') ? l->name : l->file; + unsigned int len = l->end - l->start + 1; + msg_gdbg2("Writing "%s" to "%s" 0x%08x - 0x%08x (%uB)... ", + l->name, l->file, l->start, l->end, len); + if(write_dump_to_file(buf + l->start, len, name)) { + msg_gdbg2("failed. "); + return 1; + } + msg_gdbg2("done. "); + l = get_next_included_romentry(l->end + 1); + }; + + return 0; +} + +int read_flash_to_buf(struct flashctx *flash, uint8_t *buf) +{ + romlayout_t *l; + + if (!flash->read) { + msg_cerr("No read function available for this flash chip.\n"); + return 1; + } + + l = get_next_included_romentry(0); + /* No included rom entries. Assume complete readout wanted. */ + if (l == NULL) + return flash->read(flash, buf, 0, flash->total_size * 1024); + + do { + unsigned int len = l->end - l->start + 1; + msg_gdbg2("Reading "%s" 0x%08x - 0x%08x (%uB)... ", l->name, + l->start, l->end, len); + if(flash->read(flash, buf + l->start, l->start, len)) { + msg_gdbg2("failed. "); + return 1; + } + msg_gdbg2("done. "); + l = get_next_included_romentry(l->end + 1); + } while (l != NULL); + + return 0; +} + int read_flash_to_file(struct flashctx *flash, const char *filename) { unsigned long size = flash->total_size * 1024; - unsigned char *buf = calloc(size, sizeof(char)); int ret = 0; + uint8_t *buf;
msg_cinfo("Reading flash... "); - if (!buf) { + + buf = calloc(size, sizeof(uint8_t)); + if (buf == NULL) { msg_gerr("Memory allocation failed!\n"); - msg_cinfo("FAILED.\n"); - return 1; - } - if (!flash->read) { - msg_cerr("No read function available for this flash chip.\n"); ret = 1; goto out_free; } - if (flash->read(flash, buf, 0, size)) { + + ret = read_flash_to_buf(flash, buf); + if (ret != 0) { msg_cerr("Read operation failed!\n"); - ret = 1; goto out_free; }
diff --git a/layout.c b/layout.c index dac9dac..9b10bb3 100644 --- a/layout.c +++ b/layout.c @@ -34,14 +34,6 @@ static int romimages = 0;
#define MAX_ROMLAYOUT 32
-typedef struct { - unsigned int start; - unsigned int end; - unsigned int included; - char name[256]; - char file[256]; /* file == "" means not specified. */ -} romlayout_t; - /* include_args lists arguments specified at the command line with -i. They * must be processed at some point so that desired regions are marked as * "included" in the rom_entries list.