Chromium Code Reviews| Index: layout.c |
| diff --git a/layout.c b/layout.c |
| index c917274a1aeb1fdb4fa98efe56cfb0f7c486ea31..4ba6ad66b500e7a943307d88a1e09031df319269 100644 |
| --- a/layout.c |
| +++ b/layout.c |
| @@ -39,6 +39,7 @@ typedef struct { |
| unsigned int end; |
| unsigned int included; |
| char name[256]; |
| + char file[256]; /* file[0]=='\0' means not specified. */ |
| } romlayout_t; |
| static romlayout_t rom_entries[MAX_ROMLAYOUT]; |
| @@ -196,15 +197,22 @@ int read_romlayout(char *name) |
| int find_romentry(char *name) |
| { |
| int i; |
| + char *file; |
| if (!romimages) |
| return -1; |
| - msg_gdbg("Looking for \"%s\"... ", name); |
| + /* -i <image>[:<file>] */ |
| + if (strtok(name, ":")) { |
| + file = strtok(NULL, ""); |
| + } |
| + msg_gdbg("Looking for \"%s\" (file=\"%s\")... ", |
| + name, file ? file : "<not specified>"); |
|
Hung-Te
2011/03/03 11:03:27
file may be not initialized, if name does not cont
dhendrix
2011/03/04 00:43:09
agreed. i think you need to initialize file to NUL
Louis
2011/03/04 03:46:30
Done.
Louis
2011/03/04 03:46:30
Done.
|
| for (i = 0; i < romimages; i++) { |
| if (!strcmp(rom_entries[i].name, name)) { |
| rom_entries[i].included = 1; |
| + strcpy(rom_entries[i].file, file ? file : ""); |
| msg_gdbg("found.\n"); |
| return i; |
| } |
| @@ -239,6 +247,32 @@ int find_next_included_romentry(unsigned int start) |
| return best_entry; |
| } |
| +static int read_content_from_file(int entry, uint8_t *newcontents) { |
| + char *file; |
| + FILE *fp; |
| + int len; |
| + |
| + /* If file name is specified for this partition, read file |
| + * content to overwrite. */ |
| + file = rom_entries[entry].file; |
| + len = rom_entries[entry].end - rom_entries[entry].start + 1; |
| + if (file[0]) { |
|
dhendrix
2011/03/04 00:43:09
Change to "if (file)". I think file[0] might cause
Hung-Te
2011/03/04 01:09:42
should better be if(file && *file)
Louis
2011/03/04 03:46:30
Hm... actually "file" is static array: char file[2
Louis
2011/03/04 03:46:30
As above.
On 2011/03/04 01:09:42, Hung-Te wrote:
|
| + int numbytes; |
| + if ((fp = fopen(file, "rb")) == NULL) { |
| + perror(file); |
| + return -1; |
| + } |
| + numbytes = fread(newcontents + rom_entries[entry].start, |
| + 1, len, fp); |
| + fclose(fp); |
| + if (numbytes == -1) { |
| + perror(file); |
| + return -1; |
| + } |
| + } |
| + return 0; |
| +} |
| + |
| int handle_romentries(struct flashchip *flash, uint8_t *oldcontents, uint8_t *newcontents) |
| { |
| unsigned int start = 0; |
| @@ -254,6 +288,7 @@ int handle_romentries(struct flashchip *flash, uint8_t *oldcontents, uint8_t *ne |
| * The union of all included romentries is used from the new image. |
| */ |
| while (start < size) { |
| + |
| entry = find_next_included_romentry(start); |
| /* No more romentries for remaining region? */ |
| if (entry < 0) { |
| @@ -261,9 +296,14 @@ int handle_romentries(struct flashchip *flash, uint8_t *oldcontents, uint8_t *ne |
| size - start); |
| break; |
| } |
| + |
| + /* For non-included region, copy from old content. */ |
| if (rom_entries[entry].start > start) |
| memcpy(newcontents + start, oldcontents + start, |
| rom_entries[entry].start - start); |
| + /* For included region, copy from file if specified. */ |
| + if (read_content_from_file(entry, newcontents) < 0) return -1; |
| + |
| /* Skip to location after current romentry. */ |
| start = rom_entries[entry].end + 1; |
| /* Catch overflow. */ |
| @@ -273,3 +313,72 @@ int handle_romentries(struct flashchip *flash, uint8_t *oldcontents, uint8_t *ne |
| return 0; |
| } |
| + |
| +static int write_content_to_file(int entry, uint8_t *buf) { |
| + char *file; |
| + FILE *fp; |
| + int len = rom_entries[entry].end - rom_entries[entry].start + 1; |
| + |
| + file = rom_entries[entry].file; |
| + if (file[0]) { /* save to file if name is specified. */ |
|
dhendrix
2011/03/04 00:43:09
same comment as above
Louis
2011/03/04 03:46:30
As above reply. :-)
On 2011/03/04 00:43:09, dhendr
|
| + int numbytes; |
| + if ((fp = fopen(file, "wb")) == NULL) { |
| + perror(file); |
| + return -1; |
| + } |
| + numbytes = fwrite(buf + rom_entries[entry].start, 1, len, fp); |
| + fclose(fp); |
| + if (numbytes != len) { |
| + perror(file); |
| + return -1; |
| + } |
| + } |
| + return 0; |
| +} |
| + |
| +int handle_partial_read( |
| + struct flashchip *flash, |
| + uint8_t *buf, |
| + int (*read) (struct flashchip *flash, uint8_t *buf, int start, int len)) { |
| + |
| + unsigned int start = 0; |
| + int entry; |
| + unsigned int size = flash->total_size * 1024; |
| + int count = 0; |
| + |
| + /* If no layout file was specified or the layout file was empty, assume |
| + * that the user wants to flash the complete new image. |
| + */ |
| + if (!romimages) |
| + return 0; |
| + /* Walk through the table and write content to file for those included |
| + * partition. */ |
| + while (start < size) { |
| + int len; |
| + |
| + entry = find_next_included_romentry(start); |
| + /* No more romentries for remaining region? */ |
| + if (entry < 0) { |
| + break; |
| + } |
| + ++count; |
| + |
| + /* read content from flash. */ |
| + len = rom_entries[entry].end - rom_entries[entry].start + 1; |
| + if (read(flash, buf + rom_entries[entry].start, |
| + rom_entries[entry].start, len)) { |
| + perror("flash partial read failed."); |
| + return -1; |
| + } |
| + /* If file is specified, write this partition to file. */ |
| + if (write_content_to_file(entry, buf) < 0) return -1; |
| + |
| + /* Skip to location after current romentry. */ |
| + start = rom_entries[entry].end + 1; |
| + /* Catch overflow. */ |
| + if (!start) |
| + break; |
| + } |
| + |
| + return count; |
| +} |