OpenWrt – Blame information for rev 4
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
4 | office | 1 | /* |
2 | * Copyright (C) 2014 Claudio Leite <leitec@staticky.com> |
||
3 | * |
||
4 | * This program is free software; you can redistribute it and/or modify |
||
5 | * it under the terms of the GNU General Public License as published by |
||
6 | * the Free Software Foundation; either version 2 of the License, or |
||
7 | * (at your option) any later version. |
||
8 | * |
||
9 | * This program is distributed in the hope that it will be useful, |
||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||
12 | * General Public License for more details. |
||
13 | * |
||
14 | * You should have received a copy of the GNU General Public License |
||
15 | * along with this program; if not, write to the Free Software |
||
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
||
17 | */ |
||
18 | |||
19 | /* |
||
20 | * Builds a proper flash image for routers using some Gemtek |
||
21 | * OEM boards. These include the Airlink101 AR725W, the |
||
22 | * Asante SmartHub 600 (AWRT-600N), and Linksys WRT100/110. |
||
23 | * |
||
24 | * The resulting image is compatible with the factory firmware |
||
25 | * web upgrade and TFTP interface. |
||
26 | * |
||
27 | * To build: |
||
28 | * gcc -O2 -o mkheader_gemtek mkheader_gemtek.c -lz |
||
29 | * |
||
30 | * Claudio Leite <leitec@staticky.com> |
||
31 | */ |
||
32 | |||
33 | #include <stdio.h> |
||
34 | #include <stdlib.h> |
||
35 | #include <stdint.h> |
||
36 | #include <string.h> |
||
37 | |||
38 | #include <zlib.h> /* for crc32() */ |
||
39 | |||
40 | /* |
||
41 | * The header is in little-endian format. In case |
||
42 | * we are on a BE host, we need to swap binary |
||
43 | * values. |
||
44 | */ |
||
45 | #ifdef __APPLE__ |
||
46 | # include <libkern/OSByteOrder.h> |
||
47 | # define le32 OSSwapHostToLittleInt32 |
||
48 | #else |
||
49 | # if defined(__linux__) |
||
50 | # include <endian.h> |
||
51 | # if __BYTE_ORDER == __BIG_ENDIAN |
||
52 | # define CPU_BIG_ENDIAN |
||
53 | # endif |
||
54 | # else |
||
55 | # include <sys/endian.h> /* BSD's should have this */ |
||
56 | # if _BYTE_ORDER == _BIG_ENDIAN |
||
57 | # define CPU_BIG_ENDIAN |
||
58 | # endif |
||
59 | # endif |
||
60 | # ifdef CPU_BIG_ENDIAN |
||
61 | # define le32(x) (((x & 0xff000000) >> 24) | \ |
||
62 | ((x & 0x00ff0000) >> 8) | \ |
||
63 | ((x & 0x0000ff00) << 8) | \ |
||
64 | ((x & 0x000000ff) << 24)) |
||
65 | # else |
||
66 | # define le32(x) (x) |
||
67 | # endif |
||
68 | #endif |
||
69 | |||
70 | struct gemtek_header { |
||
71 | uint8_t magic[4]; |
||
72 | uint8_t version[4]; |
||
73 | uint32_t product_id; |
||
74 | uint32_t imagesz; |
||
75 | uint32_t checksum; |
||
76 | uint32_t fast_checksum; |
||
77 | uint8_t build[4]; |
||
78 | uint8_t lang[4]; |
||
79 | }; |
||
80 | |||
81 | #define HDRLEN sizeof(struct gemtek_header) |
||
82 | |||
83 | struct machines { |
||
84 | char *desc; |
||
85 | char *id; |
||
86 | uint32_t maxsize; |
||
87 | struct gemtek_header header; |
||
88 | }; |
||
89 | |||
90 | struct machines mach_def[] = { |
||
91 | {"Airlink101 AR725W", "ar725w", 0x340000, |
||
92 | {"GMTK", "1003", le32(0x03000001), 0, 0, |
||
93 | 0, "01\0\0", "EN\0\0"}}, |
||
94 | {"Asante AWRT-600N", "awrt600n", 0x340000, |
||
95 | {"A600", "1005", le32(0x03000001), 0, 0, |
||
96 | 0, "01\0\0", "EN\0\0"}}, |
||
97 | {"Linksys WRT100", "wrt100", 0x320000, |
||
98 | {"GMTK", "1007", le32(0x03040001), 0, 0, |
||
99 | 0, "2\0\0\0", "EN\0\0"}}, |
||
100 | {"Linksys WRT110", "wrt110", 0x320000, |
||
101 | {"GMTK", "1007", le32(0x03040001), 0, 0, |
||
102 | 0, "2\0\0\0", "EN\0\0"}}, |
||
103 | {0} |
||
104 | }; |
||
105 | |||
106 | int |
||
107 | main(int argc, char *argv[]) |
||
108 | { |
||
109 | unsigned long res, flen; |
||
110 | struct gemtek_header my_hdr; |
||
111 | FILE *f, *f_out; |
||
112 | int image_type = -1, index; |
||
113 | uint8_t *buf; |
||
114 | uint32_t crc; |
||
115 | |||
116 | if (argc < 3) { |
||
117 | fprintf(stderr, "mkheader_gemtek <uImage> <webflash image> [machine ID]\n"); |
||
118 | fprintf(stderr, " where [machine ID] is one of:\n"); |
||
119 | for (index = 0; mach_def[index].desc != 0; index++) { |
||
120 | fprintf(stderr, " %-10s %s", mach_def[index].id, mach_def[index].desc); |
||
121 | if (index == 0) |
||
122 | fprintf(stderr, " (default)\n"); |
||
123 | else |
||
124 | fprintf(stderr, "\n"); |
||
125 | } |
||
126 | |||
127 | exit(-1); |
||
128 | } |
||
129 | |||
130 | if (argc == 4) { |
||
131 | for(index = 0; mach_def[index].id != 0; index++) { |
||
132 | if(strcmp(mach_def[index].id, argv[3]) == 0) { |
||
133 | image_type = index; |
||
134 | break; |
||
135 | } |
||
136 | } |
||
137 | |||
138 | if(image_type == -1) { |
||
139 | fprintf(stderr, "\nERROR: invalid machine type\n"); |
||
140 | exit(-1); |
||
141 | } |
||
142 | } else |
||
143 | image_type = 0; |
||
144 | |||
145 | printf("Opening %s...\n", argv[1]); |
||
146 | |||
147 | f = fopen(argv[1], "r"); |
||
148 | if(!f) { |
||
149 | fprintf(stderr, "\nERROR: couldn't open input image\n"); |
||
150 | exit(-1); |
||
151 | } |
||
152 | |||
153 | fseek(f, 0, SEEK_END); |
||
154 | flen = (unsigned long) ftell(f); |
||
155 | |||
156 | printf(" %lu (0x%lX) bytes long\n", flen, flen); |
||
157 | |||
158 | if (flen > mach_def[image_type].maxsize) { |
||
159 | fprintf(stderr, "\nERROR: image exceeds maximum compatible size\n"); |
||
160 | goto f_error; |
||
161 | } |
||
162 | |||
163 | buf = malloc(flen + HDRLEN); |
||
164 | if (!buf) { |
||
165 | fprintf(stderr, "\nERROR: couldn't allocate buffer\n"); |
||
166 | goto f_error; |
||
167 | } |
||
168 | rewind(f); |
||
169 | res = fread(buf + HDRLEN, 1, flen, f); |
||
170 | if (res != flen) { |
||
171 | perror("Couldn't read entire file: fread()"); |
||
172 | goto f_error; |
||
173 | } |
||
174 | fclose(f); |
||
175 | |||
176 | printf("\nCreating %s...\n", argv[2]); |
||
177 | |||
178 | memcpy(&my_hdr, &mach_def[image_type].header, HDRLEN); |
||
179 | |||
180 | printf(" Using %s magic\n", mach_def[image_type].desc); |
||
181 | |||
182 | my_hdr.imagesz = le32(flen + HDRLEN); |
||
183 | memcpy(my_hdr.lang, "EN", 2); |
||
184 | |||
185 | memcpy(buf, &my_hdr, HDRLEN); |
||
186 | |||
187 | crc = crc32(0, buf, flen + HDRLEN); |
||
188 | printf(" CRC32: %08X\n", crc); |
||
189 | |||
190 | my_hdr.checksum = le32(crc); |
||
191 | memcpy(buf, &my_hdr, HDRLEN); |
||
192 | |||
193 | printf(" Writing...\n"); |
||
194 | |||
195 | f_out = fopen(argv[2], "w"); |
||
196 | if(!f_out) { |
||
197 | fprintf(stderr, "\nERROR: couldn't open output image\n"); |
||
198 | exit(-1); |
||
199 | } |
||
200 | |||
201 | fwrite(buf, 1, flen + HDRLEN, f_out); |
||
202 | |||
203 | fclose(f_out); |
||
204 | |||
205 | free(buf); |
||
206 | return 0; |
||
207 | |||
208 | f_error: |
||
209 | fclose(f); |
||
210 | exit(-1); |
||
211 | } |