1 /* *********************************************************************
2 * Broadcom Common Firmware Environment (CFE)
4 * Boot block generator File: mkbootimage.c
6 * Author: Mitch Lichtenberg (mpl@broadcom.com)
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>
55 typedef unsigned long long uint64_t;
56 typedef unsigned long uint32_t;
58 #include "cfe_bootblock.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");
78 static void bswap32(uint32_t *ptr
)
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
)
95 bptr
= (unsigned char *) ptr
;
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
)
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
)
121 p
= (uint32_t *) ptr
;
123 length
/= sizeof(uint32_t);
127 if (swap
) bswap32(&d
);
133 if (swap
) bswap32(&chksum
);
139 static void dumpbootblock(struct boot_block
*bb
)
143 fprintf(stderr
,"Magic Number: %016llX\n",
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
;
172 int main(int argc
, char *argv
[])
177 unsigned char *bootcode
;
178 struct boot_block bootblock
;
179 uint32_t datacsum
,hdrcsum
;
182 while ((argc
> 1) && (argv
[1][0] == '-')) {
183 if (strcmp(argv
[1],"-v") == 0) {
186 else if (strcmp(argv
[1],"-EB") == 0) {
189 else if (strcmp(argv
[1],"-EL") == 0) {
192 else if (strcmp(argv
[1],"-S") == 0) {
197 fprintf(stderr
,"-S requires an argument\n");
200 sector_offset
= strtoul(argv
[1], &tmp_ptr
, 0);
202 fprintf(stderr
,"Unable to parse %s as a sector offset\n", argv
[1]);
207 fprintf(stderr
,"Invalid switch: %s\n",argv
[1]);
215 * We need to swap things around if the host and
216 * target are different endianness
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");
233 * Read in the boot file
236 fh
= open(argv
[1],O_RDONLY
);
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
) {
251 memset(bootcode
,0,bootbufsize
);
252 if (read(fh
,bootcode
,bootsize
) != bootsize
) {
260 * Construct the boot block
264 /* Checksum the boot code */
265 do_checksum(bootcode
,bootbufsize
,&datacsum
,1);
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
);
293 if (lseek(fh
, sector_offset
* 512, SEEK_SET
) != (sector_offset
* 512)) {
297 if (write(fh
,&bootblock
,sizeof(bootblock
)) != sizeof(bootblock
)) {
301 if (write(fh
,bootcode
,bootbufsize
) != bootbufsize
) {
308 fprintf(stderr
,"%s -> %s : OK\n",argv
[1],argv
[2]);