finally move buildroot-ng to trunk
[openwrt/staging/dedeckeh.git] / target / utils / src / dgfirmware.c
1 #include <stdlib.h>
2 #include <stdio.h>
3
4
5 #define IMG_SIZE 0x3e0000
6
7 #define KERNEL_START 0x020000
8 #define KERNEL_SIZE 0x0b0000
9
10 #define ROOTFS_START 0x0d0000
11 #define ROOTFS_SIZE 0x30ffb2
12
13 char* app_name;
14
15
16
17
18 void print_usage(void)
19 {
20 fprintf(stderr, "usage: dgfirmware [<opts>] <img>\n");
21 fprintf(stderr, " <img> firmware image filename\n");
22 fprintf(stderr, " <opts> -h print this message\n");
23 fprintf(stderr, " -f fix the checksum\n");
24 fprintf(stderr, " -x <file> extract the rootfs file to <file>\n");
25 fprintf(stderr, " -xk <file> extract the kernel to <file>\n");
26 fprintf(stderr, " -m <file> merge in rootfs fil\e from <file>\n");
27 fprintf(stderr, " -k <file> merge in kernel from <file>\n");
28 fprintf(stderr, " -w <file> write back the modified firmware\n");
29 }
30
31
32 unsigned char* read_img(const char *fname)
33 {
34 FILE *fp;
35 int size;
36 unsigned char *img;
37
38 fp = fopen(fname, "rb");
39 if (fp == NULL) {
40 perror(app_name);
41 exit(-1);
42 }
43
44 fseek(fp, 0, SEEK_END);
45 size = ftell(fp);
46
47 if (size != IMG_SIZE) {
48 fprintf(stderr, "%s: image file has wrong size\n", app_name);
49 fclose(fp);
50 exit(-1);
51 }
52
53 rewind(fp);
54
55 img = malloc(IMG_SIZE);
56 if (img == NULL) {
57 perror(app_name);
58 fclose(fp);
59 exit(-1);
60 }
61
62 if (fread(img, 1, IMG_SIZE, fp) != IMG_SIZE) {
63 fprintf(stderr, "%s: can't read image file\n", app_name);
64 fclose(fp);
65 exit(-1);
66 }
67
68 fclose(fp);
69 return img;
70 }
71
72
73 void write_img(unsigned char* img, const char *fname)
74 {
75 FILE *fp;
76
77 fp = fopen(fname, "wb");
78 if (fp == NULL) {
79 perror(app_name);
80 exit(-1);
81 }
82
83 if (fwrite(img, 1, IMG_SIZE, fp) != IMG_SIZE) {
84 fprintf(stderr, "%s: can't write image file\n", app_name);
85 fclose(fp);
86 exit(-1);
87 }
88 }
89
90
91 void write_rootfs(unsigned char* img, const char *fname)
92 {
93 FILE *fp;
94
95 fp = fopen(fname, "wb");
96 if (fp == NULL) {
97 perror(app_name);
98 exit(-1);
99 }
100
101 if (fwrite(img+ROOTFS_START, 1, ROOTFS_SIZE, fp) != ROOTFS_SIZE) {
102 fprintf(stderr, "%s: can't write image file\n", app_name);
103 fclose(fp);
104 exit(-1);
105 }
106 }
107
108
109 void write_kernel(unsigned char* img, const char *fname)
110 {
111 FILE *fp;
112
113 fp = fopen(fname, "wb");
114 if (fp == NULL) {
115 perror(app_name);
116 exit(-1);
117 }
118
119 if (fwrite(img+KERNEL_START, 1, KERNEL_SIZE, fp) != KERNEL_SIZE) {
120 fprintf(stderr, "%s: can't write kernel file\n", app_name);
121 fclose(fp);
122 exit(-1);
123 }
124 }
125
126
127 unsigned char* read_rootfs(unsigned char* img, const char *fname)
128 {
129 FILE *fp;
130 int size;
131 int i;
132
133 for (i=ROOTFS_START; i<ROOTFS_START+ROOTFS_SIZE; i++)
134 img[i] = 0xff;
135
136 fp = fopen(fname, "rb");
137 if (fp == NULL) {
138 perror(app_name);
139 exit(-1);
140 }
141
142 fseek(fp, 0, SEEK_END);
143 size = ftell(fp);
144
145 if (size > ROOTFS_SIZE) {
146 fprintf(stderr, "%s: rootfs image file is too big\n", app_name);
147 fclose(fp);
148 exit(-1);
149 }
150
151 rewind(fp);
152
153 if (fread(img+ROOTFS_START, 1, size, fp) != size) {
154 fprintf(stderr, "%s: can't read rootfs image file\n", app_name);
155 fclose(fp);
156 exit(-1);
157 }
158
159 fclose(fp);
160 return img;
161 }
162
163
164 unsigned char* read_kernel(unsigned char* img, const char *fname)
165 {
166 FILE *fp;
167 int size;
168 int i;
169
170 for (i=KERNEL_START; i<KERNEL_START+KERNEL_SIZE; i++)
171 img[i] = 0xff;
172
173 fp = fopen(fname, "rb");
174 if (fp == NULL) {
175 perror(app_name);
176 exit(-1);
177 }
178
179 fseek(fp, 0, SEEK_END);
180 size = ftell(fp);
181
182 if (size > KERNEL_SIZE) {
183 fprintf(stderr, "%s: kernel binary file is too big\n", app_name);
184 fclose(fp);
185 exit(-1);
186 }
187
188 rewind(fp);
189
190 if (fread(img+KERNEL_START, 1, size, fp) != size) {
191 fprintf(stderr, "%s: can't read kernel file\n", app_name);
192 fclose(fp);
193 exit(-1);
194 }
195
196 fclose(fp);
197 return img;
198 }
199
200
201 int get_checksum(unsigned char* img)
202 {
203 short unsigned s;
204
205 s = img[0x3dfffc] + (img[0x3dfffd]<<8);
206
207 return s;
208 }
209
210
211 void set_checksum(unsigned char*img, unsigned short sum)
212 {
213 img[0x3dfffc] = sum & 0xff;
214 img[0x3dfffd] = (sum>>8) & 0xff;
215 }
216
217
218 int compute_checksum(unsigned char* img)
219 {
220 int i;
221 short s=0;
222
223 for (i=0; i<0x3dfffc; i++)
224 s += img[i];
225
226 return s;
227 }
228
229
230 int main(int argc, char* argv[])
231 {
232 char *img_fname = NULL;
233 char *rootfs_fname = NULL;
234 char *kernel_fname = NULL;
235 char *new_img_fname = NULL;
236
237 int do_fix_checksum = 0;
238 int do_write = 0;
239 int do_write_rootfs = 0;
240 int do_read_rootfs = 0;
241 int do_write_kernel = 0;
242 int do_read_kernel = 0;
243
244 int i;
245 unsigned char *img;
246 unsigned short img_checksum;
247 unsigned short real_checksum;
248
249 app_name = argv[0];
250
251 for (i=1; i<argc; i++) {
252 if (!strcmp(argv[i], "-h")) {
253 print_usage();
254 return 0;
255 }
256 else if (!strcmp(argv[i], "-f")) {
257 do_fix_checksum = 1;
258 }
259 else if (!strcmp(argv[i], "-x")) {
260 if (i+1 >= argc) {
261 fprintf(stderr, "%s: missing argument\n", app_name);
262 return -1;
263 }
264 do_write_rootfs = 1;
265 rootfs_fname = argv[i+1];
266 i++;
267 }
268 else if (!strcmp(argv[i], "-xk")) {
269 if (i+1 >= argc) {
270 fprintf(stderr, "%s: missing argument\n", app_name);
271 return -1;
272 }
273 do_write_kernel = 1;
274 kernel_fname = argv[i+1];
275 i++;
276 }
277 else if (!strcmp(argv[i], "-m")) {
278 if (i+1 >= argc) {
279 fprintf(stderr, "%s: missing argument\n", app_name);
280 return -1;
281 }
282 do_read_rootfs = 1;
283 rootfs_fname = argv[i+1];
284 i++;
285 }
286 else if (!strcmp(argv[i], "-k")) {
287 if (i+1 >= argc) {
288 fprintf(stderr, "%s: missing argument\n", app_name);
289 return -1;
290 }
291 do_read_kernel = 1;
292 kernel_fname = argv[i+1];
293 i++;
294 }
295 else if (!strcmp(argv[i], "-w")) {
296 if (i+1 >= argc) {
297 fprintf(stderr, "%s: missing argument\n", app_name);
298 return -1;
299 }
300 do_write = 1;
301 new_img_fname = argv[i+1];
302 i++;
303 }
304 else if (img_fname != 0) {
305 fprintf(stderr, "%s: too many arguments\n", app_name);
306 return -1;
307 }
308 else {
309 img_fname = argv[i];
310 }
311 }
312
313 if (img_fname == NULL) {
314 fprintf(stderr, "%s: missing argument\n", app_name);
315 return -1;
316 }
317
318 if ((do_read_rootfs && do_write_rootfs) ||
319 (do_read_kernel && do_write_kernel)) {
320 fprintf(stderr, "%s: conflictuous options\n", app_name);
321 return -1;
322 }
323
324 printf ("** Read firmware file\n");
325 img = read_img(img_fname);
326
327 printf ("Firmware product: %s\n", img+0x3dffbd);
328 printf ("Firmware version: 1.%02d.%02d\n", (img[0x3dffeb] & 0x7f), img[0x3dffec]);
329
330 if (do_write_rootfs) {
331 printf ("** Write rootfs file\n");
332 write_rootfs(img, rootfs_fname);
333 }
334
335 if (do_write_kernel) {
336 printf ("** Write kernel file\n");
337 write_kernel(img, kernel_fname);
338 }
339
340 if (do_read_rootfs) {
341 printf ("** Read rootfs file\n");
342 read_rootfs(img, rootfs_fname);
343 do_fix_checksum = 1;
344 }
345
346 if (do_read_kernel) {
347 printf ("** Read kernel file\n");
348 read_kernel(img, kernel_fname);
349 do_fix_checksum = 1;
350 }
351
352 img_checksum = get_checksum(img);
353 real_checksum = compute_checksum(img);
354
355 printf ("image checksum = %04x\n", img_checksum);
356 printf ("real checksum = %04x\n", real_checksum);
357
358 if (do_fix_checksum) {
359 if (img_checksum != real_checksum) {
360 printf ("** Bad Checksum, fix it\n");
361 set_checksum(img, real_checksum);
362 }
363 else {
364 printf ("** Checksum is correct, good\n");
365 }
366 }
367
368 if (do_write) {
369 printf ("** Write image file\n");
370 write_img(img, new_img_fname);
371 }
372
373 free(img);
374 return 0;
375 }
376