Commit baeb9cf125f8c8c494fdb8e3683d61eb1b5fc107

Authored by Ye Li
1 parent d58a3d2a62

MLK-12440-3 mkimage: Update imximage tool to support plugin

Update imximage for parsing and adding plugin codes to IVT.

Signed-off-by: Ye Li <ye.li@nxp.com>

Showing 2 changed files with 215 additions and 47 deletions Side-by-side Diff

... ... @@ -6,6 +6,8 @@
6 6 * Marvell Semiconductor <www.marvell.com>
7 7 * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
8 8 *
  9 + * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
  10 + *
9 11 * SPDX-License-Identifier: GPL-2.0+
10 12 */
11 13  
... ... @@ -27,6 +29,9 @@
27 29 {CMD_CHECK_BITS_CLR, "CHECK_BITS_CLR", "Reg Check bits clr", },
28 30 {CMD_CSF, "CSF", "Command Sequence File", },
29 31 {CMD_IMAGE_VERSION, "IMAGE_VERSION", "image version", },
  32 +#ifdef CONFIG_USE_PLUGIN
  33 + {CMD_PLUGIN, "PLUGIN", "file plugin_addr", },
  34 +#endif
30 35 {-1, "", "", },
31 36 };
32 37  
... ... @@ -80,6 +85,8 @@
80 85 static uint32_t imximage_csf_size = UNDEFINED;
81 86 /* Initial Load Region Size */
82 87 static uint32_t imximage_init_loadsize;
  88 +static uint32_t imximage_iram_free_start;
  89 +static uint32_t imximage_plugin_size;
83 90  
84 91 static set_dcd_val_t set_dcd_val;
85 92 static set_dcd_param_t set_dcd_param;
86 93  
... ... @@ -118,9 +125,13 @@
118 125  
119 126 /* Try to detect V2 */
120 127 if ((fhdr_v2->header.tag == IVT_HEADER_TAG) &&
121   - (hdr_v2->dcd_table.header.tag == DCD_HEADER_TAG))
  128 + (hdr_v2->data.dcd_table.header.tag == DCD_HEADER_TAG))
122 129 return IMXIMAGE_V2;
123 130  
  131 + if ((fhdr_v2->header.tag == IVT_HEADER_TAG) &&
  132 + hdr_v2->boot_data.plugin)
  133 + return IMXIMAGE_V2;
  134 +
124 135 return IMXIMAGE_VER_INVALID;
125 136 }
126 137  
... ... @@ -165,7 +176,7 @@
165 176 static void set_dcd_param_v2(struct imx_header *imxhdr, uint32_t dcd_len,
166 177 int32_t cmd)
167 178 {
168   - dcd_v2_t *dcd_v2 = &imxhdr->header.hdr_v2.dcd_table;
  179 + dcd_v2_t *dcd_v2 = &imxhdr->header.hdr_v2.data.dcd_table;
169 180 struct dcd_v2_cmd *d = gd_last_cmd;
170 181 struct dcd_v2_cmd *d2;
171 182 int len;
172 183  
173 184  
174 185  
... ... @@ -261,21 +272,23 @@
261 272 static void set_dcd_rst_v2(struct imx_header *imxhdr, uint32_t dcd_len,
262 273 char *name, int lineno)
263 274 {
264   - dcd_v2_t *dcd_v2 = &imxhdr->header.hdr_v2.dcd_table;
265   - struct dcd_v2_cmd *d = gd_last_cmd;
266   - int len;
  275 + if (!imxhdr->header.hdr_v2.boot_data.plugin) {
  276 + dcd_v2_t *dcd_v2 = &imxhdr->header.hdr_v2.data.dcd_table;
  277 + struct dcd_v2_cmd *d = gd_last_cmd;
  278 + int len;
267 279  
268   - if (!d)
269   - d = &dcd_v2->dcd_cmd;
270   - len = be16_to_cpu(d->write_dcd_command.length);
271   - if (len > 4)
272   - d = (struct dcd_v2_cmd *)(((char *)d) + len);
  280 + if (!d)
  281 + d = &dcd_v2->dcd_cmd;
  282 + len = be16_to_cpu(d->write_dcd_command.length);
  283 + if (len > 4)
  284 + d = (struct dcd_v2_cmd *)(((char *)d) + len);
273 285  
274   - len = (char *)d - (char *)&dcd_v2->header;
  286 + len = (char *)d - (char *)&dcd_v2->header;
275 287  
276   - dcd_v2->header.tag = DCD_HEADER_TAG;
277   - dcd_v2->header.length = cpu_to_be16(len);
278   - dcd_v2->header.version = DCD_VERSION;
  288 + dcd_v2->header.tag = DCD_HEADER_TAG;
  289 + dcd_v2->header.length = cpu_to_be16(len);
  290 + dcd_v2->header.version = DCD_VERSION;
  291 + }
279 292 }
280 293  
281 294 static void set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len,
282 295  
283 296  
284 297  
... ... @@ -317,24 +330,91 @@
317 330 fhdr_v2->header.length = cpu_to_be16(sizeof(flash_header_v2_t));
318 331 fhdr_v2->header.version = IVT_VERSION; /* 0x40 */
319 332  
320   - fhdr_v2->entry = entry_point;
321   - fhdr_v2->reserved1 = fhdr_v2->reserved2 = 0;
322   - hdr_base = entry_point - imximage_init_loadsize +
323   - flash_offset;
324   - fhdr_v2->self = hdr_base;
325   - if (dcd_len > 0)
326   - fhdr_v2->dcd_ptr = hdr_base
327   - + offsetof(imx_header_v2_t, dcd_table);
328   - else
  333 + if (!hdr_v2->boot_data.plugin) {
  334 + fhdr_v2->entry = entry_point;
  335 + fhdr_v2->reserved1 = fhdr_v2->reserved2 = 0;
  336 + hdr_base = entry_point - imximage_init_loadsize +
  337 + flash_offset;
  338 + fhdr_v2->self = hdr_base;
  339 + if (dcd_len > 0)
  340 + fhdr_v2->dcd_ptr = hdr_base +
  341 + offsetof(imx_header_v2_t, data);
  342 + else
  343 + fhdr_v2->dcd_ptr = 0;
  344 + fhdr_v2->boot_data_ptr = hdr_base
  345 + + offsetof(imx_header_v2_t, boot_data);
  346 + hdr_v2->boot_data.start = entry_point - imximage_init_loadsize;
  347 +
  348 + fhdr_v2->csf = 0;
  349 +
  350 + header_size_ptr = &hdr_v2->boot_data.size;
  351 + csf_ptr = &fhdr_v2->csf;
  352 + } else {
  353 + imx_header_v2_t *next_hdr_v2;
  354 + flash_header_v2_t *next_fhdr_v2;
  355 +
  356 + if (imximage_csf_size != 0) {
  357 + fprintf(stderr, "Error: Header v2: SECURE_BOOT"
  358 + "is only supported in DCD mode!");
  359 + exit(EXIT_FAILURE);
  360 + }
  361 +
  362 + fhdr_v2->entry = imximage_iram_free_start +
  363 + flash_offset + sizeof(flash_header_v2_t) +
  364 + sizeof(boot_data_t);
  365 +
  366 + fhdr_v2->reserved1 = fhdr_v2->reserved2 = 0;
  367 + fhdr_v2->self = imximage_iram_free_start + flash_offset;
  368 +
329 369 fhdr_v2->dcd_ptr = 0;
330   - fhdr_v2->boot_data_ptr = hdr_base
331   - + offsetof(imx_header_v2_t, boot_data);
332   - hdr_v2->boot_data.start = entry_point - imximage_init_loadsize;
333 370  
334   - fhdr_v2->csf = 0;
  371 + fhdr_v2->boot_data_ptr = fhdr_v2->self +
  372 + offsetof(imx_header_v2_t, boot_data);
335 373  
336   - header_size_ptr = &hdr_v2->boot_data.size;
337   - csf_ptr = &fhdr_v2->csf;
  374 + hdr_v2->boot_data.start = imximage_iram_free_start;
  375 + /*
  376 + * The actural size of plugin image is "imximage_plugin_size +
  377 + * sizeof(flash_header_v2_t) + sizeof(boot_data_t)", plus the
  378 + * flash_offset space.The ROM code only need to copy this size
  379 + * to run the plugin code. However, later when copy the whole
  380 + * U-Boot image to DDR, the ROM code use memcpy to copy the
  381 + * first part of the image, and use the storage read function
  382 + * to get the remaining part. This requires the dividing point
  383 + * must be multiple of storage sector size. Here we set the
  384 + * first section to be 16KB for this purpose.
  385 + */
  386 + hdr_v2->boot_data.size = MAX_PLUGIN_CODE_SIZE;
  387 +
  388 + /* Security feature are not supported */
  389 + fhdr_v2->csf = 0;
  390 +
  391 + next_hdr_v2 = (imx_header_v2_t *)((char*)hdr_v2 +
  392 + imximage_plugin_size);
  393 +
  394 + next_fhdr_v2 = &next_hdr_v2->fhdr;
  395 +
  396 + next_fhdr_v2->header.tag = IVT_HEADER_TAG; /* 0xD1 */
  397 + next_fhdr_v2->header.length =
  398 + cpu_to_be16(sizeof(flash_header_v2_t));
  399 + next_fhdr_v2->header.version = IVT_VERSION; /* 0x40 */
  400 +
  401 + next_fhdr_v2->entry = entry_point;
  402 + hdr_base = entry_point - sizeof(struct imx_header);
  403 + next_fhdr_v2->reserved1 = next_fhdr_v2->reserved2 = 0;
  404 + next_fhdr_v2->self = hdr_base + imximage_plugin_size;
  405 +
  406 + next_fhdr_v2->dcd_ptr = 0;
  407 + next_fhdr_v2->boot_data_ptr = next_fhdr_v2->self +
  408 + offsetof(imx_header_v2_t, boot_data);
  409 +
  410 + next_hdr_v2->boot_data.start = hdr_base - flash_offset;
  411 +
  412 + header_size_ptr = &next_hdr_v2->boot_data.size;
  413 +
  414 + next_hdr_v2->boot_data.plugin = 0;
  415 +
  416 + next_fhdr_v2->csf = 0;
  417 + }
338 418 }
339 419  
340 420 static void set_hdr_func(void)
341 421  
342 422  
... ... @@ -393,16 +473,19 @@
393 473 {
394 474 imx_header_v2_t *hdr_v2 = &imx_hdr->header.hdr_v2;
395 475 flash_header_v2_t *fhdr_v2 = &hdr_v2->fhdr;
396   - dcd_v2_t *dcd_v2 = &hdr_v2->dcd_table;
397   - uint32_t size, version;
  476 + dcd_v2_t *dcd_v2 = &hdr_v2->data.dcd_table;
  477 + uint32_t size, version, plugin;
398 478  
399   - size = be16_to_cpu(dcd_v2->header.length);
400   - if (size > (MAX_HW_CFG_SIZE_V2 * sizeof(dcd_addr_data_t)) + 8) {
  479 + plugin = hdr_v2->boot_data.plugin;
  480 + if (!plugin) {
  481 + size = be16_to_cpu(dcd_v2->header.length) - 8;
  482 + if (size > (MAX_HW_CFG_SIZE_V2 * sizeof(dcd_addr_data_t))) {
401 483 fprintf(stderr,
402 484 "Error: Image corrupt DCD size %d exceed maximum %d\n",
403 485 (uint32_t)(size / sizeof(dcd_addr_data_t)),
404 486 MAX_HW_CFG_SIZE_V2);
405 487 exit(EXIT_FAILURE);
  488 + }
406 489 }
407 490  
408 491 version = detect_imximage_version(imx_hdr);
409 492  
... ... @@ -410,19 +493,83 @@
410 493 printf("Image Type: Freescale IMX Boot Image\n");
411 494 printf("Image Ver: %x", version);
412 495 printf("%s\n", get_table_entry_name(imximage_versions, NULL, version));
413   - printf("Data Size: ");
414   - genimg_print_size(hdr_v2->boot_data.size);
415   - printf("Load Address: %08x\n", (uint32_t)fhdr_v2->boot_data_ptr);
416   - printf("Entry Point: %08x\n", (uint32_t)fhdr_v2->entry);
417   - if (fhdr_v2->csf && (imximage_ivt_offset != UNDEFINED) &&
418   - (imximage_csf_size != UNDEFINED)) {
419   - printf("HAB Blocks: %08x %08x %08x\n",
420   - (uint32_t)fhdr_v2->self, 0,
421   - hdr_v2->boot_data.size - imximage_ivt_offset -
422   - imximage_csf_size);
  496 + printf("Mode: %s\n", plugin ? "PLUGIN" : "DCD");
  497 + if (!plugin) {
  498 + printf("Data Size: ");
  499 + genimg_print_size(hdr_v2->boot_data.size);
  500 + printf("Load Address: %08x\n", (uint32_t)fhdr_v2->boot_data_ptr);
  501 + printf("Entry Point: %08x\n", (uint32_t)fhdr_v2->entry);
  502 + if (fhdr_v2->csf && (imximage_ivt_offset != UNDEFINED) &&
  503 + (imximage_csf_size != UNDEFINED)) {
  504 + printf("HAB Blocks: %08x %08x %08x\n",
  505 + (uint32_t)fhdr_v2->self, 0,
  506 + hdr_v2->boot_data.size - imximage_ivt_offset -
  507 + imximage_csf_size);
  508 + }
  509 + } else {
  510 + imx_header_v2_t *next_hdr_v2;
  511 + flash_header_v2_t *next_fhdr_v2;
  512 +
  513 + /*First Header*/
  514 + printf("Plugin Data Size: ");
  515 + genimg_print_size(hdr_v2->boot_data.size);
  516 + printf("Plugin Code Size: ");
  517 + genimg_print_size(imximage_plugin_size);
  518 + printf("Plugin Load Address: %08x\n", hdr_v2->boot_data.start);
  519 + printf("Plugin Entry Point: %08x\n",
  520 + (uint32_t)fhdr_v2->entry);
  521 +
  522 + /*Second Header*/
  523 + next_hdr_v2 = (imx_header_v2_t *)((char*)hdr_v2 +
  524 + imximage_plugin_size);
  525 + next_fhdr_v2 = &next_hdr_v2->fhdr;
  526 + printf("U-Boot Data Size: ");
  527 + genimg_print_size(next_hdr_v2->boot_data.size);
  528 + printf("U-Boot Load Address: %08x\n", next_hdr_v2->boot_data.start);
  529 + printf("U-Boot Entry Point: %08x\n",
  530 + (uint32_t)next_fhdr_v2->entry);
423 531 }
424 532 }
425 533  
  534 +#ifdef CONFIG_USE_PLUGIN
  535 +static void copy_plugin_code(struct imx_header *imxhdr, char *plugin_file)
  536 +{
  537 + int ifd = -1;
  538 + struct stat sbuf;
  539 + char *plugin_buf = imxhdr->header.hdr_v2.data.plugin_code;
  540 + char *ptr;
  541 +
  542 + ifd = open(plugin_file, O_RDONLY|O_BINARY);
  543 + if (fstat(ifd, &sbuf) < 0) {
  544 + fprintf(stderr, "Can't stat %s: %s\n",
  545 + plugin_file,
  546 + strerror(errno));
  547 + exit(EXIT_FAILURE);
  548 + }
  549 +
  550 + ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, ifd, 0);
  551 + if (ptr == MAP_FAILED) {
  552 + fprintf(stderr, "Can't read %s: %s\n",
  553 + plugin_file,
  554 + strerror(errno));
  555 + exit(EXIT_FAILURE);
  556 + }
  557 +
  558 + if (sbuf.st_size > MAX_PLUGIN_CODE_SIZE) {
  559 + printf("plugin binary size too large\n");
  560 + exit(EXIT_FAILURE);
  561 + }
  562 +
  563 + memcpy(plugin_buf, ptr, sbuf.st_size);
  564 + imximage_plugin_size = sbuf.st_size;
  565 +
  566 + (void) munmap((void *)ptr, sbuf.st_size);
  567 + (void) close(ifd);
  568 +
  569 + imxhdr->header.hdr_v2.boot_data.plugin = 1;
  570 +}
  571 +#endif
  572 +
426 573 static void parse_cfg_cmd(struct imx_header *imxhdr, int32_t cmd, char *token,
427 574 char *name, int lineno, int fld, int dcd_len)
428 575 {
... ... @@ -497,6 +644,11 @@
497 644 if (unlikely(cmd_ver_first != 1))
498 645 cmd_ver_first = 0;
499 646 break;
  647 +#ifdef CONFIG_USE_PLUGIN
  648 + case CMD_PLUGIN:
  649 + copy_plugin_code(imxhdr, token);
  650 + break;
  651 +#endif
500 652 }
501 653 }
502 654  
... ... @@ -542,6 +694,12 @@
542 694 }
543 695 }
544 696 break;
  697 +#ifdef CONFIG_USE_PLUGIN
  698 + case CMD_PLUGIN:
  699 + value = get_cfg_value(token, name, lineno);
  700 + imximage_iram_free_start = value;
  701 + break;
  702 +#endif
545 703 default:
546 704 break;
547 705 }
... ... @@ -2,13 +2,17 @@
2 2 * (C) Copyright 2009
3 3 * Stefano Babic, DENX Software Engineering, sbabic@denx.de.
4 4 *
  5 + * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
  6 + *
5 7 * SPDX-License-Identifier: GPL-2.0+
6 8 */
7 9  
8 10 #ifndef _IMXIMAGE_H_
9 11 #define _IMXIMAGE_H_
10 12  
  13 +#include <config.h>
11 14 #define MAX_HW_CFG_SIZE_V2 220 /* Max number of registers imx can set for v2 */
  15 +#define MAX_PLUGIN_CODE_SIZE (16*1024)
12 16 #define MAX_HW_CFG_SIZE_V1 60 /* Max number of registers imx can set for v1 */
13 17 #define APP_CODE_BARKER 0xB1
14 18 #define DCD_BARKER 0xB17219E9
... ... @@ -64,6 +68,7 @@
64 68 CMD_CHECK_BITS_SET,
65 69 CMD_CHECK_BITS_CLR,
66 70 CMD_CSF,
  71 + CMD_PLUGIN,
67 72 };
68 73  
69 74 enum imximage_fld_types {
... ... @@ -164,7 +169,12 @@
164 169 typedef struct {
165 170 flash_header_v2_t fhdr;
166 171 boot_data_t boot_data;
167   - dcd_v2_t dcd_table;
  172 + union {
  173 + dcd_v2_t dcd_table;
  174 +#ifdef CONFIG_USE_PLUGIN
  175 + char plugin_code[MAX_PLUGIN_CODE_SIZE];
  176 +#endif
  177 + } data;
168 178 } imx_header_v2_t;
169 179  
170 180 /* The header must be aligned to 4k on MX53 for NAND boot */