1 /*******************************************************************************
2 Copyright (C) Marvell International Ltd. and its affiliates
4 Marvell GPL License Option
6 If you received this File from Marvell, you may opt to use, redistribute and/or
7 modify this File in accordance with the terms and conditions of the General
8 Public License Version 2, June 1991 (the "GPL License"), a copy of which is
9 available along with the File in the license.txt file or by writing to the Free
10 Software Foundation, Inc.
12 THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
13 WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
14 DISCLAIMED. The GPL License provides additional details about this warranty
17 *******************************************************************************/
29 #define _HOST_COMPILER
30 #include "bootstrap_def.h"
37 #define DB(x...) fprintf(stdout, x)
42 /* Global variables */
49 /*******************************************************************************
51 * pre-load the binary image into memory buffer taking into account
55 * buf_in mmapped input file
60 *******************************************************************************/
61 int pre_load_image(USER_OPTIONS
*opt
, char *buf_in
)
65 opt
->image_buf
= malloc(opt
->image_sz
);
66 if (opt
->image_buf
== NULL
)
69 memset(opt
->image_buf
, 0, opt
->image_sz
);
71 if ((opt
->pre_padding
) && (opt
->prepadding_size
)) {
72 memset(opt
->image_buf
, 0x5, opt
->prepadding_size
);
73 offset
= opt
->prepadding_size
;
76 if ((opt
->post_padding
) && (opt
->postpadding_size
))
77 memset(opt
->image_buf
+ opt
->image_sz
- 4 -
78 opt
->postpadding_size
,
79 0xA, opt
->postpadding_size
);
81 memcpy(opt
->image_buf
+ offset
, buf_in
, fs_stat
.st_size
);
84 } /* end of pre_load_image() */
86 /*******************************************************************************
88 * create TWSI header and write it into output stream
95 *******************************************************************************/
96 int build_twsi_header(USER_OPTIONS
*opt
)
99 MV_U8
*tmpTwsi
= NULL
;
102 MV_U32 twsi_size
= 0;
104 tmpTwsi
= malloc(MAX_TWSI_HDR_SIZE
);
105 if (tmpTwsi
== NULL
) {
106 fprintf(stderr
, "TWSI space allocation error!\n");
109 memset(tmpTwsi
, 0xFF, MAX_TWSI_HDR_SIZE
);
110 twsi_reg
= (MV_U32
*)tmpTwsi
;
112 f_twsi
= fopen(opt
->fname_twsi
, "r");
113 if (f_twsi
== NULL
) {
114 fprintf(stderr
, "Failed to open file '%s'\n", opt
->fname_twsi
);
119 for (i
= 0; i
< (MAX_TWSI_HDR_SIZE
/ 4); i
++) {
120 if (EOF
== fscanf(f_twsi
, "%x\n", twsi_reg
))
125 (((*twsi_reg
>> 24) & 0xFF) | ((*twsi_reg
>> 8) & 0xFF00) |
126 ((*twsi_reg
<< 8) & 0xFF0000) |
127 ((*twsi_reg
<< 24) & 0xFF000000));
133 /* Align to size = 512,1024,.. with at least 8 0xFF bytes @ the end */
134 twsi_size
= ((((i
+ 2) * 4) & ~0x1FF) + 0x200);
136 if ((write(f_out
, tmpTwsi
, twsi_size
)) != twsi_size
) {
137 fprintf(stderr
, "Error writing %s file\n", opt
->fname
.out
);
142 } /* end of build_twsi_header() */
144 /*******************************************************************************
146 * create BIN header and write it into output stream
148 * fname - source file name
149 * buffer - Start address of boot image buffer
150 * current_size - number of bytes already placed into the boot image buffer
154 * size of a reg header or 0 on fail
155 *******************************************************************************/
156 int build_reg_header(char *fname
, MV_U8
*buffer
, MV_U32 current_size
)
159 BHR_t
*mainHdr
= (BHR_t
*)buffer
;
160 headExtBHR_t
*headExtHdr
= headExtHdr
=
161 (headExtBHR_t
*)(buffer
+ current_size
);
162 tailExtBHR_t
*prevExtHdrTail
=
163 NULL
; /* tail of the previous extension header */
164 MV_U32 max_bytes_to_write
;
166 (MV_U32
*)(buffer
+ current_size
+ sizeof(headExtBHR_t
));
170 if (mainHdr
->ext
== 255) {
171 fprintf(stderr
, "Maximum number of extensions reached!\n");
175 /* Indicate next header in previous extension if any */
176 if (mainHdr
->ext
!= 0) {
177 prevExtHdrTail
= (tailExtBHR_t
*)(buffer
+ current_size
-
178 sizeof(tailExtBHR_t
));
179 prevExtHdrTail
->nextHdr
= 1;
182 /* Count extension headers in the main header */
185 headExtHdr
->type
= EXT_HDR_TYP_REGISTER
;
186 max_bytes_to_write
= MAX_HEADER_SIZE
- current_size
- EXT_HDR_BASE_SIZE
;
187 f_dram
= fopen(fname
, "r");
188 if (f_dram
== NULL
) {
189 fprintf(stderr
, "Failed to open file '%s'\n", fname
);
194 for (i
= 0; i
< (max_bytes_to_write
/ 8); i
+= 2) {
195 if (fscanf(f_dram
, "%x %x\n", &dram_reg
[i
], &dram_reg
[i
+ 1]) ==
198 else if ((dram_reg
[i
] == 0x0) && (dram_reg
[i
+ 1] == 0x0))
204 if (i
>= (max_bytes_to_write
/ 8)) {
205 fprintf(stderr
, "Registers configure exceeds maximum size\n");
209 /* Include extended header head and tail sizes */
210 tmp_len
= EXT_HDR_BASE_SIZE
+ i
* 4;
211 /* Write total length into the current header fields */
212 EXT_HDR_SET_LEN(headExtHdr
, tmp_len
);
215 } /* end of build_reg_header() */
217 /*******************************************************************************
219 * create BIN header and write it into putput stream
221 * fname - source file name
222 * buffer - Start address of boot image buffer
223 * current_size - number of bytes already placed into the boot image buffer
228 *******************************************************************************/
229 int build_bin_header(char *fname
, MV_U8
*buffer
, MV_U32 current_size
)
232 BHR_t
*mainHdr
= (BHR_t
*)buffer
;
233 headExtBHR_t
*headExtHdr
= (headExtBHR_t
*)(buffer
+ current_size
);
234 tailExtBHR_t
*prevExtHdrTail
=
235 NULL
; /* tail of the previous extension header */
236 MV_U32 max_bytes_to_write
;
238 (MV_U32
*)(buffer
+ current_size
+ sizeof(headExtBHR_t
));
242 if (mainHdr
->ext
== 255) {
243 fprintf(stderr
, "Maximum number of extensions reached!\n");
247 /* Indicate next header in previous extension if any */
248 if (mainHdr
->ext
!= 0) {
249 prevExtHdrTail
= (tailExtBHR_t
*)(buffer
+ current_size
-
250 sizeof(tailExtBHR_t
));
251 prevExtHdrTail
->nextHdr
= 1;
254 /* Count extension headers in main header */
257 headExtHdr
->type
= EXT_HDR_TYP_BINARY
;
258 max_bytes_to_write
= MAX_HEADER_SIZE
- current_size
- EXT_HDR_BASE_SIZE
;
260 f_bin
= fopen(fname
, "r");
262 fprintf(stderr
, "Failed to open file '%s'\n", fname
);
267 for (i
= 0; i
< (max_bytes_to_write
/ 4); i
++) {
268 if (fread(bin_reg
, 1, 4, f_bin
) != 4)
276 if (i
>= (max_bytes_to_write
/ 4)) {
277 fprintf(stderr
, "Binary extension exeeds the maximum size\n");
281 /* Include extended header head and tail sizes */
282 tmp_len
= EXT_HDR_BASE_SIZE
+ i
* 4;
283 /* Write total length into the current header fields */
284 EXT_HDR_SET_LEN(headExtHdr
, tmp_len
);
287 } /* end of build_exec_header() */
289 /*******************************************************************************
291 * build headers block based on user options and write it into output
295 * buf_in mmapped input file
300 *******************************************************************************/
301 int build_headers(USER_OPTIONS
*opt
, char *buf_in
)
304 secExtBHR_t
*secExtHdr
= NULL
;
305 headExtBHR_t
*headExtHdr
= NULL
;
306 tailExtBHR_t
*tailExtHdr
= NULL
;
307 MV_U8
*tmpHeader
= NULL
;
309 MV_U32 header_size
= 0;
310 int size_written
= 0;
311 MV_U32 max_bytes_to_write
;
314 tmpHeader
= malloc(MAX_HEADER_SIZE
);
315 if (tmpHeader
== NULL
) {
316 fprintf(stderr
, "Header space allocation error!\n");
320 memset(tmpHeader
, 0, MAX_HEADER_SIZE
);
321 hdr
= (BHR_t
*)tmpHeader
;
323 switch (opt
->image_type
) {
325 hdr
->blockID
= IBR_HDR_SATA_ID
;
329 hdr
->blockID
= IBR_HDR_UART_ID
;
333 hdr
->blockID
= IBR_HDR_SPI_ID
;
337 hdr
->blockID
= IBR_HDR_MMC_ID
;
341 hdr
->blockID
= IBR_HDR_NAND_ID
;
342 /*hdr->nandEccMode = (MV_U8)opt->nandEccMode; <<== reserved */
343 /*hdr->nandPageSize = (MV_U16)opt->nandPageSize; <<== reserved
345 hdr
->nandBlockSize
= (MV_U8
)opt
->nandBlkSize
;
346 if ((opt
->nandCellTech
== 'S') || (opt
->nandCellTech
== 's'))
347 hdr
->nandTechnology
= MAIN_HDR_NAND_SLC
;
349 hdr
->nandTechnology
= MAIN_HDR_NAND_MLC
;
353 hdr
->blockID
= IBR_HDR_PEX_ID
;
357 hdr
->blockID
= IBR_HDR_I2C_ID
;
362 "Illegal image type %d for header construction!\n",
367 /* Debug print options */
368 if (opt
->flags
& p_OPTION_MASK
)
369 hdr
->flags
&= ~BHR_FLAG_PRINT_EN
;
372 BHR_FLAG_PRINT_EN
; /* Enable printing by default */
374 if (opt
->flags
& b_OPTION_MASK
) {
375 switch (opt
->baudRate
) {
377 hdr
->options
= BHR_OPT_BAUD_2400
;
381 hdr
->options
= BHR_OPT_BAUD_4800
;
385 hdr
->options
= BHR_OPT_BAUD_9600
;
389 hdr
->options
= BHR_OPT_BAUD_19200
;
393 hdr
->options
= BHR_OPT_BAUD_38400
;
397 hdr
->options
= BHR_OPT_BAUD_57600
;
401 hdr
->options
= BHR_OPT_BAUD_115200
;
405 fprintf(stderr
, "Unsupported baud rate - %d!\n",
410 hdr
->options
= BHR_OPT_BAUD_DEFAULT
;
412 /* debug port number */
413 if (opt
->flags
& u_OPTION_MASK
)
414 hdr
->options
|= (opt
->debugPortNum
<< BHR_OPT_UART_PORT_OFFS
) &
415 BHR_OPT_UART_PORT_MASK
;
417 /* debug port MPP setup index */
418 if (opt
->flags
& m_OPTION_MASK
)
419 hdr
->options
|= (opt
->debugPortMpp
<< BHR_OPT_UART_MPPS_OFFS
) &
420 BHR_OPT_UART_MPPS_MASK
;
422 hdr
->destinationAddr
= opt
->image_dest
;
423 hdr
->executionAddr
= (MV_U32
)opt
->image_exec
;
424 hdr
->version
= MAIN_HDR_VERSION
;
425 hdr
->blockSize
= fs_stat
.st_size
;
427 header_size
= sizeof(BHR_t
);
429 /* Update Block size address */
430 if ((opt
->flags
& X_OPTION_MASK
) || (opt
->flags
& Y_OPTION_MASK
)) {
431 /* Align padding to 32 bit */
432 if (opt
->prepadding_size
& 0x3)
433 opt
->prepadding_size
+=
434 (4 - (opt
->prepadding_size
& 0x3));
436 if (opt
->postpadding_size
& 0x3)
437 opt
->postpadding_size
+=
438 (4 - (opt
->postpadding_size
& 0x3));
440 hdr
->blockSize
+= opt
->prepadding_size
+ opt
->postpadding_size
;
443 /* Align the image size to 4 byte boundary */
444 if (hdr
->blockSize
& 0x3) {
445 opt
->bytesToAlign
= (4 - (hdr
->blockSize
& 0x3));
446 hdr
->blockSize
+= opt
->bytesToAlign
;
449 /***************************** TWSI Header
450 * ********************************/
452 /* TWSI header has a special purpose and placed ahead of the main header
454 if (opt
->flags
& M_OPTION_MASK
) {
455 if (opt
->fname_twsi
) {
456 if (build_twsi_header(opt
) != 0)
458 } /* opt->fname_twsi */
459 } /* (opt->flags & M_OPTION_MASK) */
461 /************************** End of TWSI Header
462 * ****************************/
464 /********************** Single Register Header
465 * ***************************/
467 if (opt
->flags
& R_OPTION_MASK
) {
468 if (opt
->fname_dram
) {
469 MV_U32 rhdr_len
= build_reg_header(
470 opt
->fname_dram
, tmpHeader
, header_size
);
474 header_size
+= rhdr_len
;
475 tailExtHdr
= (tailExtBHR_t
*)(tmpHeader
+ header_size
-
476 sizeof(tailExtBHR_t
));
477 } /* if (fname_dram) */
478 } /* if (opts & R_OPTION_MASK) */
480 /******************** End of Single Register Header
481 * ************************/
483 /************************* Single Binary Header
484 * ****************************/
486 if (opt
->flags
& G_OPTION_MASK
) {
487 if (opt
->fname_bin
) {
488 MV_U32 bhdr_len
= build_bin_header(
489 opt
->fname_bin
, tmpHeader
, header_size
);
493 header_size
+= bhdr_len
;
494 tailExtHdr
= (tailExtBHR_t
*)(tmpHeader
+ header_size
-
495 sizeof(tailExtBHR_t
));
496 } /* if (fname_bin) */
497 } /* (opt->flags & G_OPTION_MASK) */
499 /******************* End of Single Binary Header
500 * ***************************/
502 /************************* BIN/REG Headers list
503 * ****************************/
505 if (opt
->flags
& C_OPTION_MASK
) {
506 if (opt
->fname_list
) {
508 char buffer
[PATH_MAX
+ 5];
510 MV_U32 hdr_len
= 0, last
;
511 int (*build_hdr_func
)(char *, MV_U8
*, MV_U32
);
513 f_list
= fopen(opt
->fname_list
, "r");
514 if (f_list
== NULL
) {
515 fprintf(stderr
, "File not found\n");
518 /* read the headers list row by row */
519 while (fgets(buffer
, PATH_MAX
+ 4, f_list
) != NULL
) {
520 /* Ignore strings that are not starting with
522 if (strncmp(buffer
, "BIN", 3) == 0)
523 build_hdr_func
= build_bin_header
;
524 else if (strncmp(buffer
, "REG", 3) == 0)
525 build_hdr_func
= build_reg_header
;
530 /* strip leading spaces/tabs if any */
531 while ((strncmp(fname
, " ", 1) == 0) ||
532 (strncmp(fname
, "\t", 1) == 0))
535 /* strip trailing LF/CR symbols */
536 last
= strlen(fname
) - 1;
537 while ((strncmp(fname
+ last
, "\n", 1) == 0) ||
538 (strncmp(fname
+ last
, "\r", 1) == 0)) {
542 /* Insert required header into the output buffer
544 hdr_len
= build_hdr_func(fname
, tmpHeader
,
549 header_size
+= hdr_len
;
551 (tailExtBHR_t
*)(tmpHeader
+ header_size
-
552 sizeof(tailExtBHR_t
));
556 } /* if (fname_list) */
557 } /* (opt->flags & C_OPTION_MASK) */
559 /********************** End of BIN/REG Headers list
560 * ************************/
562 /* Align the headers block to... */
563 if (opt
->image_type
== IMG_NAND
) {
564 /* ... NAND page size */
566 opt
->nandPageSize
- (header_size
& (opt
->nandPageSize
- 1));
567 } else if ((opt
->image_type
== IMG_SATA
) ||
568 (opt
->image_type
== IMG_MMC
)) {
569 /* ... disk logical block size */
570 header_size
+= 512 - (header_size
& 0x1FF);
571 } else if (opt
->image_type
== IMG_UART
) {
572 /* ... Xmodem packet size */
573 header_size
+= 128 - (header_size
& 0x7F);
575 /* Setup the image source address */
576 if (opt
->image_type
== IMG_SATA
) {
577 if ((opt
->image_source
) && (opt
->image_source
> header_size
))
578 hdr
->sourceAddr
= opt
->image_source
;
581 header_size
>> 9; /* Already aligned to 512 */
583 if ((opt
->image_source
) && (opt
->image_source
> header_size
)) {
584 hdr
->sourceAddr
= opt
->image_source
;
585 opt
->img_gap
= opt
->image_source
- header_size
;
587 /* The source imgage address should be aligned
588 to 32 byte boundary (cache line size).
589 For NAND it should be aligned to 512 bytes boundary
591 The image immediately follows the header block,
592 so if the source address is undefined, it should be
593 derived from the header size.
594 The headers size is always alighed to 4 byte
598 if ((opt
->image_type
== IMG_NAND
) ||
599 (opt
->image_type
== IMG_MMC
))
602 if (header_size
& (boundary
- 1))
604 boundary
- (header_size
& (boundary
- 1));
606 hdr
->sourceAddr
= header_size
+ opt
->img_gap
;
610 /* source address and extension headers number can be written now */
612 "Ext. headers = %d, Header size = %d bytes Hdr-to-Img gap = %d bytes\n",
613 hdr
->ext
, header_size
, opt
->img_gap
);
615 /* If not UART/TWSI image, an extra word for boot image checksum is
617 if ((opt
->image_type
== IMG_FLASH
) || (opt
->image_type
== IMG_NAND
) ||
618 (opt
->image_type
== IMG_MMC
) || (opt
->image_type
== IMG_SATA
) ||
619 (opt
->image_type
== IMG_PEX
) || (opt
->image_type
== IMG_I2C
))
623 "New image size = %#x[%d] Source image size = %#x[%d]\n",
624 hdr
->blockSize
, hdr
->blockSize
, (unsigned int)fs_stat
.st_size
,
625 (int)fs_stat
.st_size
);
627 hdr
->hdrSizeMsb
= (header_size
& 0x00FF0000) >> 16;
628 hdr
->hdrSizeLsb
= header_size
& 0x0000FFFF;
630 opt
->image_sz
= hdr
->blockSize
;
632 /* Load image into memory buffer */
633 if (REGULAR_IMAGE(opt
)) {
634 if (0 != pre_load_image(opt
, buf_in
)) {
635 fprintf(stderr
, "Failed image pre-load!\n");
640 /* Now the headers block checksum should be calculated and wrote in the
642 /* This checksum value should be valid for both secure and unsecure boot
644 /* This value will be checked first before RSA key and signature
646 hdr
->checkSum
= checksum8((void *)hdr
, MAIN_HDR_GET_LEN(hdr
), 0);
648 /* Write to file(s) */
649 if (opt
->header_mode
== HDR_IMG_TWO_FILES
) {
650 /* copy header to output image */
651 size_written
= write(f_header
, tmpHeader
, header_size
);
652 if (size_written
!= header_size
) {
653 fprintf(stderr
, "Error writing %s file\n"
654 , opt
->fname
.hdr_out
);
658 fprintf(stdout
, "====>>>> %s was created\n",
659 opt
->fname_arr
[HDR_FILE_INDX
]);
660 /* if (header_mode == HDR_IMG_TWO_FILES) */
662 /* copy header to output image */
663 size_written
= write(f_out
, tmpHeader
, header_size
);
664 if (size_written
!= header_size
) {
665 fprintf(stderr
, "Error writing %s file\n"
670 } /* if (header_mode != HDR_IMG_TWO_FILES) */
681 } /* end of build_headers() */
683 /*******************************************************************************
685 * create image in bootrom format and write it into output stream
688 * buf_in mmapped input file
693 *******************************************************************************/
694 int build_bootrom_img(USER_OPTIONS
*opt
, char *buf_in
)
696 unsigned int CRC_32
= 0;
697 int tmpSize
= BOOTROM_SIZE
- sizeof(CRC_32
);
699 int size_written
= 0;
702 tmpImg
= malloc(tmpSize
);
706 /* PAD image with Zeros until BOOTROM_SIZE*/
707 memcpy(tmpImg
, buf_in
, fs_stat
.st_size
);
708 memset(tmpImg
+ fs_stat
.st_size
, 0, tmpSize
- fs_stat
.st_size
);
710 /* copy input image to output image */
711 size_written
= write(f_out
, tmpImg
, tmpSize
);
713 /* calculate checsum */
714 CRC_32
= crc32(0, (u32
*)tmpImg
, tmpSize
/ 4);
715 tmpSize
+= sizeof(CRC_32
);
716 printf("Image CRC32 (size = %d) = 0x%08x\n", tmpSize
, CRC_32
);
718 size_written
+= write(f_out
, &CRC_32
, sizeof(CRC_32
));
720 if (size_written
== tmpSize
)
729 } /* end of build_bootrom_img() */
731 /*******************************************************************************
733 * create image in hex format and write it into output stream
736 * buf_in mmapped input file
741 *******************************************************************************/
742 int build_hex_img(USER_OPTIONS
*opt
, char *buf_in
)
744 FILE *f_desc
[2] = {NULL
};
747 int hex_unaligned_len
= 0;
748 unsigned char *hex8
= NULL
;
750 unsigned short *hex16
= NULL
;
751 unsigned short tmp16
;
752 unsigned int *hex32
= NULL
;
754 unsigned int tmp32_low
;
755 int size_written
= 0;
761 /* Calculate aligned image size */
762 hex_len
= fs_stat
.st_size
;
764 alignment
= opt
->hex_width
>> 3;
765 hex_unaligned_len
= fs_stat
.st_size
& (alignment
- 1);
767 if (hex_unaligned_len
) {
768 hex_len
-= hex_unaligned_len
;
769 hex_len
+= alignment
;
772 /* Copy the input image to memory buffer */
773 tmpImg
= malloc(hex_len
);
777 memset(tmpImg
, 0, hex_len
);
778 memcpy(tmpImg
, buf_in
, fs_stat
.st_size
);
780 if (opt
->fname
.hdr_out
)
785 for (i
= 0; i
< files_num
; i
++) {
786 f_desc
[i
] = fopen(opt
->fname_arr
[i
+ 1], "w");
787 if (f_desc
[i
] == NULL
)
791 switch (opt
->hex_width
) {
793 hex8
= (unsigned char *)tmpImg
;
795 for (i
= 0; hex_len
> 0; hex_len
--) {
796 fprintf(f_desc
[i
], "%02X\n", *hex8
++);
803 hex16
= (unsigned short *)tmpImg
;
805 for (; hex_len
> 0; hex_len
-= 2) {
806 fprintf(f_desc
[0], "%04X\n", *hex16
++);
812 hex32
= (unsigned int *)tmpImg
;
814 for (; hex_len
> 0; hex_len
-= 4) {
815 fprintf(f_desc
[0], "%08X\n", *hex32
++);
821 hex32
= (unsigned int *)tmpImg
;
823 for (; hex_len
> 0; hex_len
-= 8) {
824 fprintf(f_desc
[0], "%08X%08X\n", *hex32
++, *hex32
++);
829 } /* switch (opt->hex_width)*/
838 for (i
= 0; i
< files_num
; i
++) {
839 if (f_desc
[i
] != NULL
)
844 } /* end of build_hex_img() */
846 /*******************************************************************************
848 * create image in binary format and write it into output stream
851 * buf_in mmapped input file
856 *******************************************************************************/
857 int build_bin_img(USER_OPTIONS
*opt
, char *buf_in
)
860 FILE *f_desc
[4] = {NULL
};
863 int one_file_len
= 0;
864 int size_written
= 0;
866 int hex_unaligned_len
= 0;
867 unsigned char *hex8
= NULL
;
869 unsigned short *hex16
= NULL
;
870 unsigned short tmp16
;
871 unsigned long *hex32
= NULL
;
873 unsigned long tmp32low
;
879 /* Calculate aligned image size */
880 hex_len
= fs_stat
.st_size
;
882 alignment
= opt
->hex_width
>> 3;
883 hex_unaligned_len
= fs_stat
.st_size
& (alignment
- 1);
885 if (hex_unaligned_len
) {
886 hex_len
-= hex_unaligned_len
;
887 hex_len
+= alignment
;
890 /* prepare output files */
891 if (opt
->fname
.romd
) /*16KB*/
893 else if (opt
->fname
.romc
) /*12KB*/
895 else if (opt
->fname
.hdr_out
)
898 one_file_len
= hex_len
/ files_num
;
900 for (i
= 0; i
< files_num
; i
++) {
901 f_desc
[i
] = fopen(opt
->fname_arr
[i
+ 1], "w");
902 if (f_desc
[i
] == NULL
)
906 /* Copy the input image to memory buffer */
907 tmpImg
= malloc(hex_len
);
911 memset(tmpImg
, 0, (hex_len
));
912 memcpy(tmpImg
, buf_in
, fs_stat
.st_size
);
914 /* Split output image buffer according to width and number of files */
915 switch (opt
->hex_width
) {
917 hex8
= (unsigned char *)tmpImg
;
918 if (files_num
!= 2) {
920 "Must supply two output file names for this width!\n");
924 for (fidx
= 1; (fidx
>= 0) && (hex_len
> 0); fidx
--) {
925 f_ds
= f_desc
[1 - fidx
];
927 for (; hex_len
> (fidx
* one_file_len
); hex_len
--) {
930 for (i
= 0; i
< opt
->hex_width
; i
++) {
932 ((tmp8
& 0x80) >> 7));
944 hex16
= (unsigned short *)tmpImg
;
946 for (; hex_len
> 0; hex_len
-= 2) {
949 for (i
= 0; i
< opt
->hex_width
; i
++) {
950 fprintf(f_desc
[0], "%d",
951 ((tmp16
& 0x8000) >> 15));
954 fprintf(f_desc
[0], "\n");
962 hex32
= (long *)tmpImg
;
964 for (fidx
= files_num
- 1; (fidx
>= 0) && (hex_len
> 0);
966 f_ds
= f_desc
[files_num
- 1 - fidx
];
968 for (; hex_len
> (fidx
* one_file_len
); hex_len
-= 4) {
971 for (i
= 0; i
< opt
->hex_width
; i
++) {
973 ((tmp32
& 0x80000000) >> 31));
984 hex32
= (long *)tmpImg
;
986 for (; hex_len
> 0; hex_len
-= 8) {
990 for (i
= 0; i
< 32; i
++) {
991 fprintf(f_desc
[0], "%ld",
992 ((tmp32
& 0x80000000) >> 31));
995 for (i
= 0; i
< 32; i
++) {
996 fprintf(f_desc
[0], "%ld",
997 ((tmp32low
& 0x80000000) >> 31));
1000 fprintf(f_desc
[0], "\n");
1004 } /* switch (opt->hex_width) */
1013 for (i
= 0; i
< files_num
; i
++) {
1014 if (f_desc
[i
] != NULL
)
1020 } /* end of build_bin_img() */
1022 /*******************************************************************************
1024 * create regular boot image and write it into output stream
1027 * buf_in mmapped input file
1032 *******************************************************************************/
1033 int build_regular_img(USER_OPTIONS
*opt
, char *buf_in
)
1035 int size_written
= 0;
1036 int new_file_size
= 0;
1039 new_file_size
= opt
->image_sz
;
1041 if (0 != opt
->img_gap
) { /* cache line/NAND page/requested offset image
1045 gap_buf
= calloc(opt
->img_gap
, sizeof(MV_U8
));
1046 if (gap_buf
== NULL
) {
1048 "Failed to allocate memory for header to image gap!\n");
1051 size_written
+= write(f_out
, gap_buf
, opt
->img_gap
);
1052 new_file_size
+= opt
->img_gap
;
1056 /* Calculate checksum and copy it to the image tail */
1057 chsum32
= checksum32((void *)opt
->image_buf
, opt
->image_sz
- 4, 0);
1058 memcpy(opt
->image_buf
+ opt
->image_sz
- 4, &chsum32
, 4);
1060 /* copy input image to output image */
1061 size_written
+= write(f_out
, opt
->image_buf
, opt
->image_sz
);
1062 free(opt
->image_buf
);
1064 if (new_file_size
!= size_written
) {
1065 fprintf(stderr
, "Size mismatch between calculated/written\n");
1070 } /* end of build_other_img() */
1072 /*******************************************************************************
1074 * handle input and output file options, read and verify RSA and AES
1082 ******************************************************************************/
1083 int process_image(USER_OPTIONS
*opt
)
1087 char *buf_in
= NULL
;
1090 /* check if the output image exist */
1092 for (i
= IMG_FILE_INDX
; i
<= HDR_FILE_INDX
; i
++) {
1093 if (opt
->fname_arr
[i
]) {
1096 if (0 == stat(opt
->fname_arr
[i
], &fs_stat
)) {
1098 /* ask for overwrite permissions */
1100 "File '%s' already exist! Overwrite it (Y/n)?",
1103 if ((c
== 'N') || (c
== 'n')) {
1104 printf("exit.. nothing done.\n");
1106 } else if ((c
== 'Y') || (c
== 'y')) {
1107 /* additional read is needed for Enter
1116 /* open input image file and check if it's size is OK */
1117 if (opt
->header_mode
!= HDR_ONLY
) {
1118 f_in
= open(opt
->fname
.in
, O_RDONLY
| O_BINARY
);
1120 fprintf(stderr
, "File '%s' not found\n", opt
->fname
.in
);
1123 /* get the size of the input image */
1124 if (0 != fstat(f_in
, &fs_stat
)) {
1125 fprintf(stderr
, "fstat failed for file: '%s' err=%d\n",
1126 opt
->fname
.in
, err
);
1129 /*Check the source image size for limited output storage
1131 if (opt
->image_type
== IMG_BOOTROM
) {
1132 int max_img_size
= BOOTROM_SIZE
- sizeof(u32
);
1134 if (fs_stat
.st_size
> max_img_size
) {
1136 "ERROR : source image is bigger than %d bytes\n",
1141 /* map the input image */
1143 mmap(0, fs_stat
.st_size
, PROT_READ
, MAP_SHARED
, f_in
, 0);
1145 fprintf(stderr
, "Error mapping %s file\n",
1151 /* open the output image file */
1152 if (override
[IMG_FILE_INDX
] == 0)
1153 f_out
= open(opt
->fname
.out
,
1154 O_RDWR
| O_TRUNC
| O_CREAT
| O_BINARY
, 0666);
1156 f_out
= open(opt
->fname
.out
, O_RDWR
| O_BINARY
);
1159 fprintf(stderr
, "Error opening %s file\n", opt
->fname
.out
);
1163 /* open the output header file */
1164 if (opt
->header_mode
== HDR_IMG_TWO_FILES
) {
1165 if (override
[HDR_FILE_INDX
] == 0)
1167 open(opt
->fname
.hdr_out
,
1168 O_RDWR
| O_TRUNC
| O_CREAT
| O_BINARY
, 0666);
1170 f_header
= open(opt
->fname
.hdr_out
, O_RDWR
| O_BINARY
);
1172 if (f_header
== -1) {
1173 fprintf(stderr
, "Error opening %s file\n",
1174 opt
->fname
.hdr_out
);
1179 /* Image Header(s) */
1180 if (opt
->header_mode
!= IMG_ONLY
) {
1181 if (0 != build_headers(opt
, buf_in
))
1186 if (opt
->header_mode
!= HDR_ONLY
) {
1187 if (opt
->image_type
== IMG_BOOTROM
)
1188 err
= build_bootrom_img(opt
, buf_in
);
1189 else if (opt
->image_type
== IMG_HEX
)
1190 err
= build_hex_img(opt
, buf_in
);
1191 else if (opt
->image_type
== IMG_BIN
)
1192 err
= build_bin_img(opt
, buf_in
);
1194 err
= build_regular_img(opt
, buf_in
);
1197 fprintf(stderr
, "Error writing %s file\n"
1202 fprintf(stdout
, "====>>>> %s was created\n",
1203 opt
->fname_arr
[IMG_FILE_INDX
]);
1205 } /* if (opt->header_mode != HDR_ONLY) */
1216 munmap((void *)buf_in
, fs_stat
.st_size
);
1223 } /* end of process_image() */
1225 /*******************************************************************************
1227 * print command switches and their description
1234 *******************************************************************************/
1235 void print_usage(void)
1238 "==============================================================================================\n\n");
1239 printf("Marvell doimage Tool version %s\n", VERSION_NUMBER
);
1240 printf("Supported SoC devices:\n\t%s\n", PRODUCT_SUPPORT
);
1242 "==============================================================================================\n\n");
1245 "doimage <mandatory_opt> [other_options] [bootrom_output] <image_in> <image_out> [header_out]\n\n");
1247 printf("<mandatory_opt> - can be one or more of the following:\n");
1249 "==============================================================================================\n\n");
1252 "-T image_type: sata\\uart\\flash\\bootrom\\nand\\hex\\bin\\pex\\mmc\n");
1253 printf("-D image_dest: image destination in dram (in hex)\n");
1254 printf("-E image_exec: execution address in dram (in hex)\n");
1256 " if image_type is 'flash' and image_dest is 0xffffffff\n");
1257 printf(" then execution address on the flash\n");
1259 "-S image_source: if image_type is sata then the starting sector of\n");
1260 printf(" the source image on the disk\n");
1262 " if image_type is flash\\nand then the starting offset of\n");
1264 " the source image at the flash - optional for flash\\nand\n");
1265 printf("-W hex_width : HEX file width, can be 8,16,32,64\n");
1267 "-M twsi_file: ascii file name that contains the I2C init regs set by h/w.\n");
1268 printf(" this is used in i2c boot only\n");
1270 printf("\nThe following options are mandatory for NAND image type:\n");
1272 "-----------------------------------------------------------------------------------------------\n\n");
1275 "-L nand_blk_size:NAND block size in KBytes (decimal int in range 64-16320)\n");
1277 " This parameter is ignored for flashes with 512B pages\n");
1279 " Such small page flashes always use 16K block sizes\n");
1281 "-N nand_cell_typ:NAND cell technology type (char: M for MLC, S for SLC)\n");
1283 "-P nand_pg_size: NAND page size: (decimal 512, 2048, 4096 or 8192)\n");
1286 "-G exec_file: ascii file name that contains binary routine (ARM 5TE THUMB)\n");
1288 " to run before the bootloader image execution.\n");
1290 " The routine must contain an appropriate code for saving\n");
1292 " all registers at the routine start and restore them\n");
1293 printf(" before return from the routine\n");
1295 "-R dram_file: ascii file name that contains the list of dram regs\n");
1297 "-C hdrs_file: ascii file name that defines BIN/REG headers order and their sources\n");
1298 printf("-X pre_padding_size (hex)\n");
1299 printf("-Y post_padding_size (hex)\n");
1300 printf("-H header_mode: Header mode, can be:\n");
1302 " -H 1 : will create one file (image_out) for header and image\n");
1304 " -H 2 : will create two files, (image_out) for image , (header_out) for header\n");
1306 " -H 3 : will create one file (image_out) for header only\n");
1308 " -H 4 : will create one file (image_out) for image only\n");
1311 "\n[bootrom_output] - optional and can be one or more of the following:\n");
1313 "==============================================================================================\n\n");
1316 "-p Disable BootROM messages output to UART port (enabled by default)\n");
1317 printf("-b baudrate Set BootROM debug port UART baudrate\n");
1319 " value = 2400,4800,9600,19200,38400,57600,115200 (use default baudrate is omitted)\n");
1321 "-u port_num Set BootROM debug port UART number value = 0-3 (use default port if omitted)\n");
1323 "-m mpp_config Select BootROM debug port MPPs configuration value = 0-7 (BootROM-specific)\n");
1325 printf("\nCommand examples:\n\n");
1327 printf("doimage -T hex -W width image_in image_out\n");
1328 printf("doimage -T bootrom image_in image_out\n");
1329 printf("doimage -T resume image_in image_out\n");
1330 printf("doimage -T sata -S sector -D image_dest -E image_exec\n");
1331 printf(" [other_options] image_in image_out header_out\n\n");
1332 printf("doimage -T flash -D image_dest -E image_exec [-S address]\n");
1333 printf(" [other_options] image_in image_out\n\n");
1334 printf("doimage -T pex -D image_dest -E image_exec\n");
1335 printf(" [other_options] image_in image_out\n\n");
1337 "doimage -T nand -D image_dest -E image_exec [-S address] -P page_size\n");
1338 printf(" -L 2 -N S [other_options] image_in image_out\n\n");
1339 printf("doimage -T uart -D image_dest -E image_exec\n");
1340 printf(" [other_options] image_in image_out\n\n");
1341 printf("doimage -T pex -D image_dest -E image_exec\n");
1342 printf(" [other_options] image_in image_out\n\n");
1345 } /* end of print_usage() */
1347 /*******************************************************************************
1349 * calculate 8-bit checksum of memory buffer
1351 * start buffer start
1353 * csum initial checksum value
1357 * 8-bit buffer checksum
1358 *******************************************************************************/
1359 MV_U8
checksum8(void *start
, MV_U32 len
, MV_U8 csum
)
1361 register MV_U8 sum
= csum
;
1363 volatile MV_U8
*startp
= (volatile MV_U8
*)start
;
1366 sum
+= *(MV_U8
*)startp
;
1373 } /* end of checksum8 */
1375 /*******************************************************************************
1377 * calculate 32-bit checksum of memory buffer
1379 * start buffer start
1381 * csum initial checksum value
1385 * 32-bit buffer checksum
1386 *******************************************************************************/
1387 MV_U32
checksum32(void *start
, MV_U32 len
, MV_U32 csum
)
1389 register MV_U32 sum
= csum
;
1390 volatile MV_U32
*startp
= (volatile MV_U32
*)start
;
1393 sum
+= *(MV_U32
*)startp
;
1401 } /* *end of checksum32() */
1403 /*******************************************************************************
1407 * crc_table CRC table location
1409 * crc_table CRC table location
1412 *******************************************************************************/
1413 void make_crc_table(MV_U32
*crc_table
)
1419 /* terms of polynomial defining this crc (except x^32): */
1420 static const MV_U8 p
[] = {0, 1, 2, 4, 5, 7, 8,
1421 10, 11, 12, 16, 22, 23, 26};
1423 /* make exclusive-or pattern from polynomial (0xedb88320L) */
1425 for (n
= 0; n
< sizeof(p
) / sizeof(MV_U8
); n
++)
1426 poly
|= 1L << (31 - p
[n
]);
1428 for (n
= 0; n
< 256; n
++) {
1430 for (k
= 0; k
< 8; k
++)
1431 c
= c
& 1 ? poly
^ (c
>> 1) : c
>> 1;
1435 } /* end of make_crc_table */
1437 #define DO1(buf) (crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8))
1438 #define DO2(buf) do { \
1442 #define DO4(buf) do { \
1446 #define DO8(buf) do { \
1451 /*******************************************************************************
1453 * calculate CRC32 on memory buffer
1455 * crc initial CRC value
1461 * CRC32 of the memory buffer
1462 *******************************************************************************/
1463 MV_U32
crc32(MV_U32 crc
, volatile MV_U32
*buf
, MV_U32 len
)
1465 MV_U32 crc_table
[256];
1467 /* Create the CRC table */
1468 make_crc_table(crc_table
);
1470 crc
= crc
^ 0xffffffffL
;
1482 return crc
^ 0xffffffffL
;
1484 } /* end of crc32() */
1486 /*******************************************************************************
1488 * select image options by the image name
1490 * img_name image name
1494 * 0 on success, 1 if image name is invalid
1495 *******************************************************************************/
1496 int select_image(char *img_name
, USER_OPTIONS
*opt
)
1500 static IMG_MAP img_map
[] = {
1501 {IMG_SATA
, "sata", D_OPTION_MASK
| T_OPTION_MASK
| E_OPTION_MASK
},
1502 {IMG_UART
, "uart", D_OPTION_MASK
| T_OPTION_MASK
| E_OPTION_MASK
},
1503 {IMG_FLASH
, "flash", D_OPTION_MASK
| T_OPTION_MASK
| E_OPTION_MASK
},
1504 {IMG_MMC
, "mmc", D_OPTION_MASK
| T_OPTION_MASK
| E_OPTION_MASK
},
1505 {IMG_BOOTROM
, "bootrom", T_OPTION_MASK
},
1506 {IMG_NAND
, "nand", D_OPTION_MASK
| T_OPTION_MASK
| E_OPTION_MASK
|
1507 L_OPTION_MASK
| N_OPTION_MASK
|
1509 {IMG_HEX
, "hex", T_OPTION_MASK
| W_OPTION_MASK
},
1510 {IMG_BIN
, "bin", T_OPTION_MASK
| W_OPTION_MASK
},
1511 {IMG_PEX
, "pex", D_OPTION_MASK
| T_OPTION_MASK
| E_OPTION_MASK
},
1513 D_OPTION_MASK
| T_OPTION_MASK
| E_OPTION_MASK
| M_OPTION_MASK
},
1516 for (i
= 0; i
< ARRAY_SIZE(img_map
); i
++) {
1517 if (strcmp(img_name
, img_map
[i
].img_name
) == 0) {
1518 opt
->image_type
= img_map
[i
].img_type
;
1519 opt
->req_flags
= img_map
[i
].img_opt
;
1526 } /* *end of select_image() */
1528 /*******************************************************************************
1530 *******************************************************************************/
1531 int main(int argc
, char **argv
)
1533 USER_OPTIONS options
;
1534 int optch
; /* command-line option char */
1535 static char optstring
[] =
1536 "T:D:E:X:Y:S:P:W:H:R:M:G:L:N:C:b:u:m:p";
1542 memset(&options
, 0, sizeof(USER_OPTIONS
));
1543 options
.header_mode
= HDR_IMG_ONE_FILE
;
1545 fprintf(stdout
, "\n");
1547 while ((optch
= getopt(argc
, argv
, optstring
)) != -1) {
1548 char *endptr
= NULL
;
1551 case 'T': /* image type */
1552 if ((select_image(optarg
, &options
) != 0) ||
1553 (options
.flags
& T_OPTION_MASK
))
1555 options
.flags
|= T_OPTION_MASK
;
1558 case 'D': /* image destination */
1559 options
.image_dest
= strtoul(optarg
, &endptr
, 16);
1560 if (*endptr
|| (options
.flags
& D_OPTION_MASK
))
1562 options
.flags
|= D_OPTION_MASK
;
1563 DB("Image destination address %#x\n",
1564 options
.image_dest
);
1567 case 'E': /* image execution */
1568 options
.image_exec
= strtoul(optarg
, &endptr
, 16);
1569 if (*endptr
|| (options
.flags
& E_OPTION_MASK
))
1571 options
.flags
|= E_OPTION_MASK
;
1572 DB("Image execution address %#x\n", options
.image_exec
);
1575 case 'X': /* Pre - Padding */
1576 options
.prepadding_size
= strtoul(optarg
, &endptr
, 16);
1577 if (*endptr
|| (options
.flags
& X_OPTION_MASK
))
1579 options
.pre_padding
= 1;
1580 options
.flags
|= X_OPTION_MASK
;
1581 DB("Pre-pad image by %#x bytes\n",
1582 options
.prepadding_size
);
1585 case 'Y': /* Post - Padding */
1586 options
.postpadding_size
= strtoul(optarg
, &endptr
, 16);
1587 if (*endptr
|| (options
.flags
& Y_OPTION_MASK
))
1589 options
.post_padding
= 1;
1590 options
.flags
|= Y_OPTION_MASK
;
1591 DB("Post-pad image by %#x bytes\n",
1592 options
.postpadding_size
);
1595 case 'S': /* starting sector */
1596 options
.image_source
= strtoul(optarg
, &endptr
, 16);
1597 if (*endptr
|| (options
.flags
& S_OPTION_MASK
))
1599 options
.flags
|= S_OPTION_MASK
;
1600 DB("Image start sector (image source) %#x\n",
1601 options
.image_source
);
1604 case 'P': /* NAND Page Size */
1605 options
.nandPageSize
= strtoul(optarg
, &endptr
, 10);
1606 if (*endptr
|| (options
.flags
& P_OPTION_MASK
))
1608 options
.flags
|= P_OPTION_MASK
;
1609 DB("NAND page size %d bytes\n", options
.nandPageSize
);
1612 case 'C': /* headers definition filename */
1613 options
.fname_list
= optarg
;
1614 if (options
.flags
& C_OPTION_MASK
)
1616 options
.flags
|= C_OPTION_MASK
;
1617 DB("Headers definition file name %s\n",
1618 options
.fname_list
);
1621 case 'W': /* HEX file width */
1622 options
.hex_width
= strtoul(optarg
, &endptr
, 10);
1623 if (*endptr
|| (options
.flags
& W_OPTION_MASK
))
1625 options
.flags
|= W_OPTION_MASK
;
1626 DB("HEX file width %d bytes\n", options
.hex_width
);
1629 case 'H': /* Header file mode */
1630 options
.header_mode
= strtoul(optarg
, &endptr
, 10);
1631 if (*endptr
|| (options
.flags
& H_OPTION_MASK
))
1633 options
.flags
|= H_OPTION_MASK
;
1634 DB("Header file mode is %d\n", options
.header_mode
);
1637 case 'R': /* dram file */
1638 options
.fname_dram
= optarg
;
1639 if (options
.flags
& R_OPTION_MASK
)
1641 options
.flags
|= R_OPTION_MASK
;
1642 DB("Registers header file name %s\n",
1643 options
.fname_dram
);
1646 case 'M': /* TWSI file */
1647 options
.fname_twsi
= optarg
;
1648 if (options
.flags
& M_OPTION_MASK
)
1650 options
.flags
|= M_OPTION_MASK
;
1651 DB("TWSI header file name %s\n", options
.fname_twsi
);
1654 case 'G': /* binary file */
1655 options
.fname_bin
= optarg
;
1656 if (options
.flags
& G_OPTION_MASK
)
1658 options
.flags
|= G_OPTION_MASK
;
1659 DB("Binary header file name %s\n", options
.fname_bin
);
1662 case 'L': /* NAND block size */
1663 options
.nandBlkSize
= strtoul(optarg
, &endptr
, 10) / 64;
1664 if (*endptr
|| (options
.flags
& L_OPTION_MASK
))
1666 options
.flags
|= L_OPTION_MASK
;
1667 DB("NAND block size %d\n", options
.nandBlkSize
);
1670 case 'N': /* NAND cell technology */
1671 options
.nandCellTech
= optarg
[0];
1672 if (options
.flags
& N_OPTION_MASK
)
1674 options
.flags
|= N_OPTION_MASK
;
1675 DB("NAND cell technology %c\n", options
.nandCellTech
);
1678 case 'p': /* BootROM debug output */
1679 if (options
.flags
& p_OPTION_MASK
)
1681 options
.flags
|= p_OPTION_MASK
;
1682 DB("BootROM debug output disabled\n");
1685 case 'b': /* BootROM debug port baudrate */
1686 options
.baudRate
= strtoul(optarg
, &endptr
, 10);
1687 if (*endptr
|| (options
.flags
& b_OPTION_MASK
))
1689 options
.flags
|= b_OPTION_MASK
;
1690 DB("BootROM debug port baudrate %d\n",
1694 case 'u': /* BootROM debug port number */
1695 options
.debugPortNum
= strtoul(optarg
, &endptr
, 10);
1696 if (*endptr
|| (options
.flags
& u_OPTION_MASK
))
1698 options
.flags
|= u_OPTION_MASK
;
1699 DB("BootROM debug port number %d\n",
1700 options
.debugPortNum
);
1703 case 'm': /* BootROM debug port MPP settings */
1704 options
.debugPortMpp
= strtoul(optarg
, &endptr
, 10);
1705 if (*endptr
|| (options
.flags
& m_OPTION_MASK
))
1707 options
.flags
|= m_OPTION_MASK
;
1708 DB("BootROM debug port MPP setup # %d\n",
1709 options
.debugPortMpp
);
1715 } /* parse command-line options */
1717 /* assign file names */
1718 for (i
= 0; (optind
< argc
) && (i
< ARRAY_SIZE(options
.fname_arr
));
1720 options
.fname_arr
[i
] = argv
[optind
];
1721 DB("File @ array index %d is %s (option index is %d)\n", i
,
1722 argv
[optind
], optind
);
1723 /* verify that all file names are different */
1724 for (k
= 0; k
< i
; k
++) {
1725 if (0 == strcmp(options
.fname_arr
[i
],
1726 options
.fname_arr
[k
])) {
1728 "\nError: Input and output images can't be the same\n");
1734 if (!(options
.flags
& T_OPTION_MASK
))
1737 /* verify HEX/BIN file width selection to be valid */
1738 if ((options
.flags
& W_OPTION_MASK
) && (options
.hex_width
!= 8) &&
1739 (options
.hex_width
!= 16) && (options
.hex_width
!= 32) &&
1740 (options
.hex_width
!= 64))
1742 /* BootROM test images, no header is needed */
1743 if ((options
.image_type
== IMG_BOOTROM
) ||
1744 (options
.image_type
== IMG_HEX
) || (options
.image_type
== IMG_BIN
))
1745 options
.header_mode
= IMG_ONLY
;
1747 if (options
.header_mode
== IMG_ONLY
) {
1748 /* remove unneeded options */
1749 options
.req_flags
&=
1750 ~(D_OPTION_MASK
| E_OPTION_MASK
| S_OPTION_MASK
|
1751 R_OPTION_MASK
| P_OPTION_MASK
| L_OPTION_MASK
|
1755 if (options
.req_flags
!= (options
.flags
& options
.req_flags
))
1758 if ((options
.flags
& L_OPTION_MASK
) &&
1759 ((options
.nandBlkSize
> 255) ||
1760 ((options
.nandBlkSize
== 0) && (options
.nandPageSize
!= 512)))) {
1761 fprintf(stderr
, "Error: wrong NAND block size %d!\n\n\n\n\n",
1762 64 * options
.nandBlkSize
);
1766 if ((options
.flags
& N_OPTION_MASK
) && (options
.nandCellTech
!= 'S') &&
1767 (options
.nandCellTech
!= 'M') && (options
.nandCellTech
!= 's') &&
1768 (options
.nandCellTech
!= 'm')) {
1770 "Error: Wrong NAND cell technology type!\n\n\n\n\n");
1774 return process_image(&options
);
1781 } /* end of main() */