2 * USB DFU file trailer tool
3 * (C) Copyright by OpenMoko, Inc.
4 * Author: Harald Welte <laforge@openmoko.org>
6 * based on mkimage.c, copyright information as follows:
8 * (C) Copyright 2000-2004
9 * DENX Software Engineering
10 * Wolfgang Denk, wd@denx.de
11 * All rights reserved.
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License as
15 * published by the Free Software Foundation; either version 2 of
16 * the License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
35 #include <netinet/in.h> /* for host / network byte order conversions */
42 #if defined(__BEOS__) || defined(__NetBSD__) || defined(__APPLE__)
47 typedef unsigned int __u32
;
49 #define SWAP_LONG(x) \
51 (((__u32)(x) & (__u32)0x000000ffUL) << 24) | \
52 (((__u32)(x) & (__u32)0x0000ff00UL) << 8) | \
53 (((__u32)(x) & (__u32)0x00ff0000UL) >> 8) | \
54 (((__u32)(x) & (__u32)0xff000000UL) >> 24) ))
55 typedef unsigned char uint8_t;
56 typedef unsigned short uint16_t;
57 typedef unsigned int uint32_t;
59 #define ntohl(a) SWAP_LONG(a)
60 #define htonl(a) SWAP_LONG(a)
61 #endif /* __WIN32__ */
63 #ifndef O_BINARY /* should be define'd on __WIN32__ */
67 #include <usb_dfu_trailer.h>
72 #define MAP_FAILED (-1)
77 static char *datafile
;
78 static char *imagefile
;
83 fprintf (stderr
, "%s - create / display u-boot DFU trailer\n", cmdname
);
84 fprintf (stderr
, "Usage: %s -l image\n"
85 " -l ==> list image header information\n"
86 " %s -v VID -p PID -r REV -d data_file image\n",
88 fprintf (stderr
, " -v ==> set vendor ID to 'VID'\n"
89 " -p ==> set product ID system to 'PID'\n"
90 " -r ==> set hardware revision to 'REV'\n"
91 " -d ==> use 'data_file' as input file\n"
96 static void print_trailer(struct uboot_dfu_trailer
*trailer
)
98 printf("===> DFU Trailer information:\n");
99 printf("Trailer Vers.: %d\n", trailer
->version
);
100 printf("Trailer Length: %d\n", trailer
->length
);
101 printf("VendorID: 0x%04x\n", trailer
->vendor
);
102 printf("ProductID: 0x%04x\n", trailer
->product
);
103 printf("HW Revision: 0x%04x\n", trailer
->revision
);
106 static void copy_file (int ifd
, const char *datafile
, int pad
)
116 if ((dfd
= open(datafile
, O_RDONLY
|O_BINARY
)) < 0) {
117 fprintf (stderr
, "%s: Can't open %s: %s\n",
118 cmdname
, datafile
, strerror(errno
));
122 if (fstat(dfd
, &sbuf
) < 0) {
123 fprintf (stderr
, "%s: Can't stat %s: %s\n",
124 cmdname
, datafile
, strerror(errno
));
128 ptr
= (unsigned char *)mmap(0, sbuf
.st_size
,
129 PROT_READ
, MAP_SHARED
, dfd
, 0);
130 if (ptr
== (unsigned char *)MAP_FAILED
) {
131 fprintf (stderr
, "%s: Can't read %s: %s\n",
132 cmdname
, datafile
, strerror(errno
));
136 size
= sbuf
.st_size
- offset
;
137 if (write(ifd
, ptr
+ offset
, size
) != size
) {
138 fprintf (stderr
, "%s: Write error on %s: %s\n",
139 cmdname
, imagefile
, strerror(errno
));
143 if (pad
&& ((tail
= size
% 4) != 0)) {
145 if (write(ifd
, (char *)&zero
, 4-tail
) != 4-tail
) {
146 fprintf (stderr
, "%s: Write error on %s: %s\n",
147 cmdname
, imagefile
, strerror(errno
));
152 (void) munmap((void *)ptr
, sbuf
.st_size
);
157 int main(int argc
, char **argv
)
162 u_int16_t opt_vendor
, opt_product
, opt_revision
;
163 struct uboot_dfu_trailer _hdr
, _mirror
, *hdr
= &_hdr
;
165 opt_vendor
= opt_product
= opt_revision
= 0;
169 while (--argc
> 0 && **++argv
== '-') {
178 opt_vendor
= strtoul(*++argv
, NULL
, 16);
183 opt_product
= strtoul(*++argv
, NULL
, 16);
188 opt_revision
= strtoul(*++argv
, NULL
, 16);
211 ifd
= open(imagefile
, O_RDONLY
|O_BINARY
);
213 ifd
= open(imagefile
, O_RDWR
|O_CREAT
|O_TRUNC
|O_BINARY
, 0666);
216 fprintf (stderr
, "%s: Can't open %s: %s\n",
217 cmdname
, imagefile
, strerror(errno
));
223 /* list header information of existing image */
224 if (fstat(ifd
, &sbuf
) < 0) {
225 fprintf (stderr
, "%s: Can't stat %s: %s\n",
226 cmdname
, imagefile
, strerror(errno
));
230 if ((unsigned)sbuf
.st_size
< sizeof(struct uboot_dfu_trailer
)) {
232 "%s: Bad size: \"%s\" is no valid image\n",
237 ptr
= (unsigned char *)mmap(0, sbuf
.st_size
,
238 PROT_READ
, MAP_SHARED
, ifd
, 0);
239 if ((caddr_t
)ptr
== (caddr_t
)-1) {
240 fprintf (stderr
, "%s: Can't read %s: %s\n",
241 cmdname
, imagefile
, strerror(errno
));
245 dfu_trailer_mirror(hdr
, ptr
+sbuf
.st_size
);
247 if (hdr
->magic
!= UBOOT_DFU_TRAILER_MAGIC
) {
249 "%s: Bad Magic Number: \"%s\" is no valid image\n",
254 /* for multi-file images we need the data part, too */
257 (void) munmap((void *)ptr
, sbuf
.st_size
);
263 /* if we're not listing: */
265 copy_file (ifd
, datafile
, 0);
267 memset (hdr
, 0, sizeof(struct uboot_dfu_trailer
));
269 /* Build new header */
270 hdr
->version
= UBOOT_DFU_TRAILER_V1
;
271 hdr
->magic
= UBOOT_DFU_TRAILER_MAGIC
;
272 hdr
->length
= sizeof(struct uboot_dfu_trailer
);
273 hdr
->vendor
= opt_vendor
;
274 hdr
->product
= opt_product
;
275 hdr
->revision
= opt_revision
;
278 dfu_trailer_mirror(&_mirror
, (unsigned char *)hdr
+sizeof(*hdr
));
280 if (write(ifd
, &_mirror
, sizeof(struct uboot_dfu_trailer
))
281 != sizeof(struct uboot_dfu_trailer
)) {
282 fprintf (stderr
, "%s: Write error on %s: %s\n",
283 cmdname
, imagefile
, strerror(errno
));
287 /* We're a bit of paranoid */
288 #if defined(_POSIX_SYNCHRONIZED_IO) && !defined(__sun__) && !defined(__FreeBSD__)
289 (void) fdatasync (ifd
);
294 if (fstat(ifd
, &sbuf
) < 0) {
295 fprintf (stderr
, "%s: Can't stat %s: %s\n",
296 cmdname
, imagefile
, strerror(errno
));
300 /* We're a bit of paranoid */
301 #if defined(_POSIX_SYNCHRONIZED_IO) && !defined(__sun__) && !defined(__FreeBSD__)
302 (void) fdatasync (ifd
);
308 fprintf (stderr
, "%s: Write error on %s: %s\n",
309 cmdname
, imagefile
, strerror(errno
));