Patchwork [U-Boot,01/11] imximage: make header variable length

login
register
mail settings
Submitter Troy Kisky
Date Sept. 19, 2012, 12:02 a.m.
Message ID <1348012989-19674-2-git-send-email-troy.kisky@boundarydevices.com>
Download mbox | patch
Permalink /patch/184882/
State Changes Requested
Headers show

Comments

Troy Kisky - Sept. 19, 2012, 12:02 a.m.
Also, the header offset is no longer
right before the code starts.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
---
 tools/imximage.c |  142 +++++++++++++++++++++++++++++++-----------------------
 tools/imximage.h |   10 ++--
 2 files changed, 87 insertions(+), 65 deletions(-)

Patch

diff --git a/tools/imximage.c b/tools/imximage.c
index 03a7716..25d3b74 100644
--- a/tools/imximage.c
+++ b/tools/imximage.c
@@ -65,12 +65,15 @@  static table_entry_t imximage_versions[] = {
 	{-1,            "",     " (Invalid)",                 },
 };
 
-static struct imx_header imximage_header;
 static uint32_t imximage_version;
 
 static set_dcd_val_t set_dcd_val;
 static set_dcd_rst_t set_dcd_rst;
 static set_imx_hdr_t set_imx_hdr;
+static set_imx_size_t set_imx_size;
+static uint32_t g_flash_offset;
+
+static struct image_type_params imximage_params;
 
 static uint32_t get_cfg_value(char *token, char *name,  int linenr)
 {
@@ -207,85 +210,79 @@  static void set_dcd_rst_v2(struct imx_header *imxhdr, uint32_t dcd_len,
 	dcd_v2->write_dcd_command.param = DCD_COMMAND_PARAM;
 }
 
-static void set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len,
-					struct stat *sbuf,
-					struct mkimage_params *params)
+static int set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len,
+		uint32_t entry_point, uint32_t flash_offset)
 {
 	imx_header_v1_t *hdr_v1 = &imxhdr->header.hdr_v1;
 	flash_header_v1_t *fhdr_v1 = &hdr_v1->fhdr;
 	dcd_v1_t *dcd_v1 = &hdr_v1->dcd_table;
-	uint32_t base_offset;
-
-	/* Exit if there is no BOOT_FROM field specifying the flash_offset */
-	if(imxhdr->flash_offset == FLASH_OFFSET_UNDEFINED) {
-		fprintf(stderr, "Error: Header v1: No BOOT_FROM tag in %s\n",
-			params->imagename);
-		exit(EXIT_FAILURE);
-	}
+	uint32_t hdr_base;
+	uint32_t header_length = (((char *)&dcd_v1->addr_data[dcd_len].addr)
+			- ((char *)imxhdr));
 
 	/* Set magic number */
 	fhdr_v1->app_code_barker = APP_CODE_BARKER;
 
-	fhdr_v1->app_dest_ptr = params->addr;
-	fhdr_v1->app_dest_ptr = params->ep - imxhdr->flash_offset -
-		sizeof(struct imx_header);
-	fhdr_v1->app_code_jump_vector = params->ep;
+	hdr_base = entry_point - header_length;
+	fhdr_v1->app_dest_ptr = hdr_base - flash_offset;
+	fhdr_v1->app_code_jump_vector = entry_point;
 
-	base_offset = fhdr_v1->app_dest_ptr + imxhdr->flash_offset ;
-	fhdr_v1->dcd_ptr_ptr =
-		(uint32_t) (offsetof(flash_header_v1_t, dcd_ptr) -
-		offsetof(flash_header_v1_t, app_code_jump_vector) +
-		base_offset);
-
-	fhdr_v1->dcd_ptr = base_offset +
-			offsetof(imx_header_v1_t, dcd_table);
-
-	/* The external flash header must be at the end of the DCD table */
-	dcd_v1->addr_data[dcd_len].type = sbuf->st_size +
-				imxhdr->flash_offset +
-				sizeof(struct imx_header);
+	fhdr_v1->dcd_ptr_ptr = hdr_base + offsetof(flash_header_v1_t, dcd_ptr);
+	fhdr_v1->dcd_ptr = hdr_base + offsetof(imx_header_v1_t, dcd_table);
 
 	/* Security feature are not supported */
 	fhdr_v1->app_code_csf = 0;
 	fhdr_v1->super_root_key = 0;
+	return header_length;
+}
+
+static void set_imx_size_v1(struct imx_header *imxhdr, uint32_t file_size,
+		uint32_t flash_offset)
+{
+	uint32_t *p = (uint32_t *)(((char *)imxhdr)
+			+ imximage_params.header_size);
+
+	/* The external flash header must be at the end of the DCD table */
+	/* file_size includes header */
+	p[-1] = file_size + flash_offset;
 }
 
-static void set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,
-					struct stat *sbuf,
-					struct mkimage_params *params)
+static int set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,
+		uint32_t entry_point, uint32_t flash_offset)
 {
 	imx_header_v2_t *hdr_v2 = &imxhdr->header.hdr_v2;
 	flash_header_v2_t *fhdr_v2 = &hdr_v2->fhdr;
-
-	/* Exit if there is no BOOT_FROM field specifying the flash_offset */
-	if(imxhdr->flash_offset == FLASH_OFFSET_UNDEFINED) {
-		fprintf(stderr, "Error: Header v2: No BOOT_FROM tag in %s\n",
-			params->imagename);
-		exit(EXIT_FAILURE);
-	}
+	uint32_t hdr_base;
+	uint32_t header_length = (dcd_len) ?
+		(char *)&hdr_v2->dcd_table.addr_data[dcd_len] - ((char*)imxhdr)
+		: offsetof(imx_header_v2_t, dcd_table);
 
 	/* Set magic number */
 	fhdr_v2->header.tag = IVT_HEADER_TAG; /* 0xD1 */
 	fhdr_v2->header.length = cpu_to_be16(sizeof(flash_header_v2_t));
 	fhdr_v2->header.version = IVT_VERSION; /* 0x40 */
 
-	fhdr_v2->entry = params->ep;
+	fhdr_v2->entry = entry_point;
 	fhdr_v2->reserved1 = fhdr_v2->reserved2 = 0;
-	fhdr_v2->self = params->ep - sizeof(struct imx_header);
-
-	fhdr_v2->dcd_ptr = fhdr_v2->self +
-			offsetof(imx_header_v2_t, dcd_table);
+	fhdr_v2->self = hdr_base = entry_point - header_length;
 
-	fhdr_v2->boot_data_ptr = fhdr_v2->self +
-			offsetof(imx_header_v2_t, boot_data);
-
-	hdr_v2->boot_data.start = fhdr_v2->self - imxhdr->flash_offset;
-	hdr_v2->boot_data.size = sbuf->st_size +
-			imxhdr->flash_offset +
-			sizeof(struct imx_header);
+	fhdr_v2->dcd_ptr = (dcd_len) ? hdr_base
+			+ offsetof(imx_header_v2_t, dcd_table) : 0;
+	fhdr_v2->boot_data_ptr = hdr_base
+			+ offsetof(imx_header_v2_t, boot_data);
+	hdr_v2->boot_data.start = hdr_base - flash_offset;
 
 	/* Security feature are not supported */
 	fhdr_v2->csf = 0;
+	return header_length;
+}
+
+static void set_imx_size_v2(struct imx_header *imxhdr, uint32_t file_size,
+		uint32_t flash_offset)
+{
+	imx_header_v2_t *hdr_v2 = &imxhdr->header.hdr_v2;
+	/* file_size includes header */
+	hdr_v2->boot_data.size = file_size + flash_offset;
 }
 
 static void set_hdr_func(struct imx_header *imxhdr)
@@ -295,11 +292,13 @@  static void set_hdr_func(struct imx_header *imxhdr)
 		set_dcd_val = set_dcd_val_v1;
 		set_dcd_rst = set_dcd_rst_v1;
 		set_imx_hdr = set_imx_hdr_v1;
+		set_imx_size = set_imx_size_v1;
 		break;
 	case IMXIMAGE_V2:
 		set_dcd_val = set_dcd_val_v2;
 		set_dcd_rst = set_dcd_rst_v2;
 		set_imx_hdr = set_imx_hdr_v2;
+		set_imx_size = set_imx_size_v2;
 		break;
 	default:
 		err_imximage_version(imximage_version);
@@ -381,9 +380,9 @@  static void parse_cfg_cmd(struct imx_header *imxhdr, int32_t cmd, char *token,
 		set_hdr_func(imxhdr);
 		break;
 	case CMD_BOOT_FROM:
-		imxhdr->flash_offset = get_table_entry_id(imximage_bootops,
+		g_flash_offset = get_table_entry_id(imximage_bootops,
 					"imximage boot option", token);
-		if (imxhdr->flash_offset == -1) {
+		if (g_flash_offset == -1) {
 			fprintf(stderr, "Error: %s[%d] -Invalid boot device"
 				"(%s)\n", name, lineno, token);
 			exit(EXIT_FAILURE);
@@ -521,12 +520,17 @@  static void imximage_print_header(const void *ptr)
 	}
 }
 
-static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd,
-				struct mkimage_params *params)
+int imximage_vrec_header(struct mkimage_params *params,
+		struct image_type_params *tparams)
 {
-	struct imx_header *imxhdr = (struct imx_header *)ptr;
+	struct imx_header *imxhdr;
 	uint32_t dcd_len;
 
+	imxhdr = calloc(1, MAX_HEADER_SIZE);
+	if (!imxhdr) {
+		fprintf(stderr, "Error: out of memory\n");
+		exit(EXIT_FAILURE);
+	}
 	/*
 	 * In order to not change the old imx cfg file
 	 * by adding VERSION command into it, here need
@@ -534,14 +538,31 @@  static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd,
 	 */
 	imximage_version = IMXIMAGE_V1;
 	/* Be able to detect if the cfg file has no BOOT_FROM tag */
-	imxhdr->flash_offset = FLASH_OFFSET_UNDEFINED;
+	g_flash_offset = FLASH_OFFSET_UNDEFINED;
 	set_hdr_func(imxhdr);
 
 	/* Parse dcd configuration file */
 	dcd_len = parse_cfg_file(imxhdr, params->imagename);
 
+	/* Exit if there is no BOOT_FROM field specifying the flash_offset */
+	if (g_flash_offset == FLASH_OFFSET_UNDEFINED) {
+		fprintf(stderr, "Error: No BOOT_FROM tag in %s\n",
+				params->imagename);
+		exit(EXIT_FAILURE);
+	}
 	/* Set the imx header */
-	(*set_imx_hdr)(imxhdr, dcd_len, sbuf, params);
+	imximage_params.header_size = (*set_imx_hdr)(imxhdr, dcd_len,
+			params->ep, g_flash_offset);
+	imximage_params.hdr = imxhdr;
+	return 0;
+}
+
+static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd,
+				struct mkimage_params *params)
+{
+	/* Set the size in header */
+	(*set_imx_size)((struct imx_header *)ptr, sbuf->st_size,
+			g_flash_offset);
 }
 
 int imximage_check_params(struct mkimage_params *params)
@@ -571,8 +592,9 @@  int imximage_check_params(struct mkimage_params *params)
  */
 static struct image_type_params imximage_params = {
 	.name		= "Freescale i.MX 5x Boot Image support",
-	.header_size	= sizeof(struct imx_header),
-	.hdr		= (void *)&imximage_header,
+	.header_size	= 0,
+	.hdr		= NULL,
+	.vrec_header	= imximage_vrec_header,
 	.check_image_type = imximage_check_image_types,
 	.verify_header	= imximage_verify_header,
 	.print_header	= imximage_print_header,
diff --git a/tools/imximage.h b/tools/imximage.h
index 34f293d..5fe3a8a 100644
--- a/tools/imximage.h
+++ b/tools/imximage.h
@@ -30,6 +30,7 @@ 
 #define DCD_BARKER	0xB17219E9
 
 #define HEADER_OFFSET	0x400
+#define MAX_HEADER_SIZE	(16 << 10)
 
 #define CMD_DATA_STR	"DATA"
 #define FLASH_OFFSET_UNDEFINED	0xFFFFFFFF
@@ -156,7 +157,6 @@  struct imx_header {
 		imx_header_v1_t hdr_v1;
 		imx_header_v2_t hdr_v2;
 	} header;
-	uint32_t flash_offset;
 };
 
 typedef void (*set_dcd_val_t)(struct imx_header *imxhdr,
@@ -168,9 +168,9 @@  typedef void (*set_dcd_rst_t)(struct imx_header *imxhdr,
 					uint32_t dcd_len,
 					char *name, int lineno);
 
-typedef void (*set_imx_hdr_t)(struct imx_header *imxhdr,
-					uint32_t dcd_len,
-					struct stat *sbuf,
-					struct mkimage_params *params);
+typedef int (*set_imx_hdr_t)(struct imx_header *imxhdr, uint32_t dcd_len,
+		uint32_t entry_point, uint32_t flash_offset);
+typedef void (*set_imx_size_t)(struct imx_header *imxhdr, uint32_t file_size,
+		uint32_t flash_offset);
 
 #endif /* _IMXIMAGE_H_ */