diff options
Diffstat (limited to 'cfe/cfe/hosttools/mkflashimage.c')
-rw-r--r-- | cfe/cfe/hosttools/mkflashimage.c | 347 |
1 files changed, 347 insertions, 0 deletions
diff --git a/cfe/cfe/hosttools/mkflashimage.c b/cfe/cfe/hosttools/mkflashimage.c new file mode 100644 index 0000000..84ec77c --- /dev/null +++ b/cfe/cfe/hosttools/mkflashimage.c @@ -0,0 +1,347 @@ +/* ********************************************************************* + * Broadcom Common Firmware Environment (CFE) + * + * Flash Image generator File: mkflashimage.c + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + * This program sticks a header on the front of a binary + * file making it suitable for use with the 'flash' command + * in CFE. The header contains the CFE version # and board + * type, a CRC, and other info to help prevent us from + * flashing bad stuff onto a board. + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This software is furnished under license and may be used and + * copied only in accordance with the following terms and + * conditions. Subject to these conditions, you may download, + * copy, install, use, modify and distribute modified or unmodified + * copies of this software in source and/or binary form. No title + * or ownership is transferred hereby. + * + * 1) Any source code used, modified or distributed must reproduce + * and retain this copyright notice and list of conditions + * as they appear in the source file. + * + * 2) No right is granted to use any trade name, trademark, or + * logo of Broadcom Corporation. The "Broadcom Corporation" + * name may not be used to endorse or promote products derived + * from this software without the prior written permission of + * Broadcom Corporation. + * + * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT + * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN + * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + ********************************************************************* */ + +#include <sys/types.h> +#include <sys/stat.h> + +#ifndef _SYS_INT_TYPES_H +typedef unsigned char uint8_t; +typedef unsigned long long uint64_t; +typedef unsigned long uint32_t; +#endif + +#include "cfe_flashimage.h" +#include <fcntl.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + + +static int verbose = 0; +static int big_endian = 1; +static int both_endian = 0; +int mlong64 = 0; +char boardname[32]; + +/* + * This is the offset in the flash where the little-endian image goes + * if we're making a bi-endian flash. + */ + +#define CFE_BIENDIAN_LE_OFFSET (1024*1024) + +static void usage(void) +{ + fprintf(stderr,"usage: mkflashimage [-v] [-EB] [-EL] [-64] [-B boardname] [-V v.v.v] binfile outfile\n"); + fprintf(stderr,"\n"); + fprintf(stderr," mkflashimage [-v] -EX [-64] [-B boardname] [-V v.v.v] BE-binfile LE-binfile outfile\n"); + fprintf(stderr," (this variant used for making bi-endian flash files)\n"); + exit(1); +} + + +static int host_is_little(void) +{ + unsigned long var = 1; + unsigned char *pvar = (unsigned char *) &var; + + return (*pvar == 1); +} + +#define CRC32_POLY 0xEDB88320UL /* CRC-32 Poly */ + +static unsigned int +crc32(const unsigned char *databuf, unsigned int datalen) +{ + unsigned int idx, bit, data, crc = 0xFFFFFFFFUL; + + for (idx = 0; idx < datalen; idx++) { + for (data = *databuf++, bit = 0; bit < 8; bit++, data >>= 1) { + crc = (crc >> 1) ^ (((crc ^ data) & 1) ? CRC32_POLY : 0); + } + } + + return crc; +} + + +void stuff_be32(uint8_t *dest,unsigned int src) +{ + *dest++ = (src >> 24) & 0xFF; + *dest++ = (src >> 16) & 0xFF; + *dest++ = (src >> 8) & 0xFF; + *dest++ = (src >> 0) & 0xFF; +} + +int main(int argc, char *argv[]) +{ + int fh; + int flashsize; + unsigned char *flashcode; + cfe_flashimage_t header; + int host_le; + int majver,minver,ecover; + uint32_t crc; + uint32_t flags; + char *outfile; + + majver = minver = ecover = 0; + boardname[0] = 0; + + while ((argc > 1) && (argv[1][0] == '-')) { + if (strcmp(argv[1],"-v") == 0) { + verbose = 1; + } + else if (strcmp(argv[1],"-EX") == 0) { + if (verbose) fprintf(stderr,"[Image file will be marked Bi-Endian]\n"); + both_endian = 1; + } + else if (strcmp(argv[1],"-EB") == 0) { + if (verbose) fprintf(stderr,"[Image file will be marked Big-Endian]\n"); + big_endian = 1; + } + else if (strcmp(argv[1],"-EL") == 0) { + if (verbose) fprintf(stderr,"[Image file will be marked Little-Endian]\n"); + big_endian = 0; + } + else if (strcmp(argv[1],"-64") == 0) { + if (verbose) fprintf(stderr,"[Image file will be marked 64-bit]\n"); + mlong64 = 1; + } + else if (strcmp(argv[1],"-B") == 0) { + argc--; + argv++; + strcpy(boardname,argv[1]); + if (verbose) fprintf(stderr,"[Board name: %s]\n",boardname); + } + else if (strcmp(argv[1],"-V") == 0) { + argc--; + argv++; + sscanf(argv[1],"%d.%d.%d",&majver,&minver,&ecover); + if (verbose) fprintf(stderr,"[Image version: %d.%d.%d]\n",majver,minver,ecover); + } + else { + fprintf(stderr,"Invalid switch: %s\n",argv[1]); + exit(1); + } + argv++; + argc--; + } + + /* + * We need to swap things around if the host and + * target are different endianness + */ + + host_le = host_is_little(); + + if (verbose) { + fprintf(stderr,"Host is %s-endian.\n",host_le ? "little" : "big"); + if (both_endian) { + fprintf(stderr,"Target is bi-endian.\n"); + } + else { + fprintf(stderr,"Target is %s-endian.\n",big_endian ? "big" : "little"); + } + } + + if ((both_endian && (argc != 4)) || (!both_endian && (argc != 3))) { + usage(); + } + + /* + * Read in the boot file(s) + */ + + flags = 0; + + if (both_endian) { + int be_size; + + flags |= (CFE_IMAGE_EB | CFE_IMAGE_EL); + + if (verbose) fprintf(stderr,"Reading: %s\n",argv[2]); + + fh = open(argv[2],O_RDONLY); + if (fh < 0) { + perror(argv[2]); + } + + flashsize = lseek(fh,0L,SEEK_END); + lseek(fh,0L,SEEK_SET); + + flashcode = malloc(flashsize+CFE_BIENDIAN_LE_OFFSET); + if (flashcode == NULL) { + perror("malloc"); + exit(1); + } + memset(flashcode,0xFF,flashsize+CFE_BIENDIAN_LE_OFFSET); + + if (read(fh,flashcode+CFE_BIENDIAN_LE_OFFSET,flashsize) != flashsize) { + perror("read"); + exit(1); + } + + close(fh); + + if (memcmp(flashcode+CFE_BIENDIAN_LE_OFFSET,CFE_IMAGE_SEAL,4) == 0) { + fprintf(stderr,"File '%s' already has an image header.\n",argv[2]); + exit(1); + } + + flashsize += CFE_BIENDIAN_LE_OFFSET; /* actual file size */ + + if (verbose) fprintf(stderr,"Reading: %s\n",argv[1]); + + fh = open(argv[1],O_RDONLY); + if (fh < 0) { + perror(argv[1]); + exit(1); + } + + be_size = lseek(fh,0L,SEEK_END); + lseek(fh,0L,SEEK_SET); + if (be_size > CFE_BIENDIAN_LE_OFFSET) { + fprintf(stderr,"File '%s' will not fit within first %d bytes of flash image\n", + argv[1],CFE_BIENDIAN_LE_OFFSET); + close(fh); + exit(1); + } + + if (read(fh,flashcode,be_size) != be_size) { + perror("read"); + exit(1); + } + + close(fh); + + outfile = argv[3]; + + } + else { + if (big_endian) flags |= CFE_IMAGE_EB; + else flags |= CFE_IMAGE_EL; + + fh = open(argv[1],O_RDONLY); + if (fh < 0) { + perror(argv[1]); + exit(1); + } + + flashsize = lseek(fh,0L,SEEK_END); + lseek(fh,0L,SEEK_SET); + + flashcode = malloc(flashsize); + if (flashcode == NULL) { + perror("malloc"); + exit(1); + } + memset(flashcode,0,flashsize); + if (read(fh,flashcode,flashsize) != flashsize) { + perror("read"); + exit(1); + } + + close(fh); + + if (memcmp(flashcode,CFE_IMAGE_SEAL,4) == 0) { + fprintf(stderr,"File '%s' already has an image header.\n",argv[1]); + exit(1); + } + + outfile = argv[2]; + } + + + /* + * Construct the flash header + */ + + if (mlong64) flags |= CFE_IMAGE_MLONG64; + crc = crc32(flashcode,flashsize); + + memset(&header,0,sizeof(header)); + memcpy(header.seal,CFE_IMAGE_SEAL,sizeof(header.seal)); + stuff_be32(header.flags,flags); + stuff_be32(header.size,flashsize); + stuff_be32(header.crc,crc); + header.majver = majver; + header.minver = minver; + header.ecover = ecover; + header.miscver = 0; + strcpy(header.boardname,boardname); + + /* + * Now write the output file + */ + + fh = open(outfile,O_RDWR|O_CREAT|O_TRUNC,S_IREAD|S_IWRITE|S_IRGRP|S_IWGRP|S_IROTH); + if (fh < 0) { + perror(outfile); + exit(1); + } + if (write(fh,&header,sizeof(header)) != sizeof(header)) { + perror(outfile); + exit(1); + } + if (write(fh,flashcode,flashsize) != flashsize) { + perror(outfile); + exit(1); + } + + fprintf(stderr,"Wrote %d bytes to %s\n",sizeof(header)+flashsize,outfile); + + close(fh); + + exit(0); + + +} + |