GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / cfe / cfe / hosttools / mkbootimage.c
blobe1b94d59701c050990d798bf0512bfae75b9644a
1 /* *********************************************************************
2 * Broadcom Common Firmware Environment (CFE)
4 * Boot block generator File: mkbootimage.c
5 *
6 * Author: Mitch Lichtenberg (mpl@broadcom.com)
7 *
8 * This program converts a binary file (bootstrap program)
9 * into a boot block by prepending the boot block sector
10 * to the program. It generates the appropriate
11 * boot block checksums and such. The resulting file may
12 * be used by installboot (for example) to put into a disk
13 * image for the simulator.
15 *********************************************************************
17 * Copyright 2000,2001,2002,2003
18 * Broadcom Corporation. All rights reserved.
20 * This software is furnished under license and may be used and
21 * copied only in accordance with the following terms and
22 * conditions. Subject to these conditions, you may download,
23 * copy, install, use, modify and distribute modified or unmodified
24 * copies of this software in source and/or binary form. No title
25 * or ownership is transferred hereby.
27 * 1) Any source code used, modified or distributed must reproduce
28 * and retain this copyright notice and list of conditions
29 * as they appear in the source file.
31 * 2) No right is granted to use any trade name, trademark, or
32 * logo of Broadcom Corporation. The "Broadcom Corporation"
33 * name may not be used to endorse or promote products derived
34 * from this software without the prior written permission of
35 * Broadcom Corporation.
37 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
38 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
39 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
40 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
41 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
42 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
43 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
44 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
45 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
46 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
47 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
48 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
49 * THE POSSIBILITY OF SUCH DAMAGE.
50 ********************************************************************* */
52 #include <sys/types.h>
53 #include <sys/stat.h>
55 typedef unsigned long long uint64_t;
56 typedef unsigned long uint32_t;
58 #include "cfe_bootblock.h"
59 #include <fcntl.h>
60 #include <stdlib.h>
61 #include <stdio.h>
62 #include <string.h>
64 #define roundup(x,align) (((x)+(align)-1)&~((align)-1))
65 #define howmany(x,align) (((x)+(align)-1)/(align))
67 static int verbose = 0;
68 static int big_endian = 1;
69 static int swapflg = 1;
70 static unsigned long sector_offset = 0;
72 static void usage(void)
74 fprintf(stderr,"usage: mkbootimage [-S <sector offset>] [-v] [-EB] [-EL] inputfile outputfile\n");
75 exit(1);
78 static void bswap32(uint32_t *ptr)
80 unsigned char b;
81 unsigned char *bptr;
83 if (swapflg) {
84 bptr = (unsigned char *) ptr;
85 b = bptr[0]; bptr[0] = bptr[3]; bptr[3] = b;
86 b = bptr[1]; bptr[1] = bptr[2]; bptr[2] = b;
90 static void bswap64(uint64_t *ptr)
92 unsigned char b;
93 unsigned char *bptr;
95 bptr = (unsigned char *) ptr;
97 if (swapflg) {
98 b = bptr[0]; bptr[0] = bptr[7]; bptr[7] = b;
99 b = bptr[1]; bptr[1] = bptr[6]; bptr[6] = b;
100 b = bptr[2]; bptr[2] = bptr[5]; bptr[5] = b;
101 b = bptr[3]; bptr[3] = bptr[4]; bptr[4] = b;
106 static void bswap_bootblock(struct boot_block *bb)
108 int idx;
110 for (idx = 59; idx <= 63; idx++) {
111 bswap64(&(bb->bb_data[idx]));
115 static void do_checksum(void *ptr,int length,uint32_t *csptr,int swap)
117 uint32_t *p;
118 uint32_t chksum = 0;
119 uint32_t d;
121 p = (uint32_t *) ptr;
123 length /= sizeof(uint32_t);
125 while (length) {
126 d = *p;
127 if (swap) bswap32(&d);
128 chksum += d;
129 p++;
130 length--;
133 if (swap) bswap32(&chksum);
135 *csptr = chksum;
139 static void dumpbootblock(struct boot_block *bb)
141 int idx;
143 fprintf(stderr,"Magic Number: %016llX\n",
144 bb->bb_magic);
145 fprintf(stderr,"Boot code offset: %llu\n",
146 (unsigned long long)bb->bb_secstart);
147 fprintf(stderr,"Boot code size: %u\n",
148 (uint32_t) (bb->bb_secsize & BOOT_SECSIZE_MASK));
149 fprintf(stderr,"Header checksum: %08X\n",
150 (uint32_t) (bb->bb_hdrinfo & BOOT_HDR_CHECKSUM_MASK));
151 fprintf(stderr,"Header version: %d\n",
152 (uint32_t) ((bb->bb_hdrinfo & BOOT_HDR_VER_MASK) >> BOOT_HDR_VER_SHIFT));
153 fprintf(stderr,"Data checksum: %08X\n",
154 (uint32_t) ((bb->bb_secsize & BOOT_DATA_CHECKSUM_MASK) >> BOOT_DATA_CHECKSUM_SHIFT));
155 fprintf(stderr,"Architecture info: %08X\n",
156 (uint32_t) (bb->bb_archinfo & BOOT_ARCHINFO_MASK));
157 fprintf(stderr,"\n");
159 for (idx = 59; idx <= 63; idx++) {
160 fprintf(stderr,"Word %d = %016llX\n",idx,bb->bb_data[idx]);
164 static int host_is_little(void)
166 unsigned long var = 1;
167 unsigned char *pvar = (unsigned char *) &var;
169 return (*pvar == 1);
172 int main(int argc, char *argv[])
174 int fh;
175 long bootsize;
176 long bootbufsize;
177 unsigned char *bootcode;
178 struct boot_block bootblock;
179 uint32_t datacsum,hdrcsum;
180 int host_le;
182 while ((argc > 1) && (argv[1][0] == '-')) {
183 if (strcmp(argv[1],"-v") == 0) {
184 verbose = 1;
186 else if (strcmp(argv[1],"-EB") == 0) {
187 big_endian = 1;
189 else if (strcmp(argv[1],"-EL") == 0) {
190 big_endian = 0;
192 else if (strcmp(argv[1],"-S") == 0) {
193 char *tmp_ptr;
194 argv++;
195 argc--;
196 if (argc == 1) {
197 fprintf(stderr,"-S requires an argument\n");
198 exit(1);
200 sector_offset = strtoul(argv[1], &tmp_ptr, 0);
201 if (*tmp_ptr) {
202 fprintf(stderr,"Unable to parse %s as a sector offset\n", argv[1]);
203 exit(1);
206 else {
207 fprintf(stderr,"Invalid switch: %s\n",argv[1]);
208 exit(1);
210 argv++;
211 argc--;
215 * We need to swap things around if the host and
216 * target are different endianness
219 swapflg = 0;
220 host_le = host_is_little();
222 if (big_endian && host_is_little()) swapflg = 1;
223 if ((big_endian == 0) && !(host_is_little())) swapflg = 1;
225 fprintf(stderr,"Host is %s-endian.\n",host_le ? "little" : "big");
226 fprintf(stderr,"Target is %s-endian.\n",big_endian ? "big" : "little");
228 if (argc != 3) {
229 usage();
233 * Read in the boot file
236 fh = open(argv[1],O_RDONLY);
237 if (fh < 0) {
238 perror(argv[1]);
241 bootsize = lseek(fh,0L,SEEK_END);
242 lseek(fh,0L,SEEK_SET);
244 bootbufsize = roundup(bootsize,BOOT_BLOCK_BLOCKSIZE);
246 bootcode = malloc(bootbufsize);
247 if (bootcode == NULL) {
248 perror("malloc");
249 exit(1);
251 memset(bootcode,0,bootbufsize);
252 if (read(fh,bootcode,bootsize) != bootsize) {
253 perror("read");
254 exit(1);
257 close(fh);
260 * Construct the boot block
264 /* Checksum the boot code */
265 do_checksum(bootcode,bootbufsize,&datacsum,1);
266 bswap32(&datacsum);
269 /* fill in the boot block fields, and checksum the boot block */
270 bootblock.bb_magic = BOOT_MAGIC_NUMBER;
271 bootblock.bb_hdrinfo = (((uint64_t) BOOT_HDR_VERSION) << BOOT_HDR_VER_SHIFT);
272 bootblock.bb_secstart = BOOT_BLOCK_BLOCKSIZE + (sector_offset * 512);
273 bootblock.bb_secsize = ((uint64_t) bootbufsize) |
274 (((uint64_t) datacsum) << BOOT_DATA_CHECKSUM_SHIFT);
275 bootblock.bb_archinfo = 0;
277 do_checksum(&(bootblock.bb_magic),BOOT_BLOCK_SIZE,&hdrcsum,0);
278 bootblock.bb_hdrinfo |= (uint64_t) hdrcsum;
280 if (verbose) dumpbootblock(&bootblock);
282 bswap_bootblock(&bootblock);
285 * Now write the output file
288 fh = open(argv[2],O_RDWR|O_CREAT,S_IREAD|S_IWRITE);
289 if (fh < 0) {
290 perror(argv[2]);
291 exit(1);
293 if (lseek(fh, sector_offset * 512, SEEK_SET) != (sector_offset * 512)) {
294 perror(argv[2]);
295 exit(1);
297 if (write(fh,&bootblock,sizeof(bootblock)) != sizeof(bootblock)) {
298 perror(argv[2]);
299 exit(1);
301 if (write(fh,bootcode,bootbufsize) != bootbufsize) {
302 perror(argv[2]);
303 exit(1);
306 close(fh);
308 fprintf(stderr,"%s -> %s : OK\n",argv[1],argv[2]);
310 exit(0);