4 * Copyright (C) 2005-2006 Mike Baker,
5 * Imre Kaloz <kaloz@openwrt.org>
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 * Motorola's firmware flashing code requires an extra header.
28 * The header is eight bytes (see struct motorola below).
29 * This program will take a firmware file and create a new one
31 * motorola-bin --wr850g WR850G_V403.stripped.trx WR850G_V403.trx
33 * Note: Motorola's firmware is distributed with this header.
34 * If you need to flash Motorola firmware on a router running OpenWRT,
35 * you will to remove this header. Use the --strip flag:
36 * motorola-bin --strip WR850G_V403.trx WR850G_V403.stripped.trx
42 * Add support for for creating WA840G and WE800G images
53 #include <netinet/in.h>
56 #define BPB 8 /* bits/byte */
58 static uint32_t crc32
[1<<BPB
];
60 static void init_crc32()
62 const uint32_t poly
= ntohl(0x2083b8ed);
65 for (n
= 0; n
< 1<<BPB
; n
++) {
69 for (bit
= 0; bit
< BPB
; bit
++)
70 crc
= (crc
& 1) ? (poly
^ (crc
>> 1)) : (crc
>> 1);
75 static uint32_t crc32buf(unsigned char *buf
, size_t len
)
77 uint32_t crc
= 0xFFFFFFFF;
79 for (; len
; len
--, buf
++)
80 crc
= crc32
[(uint8_t)crc
^ *buf
] ^ (crc
>> BPB
);
85 uint32_t crc
; // crc32 of the remainder
86 uint32_t flags
; // unknown, 105770*
89 static const struct model
{
90 char digit
; /* a digit signifying model (historical) */
94 { '1', "WR850G", 0x10577050LU
},
95 { '2', "WA840G", 0x10577040LU
},
96 { '3', "WE800G", 0x10577000LU
},
100 static void usage(const char *) __attribute__ (( __noreturn__
));
102 static void usage(const char *mess
)
104 const struct model
*m
;
106 fprintf(stderr
, "Error: %s\n", mess
);
107 fprintf(stderr
, "Usage: motorola-bin -device|--strip infile outfile\n");
108 fprintf(stderr
, "Known devices: ");
110 for (m
= models
; m
->digit
!= '\0'; m
++)
111 fprintf(stderr
, " %c - %s", m
->digit
, m
->name
);
113 fprintf(stderr
, "\n");
117 int main(int argc
, char **argv
)
119 off_t len
; // of original firmware
121 void *trx
; // pointer to original firmware (mmmapped)
122 struct motorola
*firmware
; // pionter to prefix + copy of original firmware
128 usage("wrong number of arguments");
131 if ((fd
= open(argv
[2], O_RDONLY
)) < 0
132 || (len
= lseek(fd
, 0, SEEK_END
)) < 0
133 || (trx
= mmap(0, len
, PROT_READ
, MAP_SHARED
, fd
, 0)) == (void *) (-1)
136 fprintf(stderr
, "Error loading file %s: %s\n", argv
[2], strerror(errno
));
142 if (strcmp(argv
[1], "--strip") == 0)
144 const char *ugh
= NULL
;
146 if (len
< sizeof(struct motorola
)) {
147 ugh
= "input file too short";
149 const struct model
*m
;
152 if (htonl(crc32buf(trx
+ offsetof(struct motorola
, flags
), len
- offsetof(struct motorola
, flags
))) != firmware
->crc
)
154 for (m
= models
; ; m
++) {
155 if (m
->digit
== '\0') {
157 ugh
= "unrecognized flags field";
160 if (firmware
->flags
== htonl(m
->flags
)) {
161 fprintf(stderr
, "Firmware for Motorola %s\n", m
->name
);
168 fprintf(stderr
, "%s\n", ugh
);
171 // all is well, write the file without the prefix
172 if ((fd
= open(argv
[3], O_CREAT
|O_WRONLY
|O_TRUNC
,0644)) < 0
173 || write(fd
, trx
+ sizeof(struct motorola
), len
- sizeof(struct motorola
)) != len
- sizeof(struct motorola
)
176 fprintf(stderr
, "Error storing file %s: %s\n", argv
[3], strerror(errno
));
182 // setup the firmware flags magic number
183 const struct model
*m
;
184 const char *df
= argv
[1];
187 usage("first argument must start with -");
189 ++df
; /* allow but don't require second - */
191 for (m
= models
; ; m
++) {
192 if (m
->digit
== '\0')
193 usage("unrecognized device specified");
194 if ((df
[0] == m
->digit
&& df
[1] == '\0') || strcasecmp(df
, m
->name
) == 0) {
201 // create a firmware image in memory
202 // and copy the trx to it
203 firmware
= malloc(sizeof(struct motorola
) + len
);
204 memcpy(&firmware
[1], trx
, len
);
206 // setup the motorola headers
207 firmware
->flags
= htonl(flags
);
209 // CRC of flags + firmware
210 firmware
->crc
= htonl(crc32buf((unsigned char *)&firmware
->flags
, sizeof(firmware
->flags
) + len
));
212 // write the firmware
213 if ((fd
= open(argv
[3], O_CREAT
|O_WRONLY
|O_TRUNC
,0644)) < 0
214 || write(fd
, firmware
, sizeof(struct motorola
) + len
) != sizeof(struct motorola
) + len
217 fprintf(stderr
, "Error storing file %s: %s\n", argv
[3], strerror(errno
));
This page took 0.05623 seconds and 5 git commands to generate.