• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/firmware-utils/src/dgfirmware.c

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

This page was automatically generated by LXR 0.3.1.  •  OpenWrt