1/* ********************************************************************* 2 * Broadcom Common Firmware Environment (CFE) 3 * 4 * Flash Image Swapper File: swapflashimage.c 5 * 6 * This program updates the header and swaps the data bytes 7 * in files generated for use with the 'flash' command 8 * in CFE. It is only used when in certain cases of flashing 9 * a file intended for the opposite endian of the CFE executing 10 * the flash command, typically when the target flash device 11 * has a bus interface wider than 8 bits. 12 * 13 ********************************************************************* 14 * 15 * Copyright 2000,2001,2002,2003,2005 16 * Broadcom Corporation. All rights reserved. 17 * 18 * This software is furnished under license and may be used and 19 * copied only in accordance with the following terms and 20 * conditions. Subject to these conditions, you may download, 21 * copy, install, use, modify and distribute modified or unmodified 22 * copies of this software in source and/or binary form. No title 23 * or ownership is transferred hereby. 24 * 25 * 1) Any source code used, modified or distributed must reproduce 26 * and retain this copyright notice and list of conditions 27 * as they appear in the source file. 28 * 29 * 2) No right is granted to use any trade name, trademark, or 30 * logo of Broadcom Corporation. The "Broadcom Corporation" 31 * name may not be used to endorse or promote products derived 32 * from this software without the prior written permission of 33 * Broadcom Corporation. 34 * 35 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR 36 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED 37 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 38 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT 39 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN 40 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, 41 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 42 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 43 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 44 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 45 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 46 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF 47 * THE POSSIBILITY OF SUCH DAMAGE. 48 ********************************************************************* */ 49 50#include <sys/types.h> 51#include <unistd.h> 52#include <sys/stat.h> 53 54#ifndef _SYS_INT_TYPES_H 55typedef unsigned char uint8_t; 56typedef unsigned long uint32_t; 57#endif 58 59#include "cfe_flashimage.h" 60#include <fcntl.h> 61#include <stdlib.h> 62#include <stdio.h> 63#include <string.h> 64 65 66#ifndef O_BINARY 67#define O_BINARY 0 68#endif 69 70static void usage(void) 71{ 72 fprintf(stderr,"usage: swapflashimage [-(b|h|w)] flashfile outfile\n"); 73 fprintf(stderr,"\n"); 74 exit(1); 75} 76 77 78#define CRC32_POLY 0xEDB88320UL /* CRC-32 Poly */ 79 80static unsigned int 81crc32(const unsigned char *databuf, unsigned int datalen) 82{ 83 unsigned int idx, bit, data, crc = 0xFFFFFFFFUL; 84 85 for (idx = 0; idx < datalen; idx++) { 86 for (data = *databuf++, bit = 0; bit < 8; bit++, data >>= 1) { 87 crc = (crc >> 1) ^ (((crc ^ data) & 1) ? CRC32_POLY : 0); 88 } 89 } 90 91 return crc; 92} 93 94 95static void stuff_be32(uint8_t *dest,unsigned int src) 96{ 97 *dest++ = (src >> 24) & 0xFF; 98 *dest++ = (src >> 16) & 0xFF; 99 *dest++ = (src >> 8) & 0xFF; 100 *dest++ = (src >> 0) & 0xFF; 101} 102 103static uint32_t get_be32(uint8_t *src) 104{ 105 return (((uint32_t) (src[0] << 24)) | \ 106 ((uint32_t) (src[1] << 16)) | \ 107 ((uint32_t) (src[2] << 8)) | \ 108 ((uint32_t) (src[3] << 0))); 109} 110 111static int flash_validate(cfe_flashimage_t *hdr, uint8_t *code, int insize) 112{ 113 uint32_t size; 114 uint32_t flags; 115 uint32_t hdrcrc; 116 uint32_t calccrc; 117 118 if (memcmp(hdr->seal,CFE_IMAGE_SEAL,sizeof(hdr->seal)) != 0) { 119 printf("Invalid header seal. This is not a CFE flash image.\n"); 120 return -1; 121 } 122 123 printf("Flash image contains CFE version %d.%d.%d for board '%s'\n", 124 hdr->majver,hdr->minver,hdr->ecover,hdr->boardname); 125 126 size = get_be32(hdr->size); 127 flags = get_be32(hdr->flags); 128 hdrcrc = get_be32(hdr->crc); 129 printf("Flash image is %d bytes, flags %08X, CRC %08X\n", 130 (unsigned int)size,(unsigned int)flags,(unsigned int)hdrcrc); 131 132 if (size != insize) { 133 printf("Flash image size is bogus!\n"); 134 return -1; 135 } 136 137 calccrc = crc32(code,size); 138 139 if (calccrc != hdrcrc) { 140 printf("CRC is incorrect. Calculated CRC is %08X\n", 141 (unsigned int)calccrc); 142 return -1; 143 } 144 return 0; 145} 146 147int main(int argc, char *argv[]) 148{ 149 int swapsize; 150 int fh; 151 int flashsize; 152 uint8_t *flashcode; 153 cfe_flashimage_t header; 154 uint32_t crc; 155 char *outfile; 156 int outsize; 157 uint8_t *ptr; 158 int i, j, k; 159 uint8_t t; 160 161 swapsize = 0; 162 while ((argc > 1) && (argv[1][0] == '-')) { 163 if (strcmp(argv[1],"-B") == 0 || strcmp(argv[1],"-b") == 0) { 164 fprintf(stderr,"[Bytes will be not be swapped]\n"); 165 swapsize = 1; 166 } 167 else if (strcmp(argv[1],"-H") == 0 || strcmp(argv[1],"-h") == 0) { 168 fprintf(stderr,"[Bytes within pairs will be swapped]\n"); 169 swapsize = 2; 170 } 171 else if (strcmp(argv[1],"-W") == 0 || strcmp(argv[1],"-w") == 0) { 172 fprintf(stderr,"[Bytes within quads will be swapped]\n"); 173 swapsize = 4; 174 } 175 else { 176 fprintf(stderr,"Invalid switch: %s\n",argv[1]); 177 exit(1); 178 } 179 argv++; 180 argc--; 181 } 182 183 if (swapsize == 0) { 184 fprintf(stderr,"[Bytes within quads will be swapped]\n"); 185 swapsize = 4; 186 } 187 188 /* 189 * We need to swap things around if the host and 190 * target are different endianness 191 */ 192 193 if (argc != 3) { 194 usage(); 195 } 196 197 /* 198 * Read and validate the header first. 199 */ 200 201 fh = open(argv[1],O_RDONLY|O_BINARY); 202 if (fh < 0) { 203 perror(argv[1]); 204 } 205 206 flashsize = lseek(fh,0L,SEEK_END); 207 lseek(fh,0L,SEEK_SET); 208 209 if (read(fh,&header,sizeof(header)) != sizeof(header)) { 210 perror("header"); 211 exit(1); 212 } 213 214 /* 215 * Force the data to be a multiple of the swap unit (or error?). 216 */ 217 218 flashsize -= sizeof(header); 219 outsize = (flashsize + (swapsize-1)) & ~(swapsize-1); 220 221 flashcode = malloc(outsize); 222 if (flashcode == NULL) { 223 perror("malloc"); 224 exit(1); 225 } 226 227 /* 228 * Read in the boot code 229 */ 230 231 if (read(fh,flashcode,flashsize) != flashsize) { 232 perror("read"); 233 exit(1); 234 } 235 236 close(fh); 237 238 if (flash_validate(&header, flashcode, flashsize) < 0) { 239 exit(1); 240 } 241 242 if (flashsize < outsize) 243 memset(flashcode+flashsize,0xFF,outsize-flashsize); 244 flashsize = outsize; 245 246 outfile = argv[2]; 247 248 /* 249 * Perform the requested swap. 250 */ 251 252 ptr = flashcode; 253 for (i = 0; i < flashsize; i += swapsize) { 254 for (j = 0,k = (swapsize-1); j < swapsize/2; j++,k--) { 255 t = *(ptr+j); 256 *(ptr+j) = *(ptr + k); 257 *(ptr+k) = t; 258 } 259 ptr += swapsize; 260 } 261 262 /* 263 * Update the size and CRC in the flash header 264 */ 265 266 crc = crc32(flashcode,flashsize); 267 268 stuff_be32(header.size,flashsize); 269 stuff_be32(header.crc,crc); 270 271 /* 272 * Now write the output file 273 */ 274 275 fh = open(outfile,O_RDWR|O_CREAT|O_TRUNC,S_IREAD|S_IWRITE|S_IRGRP|S_IWGRP|S_IROTH|O_BINARY); 276 if (fh < 0) { 277 perror(outfile); 278 exit(1); 279 } 280 if (write(fh,&header,sizeof(header)) != sizeof(header)) { 281 perror(outfile); 282 exit(1); 283 } 284 if (write(fh,flashcode,flashsize) != flashsize) { 285 perror(outfile); 286 exit(1); 287 } 288 289 fprintf(stderr,"Wrote %d bytes to %s\n", 290 (int)(sizeof(header)+flashsize),outfile); 291 292 close(fh); 293 294 exit(0); 295} 296