Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(519)

Unified Diff: layout.c

Issue 6611015: Support -i partition:file feature for both read and write. (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/flashrom.git@master
Patch Set: fixed according to code review and security check. Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « flashrom.c ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: layout.c
diff --git a/layout.c b/layout.c
index c917274a1aeb1fdb4fa98efe56cfb0f7c486ea31..31c99f73b521ac37efd715ab76f8bb6009ace04e 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];
@@ -178,6 +179,7 @@ int read_romlayout(char *name)
rom_entries[romimages].start = strtol(tstr1, (char **)NULL, 16);
rom_entries[romimages].end = strtol(tstr2, (char **)NULL, 16);
rom_entries[romimages].included = 0;
+ strcpy(rom_entries[romimages].file, "");
romimages++;
}
@@ -196,15 +198,24 @@ int read_romlayout(char *name)
int find_romentry(char *name)
{
int i;
+ char *file = NULL;
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>");
for (i = 0; i < romimages; i++) {
if (!strcmp(rom_entries[i].name, name)) {
rom_entries[i].included = 1;
+ snprintf(rom_entries[i].file,
+ sizeof(rom_entries[i].file),
+ "%s", file ? file : "");
msg_gdbg("found.\n");
return i;
}
@@ -239,6 +250,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]) {
+ 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 +291,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 +299,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 +316,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. */
+ 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;
+}
« no previous file with comments | « flashrom.c ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698