Patchwork [1/5] layout: Add -i <image>[:<file>] support

login
register
about
Submitter Stefan Tauner
Date 2011-12-25 16:56:04
Message ID <1324832168-15617-2-git-send-email-stefan.tauner@student.tuwien.ac.at>
Download mbox | patch
Permalink /patch/3486/
State Superseded
Headers show

Comments

Stefan Tauner - 2011-12-25 16:56:04
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.

based on chromiumos'
d0ea9ed71e7f86bb8e8db2ca7c32a96de25343d8
Signed-off-by: David Hendricks <dhendrix@chromium.org>

Signed-off-by: Stefan Tauner <stefan.tauner@student.tuwien.ac.at>
---

TODO:
 - man page
 - handling or at least an explanation of precedence of command line
   parameters in case of overlapping regions.
---
 layout.c |   45 ++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 44 insertions(+), 1 deletions(-)

Patch

diff --git a/layout.c b/layout.c
index 1f7f01a..4bd1560 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 == "" means not specified. */
 } romlayout_t;
 
 /* include_args lists arguments specified at the command line with -i. They
@@ -183,6 +184,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++;
 	}
 
@@ -220,14 +222,24 @@  int register_include_arg(char *name)
 static int find_romentry(char *name)
 {
 	int i;
+	char *file = NULL;
 
 	if (!romimages)
 		return -1;
 
-	msg_gspew("Looking for region \"%s\"... ", name);
+	/* -i <image>[:<file>] */
+	if (strtok(name, ":")) {
+		file = strtok(NULL, "");
+	}
+	msg_gspew("Looking for region \"%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_gspew("found.\n");
 			return i;
 		}
@@ -299,6 +311,33 @@  romlayout_t *get_next_included_romentry(unsigned int start)
 	return best_entry;
 }
 
+/* If a file name is specified for this region, read the file contents and
+ * overwrite @newcontents in the range specified by @entry.
+ */
+static int read_content_from_file(romlayout_t *entry, uint8_t *newcontents)
+{
+	char *file;
+	FILE *fp;
+	int len;
+
+	file = entry->file;
+	len = entry->end - entry->start + 1;
+	if (file[0] != '\0') {
+		int numbytes;
+		if ((fp = fopen(file, "rb")) == NULL) {
+			perror(file);
+			return 1;
+		}
+		numbytes = fread(newcontents + entry->start, 1, len, fp);
+		fclose(fp);
+		if (numbytes != len) {
+			perror(file);
+			return 1;
+		}
+	}
+	return 0;
+}
+
 int handle_romentries(struct flashctx *flash, uint8_t *oldcontents, uint8_t *newcontents)
 {
 	unsigned int start = 0;
@@ -326,6 +365,10 @@  int handle_romentries(struct flashctx *flash, uint8_t *oldcontents, uint8_t *new
 		if (entry->start > start)
 			memcpy(newcontents + start, oldcontents + start,
 			       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 = entry->end + 1;
 		/* Catch overflow. */