1 // SPDX-License-Identifier: GPL-2.0-only
7 #define IMG_SIZE 0x3e0000
9 #define KERNEL_START 0x020000
10 #define KERNEL_SIZE 0x0b0000
12 #define ROOTFS_START 0x0d0000
13 #define ROOTFS_SIZE 0x30ffb2
20 void print_usage(void)
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");
34 unsigned char* read_img(const char *fname
)
40 fp
= fopen(fname
, "rb");
46 fseek(fp
, 0, SEEK_END
);
49 if (size
!= IMG_SIZE
) {
50 fprintf(stderr
, "%s: image file has wrong size\n", app_name
);
57 img
= malloc(IMG_SIZE
);
64 if (fread(img
, 1, IMG_SIZE
, fp
) != IMG_SIZE
) {
65 fprintf(stderr
, "%s: can't read image file\n", app_name
);
75 void write_img(unsigned char* img
, const char *fname
)
79 fp
= fopen(fname
, "wb");
85 if (fwrite(img
, 1, IMG_SIZE
, fp
) != IMG_SIZE
) {
86 fprintf(stderr
, "%s: can't write image file\n", app_name
);
95 void write_rootfs(unsigned char* img
, const char *fname
)
99 fp
= fopen(fname
, "wb");
105 if (fwrite(img
+ROOTFS_START
, 1, ROOTFS_SIZE
, fp
) != ROOTFS_SIZE
) {
106 fprintf(stderr
, "%s: can't write image file\n", app_name
);
115 void write_kernel(unsigned char* img
, const char *fname
)
119 fp
= fopen(fname
, "wb");
125 if (fwrite(img
+KERNEL_START
, 1, KERNEL_SIZE
, fp
) != KERNEL_SIZE
) {
126 fprintf(stderr
, "%s: can't write kernel file\n", app_name
);
135 unsigned char* read_rootfs(unsigned char* img
, const char *fname
)
141 for (i
=ROOTFS_START
; i
<ROOTFS_START
+ROOTFS_SIZE
; i
++)
144 fp
= fopen(fname
, "rb");
150 fseek(fp
, 0, SEEK_END
);
153 if (size
> ROOTFS_SIZE
) {
154 fprintf(stderr
, "%s: rootfs image file is too big\n", app_name
);
161 if (fread(img
+ROOTFS_START
, 1, size
, fp
) != size
) {
162 fprintf(stderr
, "%s: can't read rootfs image file\n", app_name
);
172 unsigned char* read_kernel(unsigned char* img
, const char *fname
)
178 for (i
=KERNEL_START
; i
<KERNEL_START
+KERNEL_SIZE
; i
++)
181 fp
= fopen(fname
, "rb");
187 fseek(fp
, 0, SEEK_END
);
190 if (size
> KERNEL_SIZE
) {
191 fprintf(stderr
, "%s: kernel binary file is too big\n", app_name
);
198 if (fread(img
+KERNEL_START
, 1, size
, fp
) != size
) {
199 fprintf(stderr
, "%s: can't read kernel file\n", app_name
);
209 int get_checksum(unsigned char* img
)
213 s
= img
[0x3dfffc] + (img
[0x3dfffd]<<8);
219 void set_checksum(unsigned char*img
, unsigned short sum
)
221 img
[0x3dfffc] = sum
& 0xff;
222 img
[0x3dfffd] = (sum
>>8) & 0xff;
226 int compute_checksum(unsigned char* img
)
231 for (i
=0; i
<0x3dfffc; i
++)
238 int main(int argc
, char* argv
[])
240 char *img_fname
= NULL
;
241 char *rootfs_fname
= NULL
;
242 char *kernel_fname
= NULL
;
243 char *new_img_fname
= NULL
;
245 int do_fix_checksum
= 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;
254 unsigned short img_checksum
;
255 unsigned short real_checksum
;
259 for (i
=1; i
<argc
; i
++) {
260 if (!strcmp(argv
[i
], "-h")) {
264 else if (!strcmp(argv
[i
], "-f")) {
267 else if (!strcmp(argv
[i
], "-x")) {
269 fprintf(stderr
, "%s: missing argument\n", app_name
);
273 rootfs_fname
= argv
[i
+1];
276 else if (!strcmp(argv
[i
], "-xk")) {
278 fprintf(stderr
, "%s: missing argument\n", app_name
);
282 kernel_fname
= argv
[i
+1];
285 else if (!strcmp(argv
[i
], "-m")) {
287 fprintf(stderr
, "%s: missing argument\n", app_name
);
291 rootfs_fname
= argv
[i
+1];
294 else if (!strcmp(argv
[i
], "-k")) {
296 fprintf(stderr
, "%s: missing argument\n", app_name
);
300 kernel_fname
= argv
[i
+1];
303 else if (!strcmp(argv
[i
], "-w")) {
305 fprintf(stderr
, "%s: missing argument\n", app_name
);
309 new_img_fname
= argv
[i
+1];
312 else if (img_fname
!= 0) {
313 fprintf(stderr
, "%s: too many arguments\n", app_name
);
321 if (img_fname
== NULL
) {
322 fprintf(stderr
, "%s: missing argument\n", app_name
);
326 if ((do_read_rootfs
&& do_write_rootfs
) ||
327 (do_read_kernel
&& do_write_kernel
)) {
328 fprintf(stderr
, "%s: conflictuous options\n", app_name
);
332 printf ("** Read firmware file\n");
333 img
= read_img(img_fname
);
335 printf ("Firmware product: %s\n", img
+0x3dffbd);
336 printf ("Firmware version: 1.%02d.%02d\n", (img
[0x3dffeb] & 0x7f), img
[0x3dffec]);
338 if (do_write_rootfs
) {
339 printf ("** Write rootfs file\n");
340 write_rootfs(img
, rootfs_fname
);
343 if (do_write_kernel
) {
344 printf ("** Write kernel file\n");
345 write_kernel(img
, kernel_fname
);
348 if (do_read_rootfs
) {
349 printf ("** Read rootfs file\n");
350 read_rootfs(img
, rootfs_fname
);
354 if (do_read_kernel
) {
355 printf ("** Read kernel file\n");
356 read_kernel(img
, kernel_fname
);
360 img_checksum
= get_checksum(img
);
361 real_checksum
= compute_checksum(img
);
363 printf ("image checksum = %04x\n", img_checksum
);
364 printf ("real checksum = %04x\n", real_checksum
);
366 if (do_fix_checksum
) {
367 if (img_checksum
!= real_checksum
) {
368 printf ("** Bad Checksum, fix it\n");
369 set_checksum(img
, real_checksum
);
372 printf ("** Checksum is correct, good\n");
377 printf ("** Write image file\n");
378 write_img(img
, new_img_fname
);