18da13dd047783e85475f96c833d7acb515e2aa6
2 * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
4 * This tool was based on:
5 * TP-Link WR941 V2 firmware checksum fixing tool.
6 * Copyright (C) 2008,2009 Wang Jian <lark@linux.net.cn>
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published
10 * by the Free Software Foundation.
18 #include <unistd.h> /* for unlink() */
20 #include <getopt.h> /* for getopt() */
27 #include <arpa/inet.h>
28 #include <netinet/in.h>
30 #include "mktplinkfw-lib.h"
34 extern char *progname
;
35 extern uint32_t kernel_len
;
36 extern struct file_info kernel_info
;
37 extern struct file_info rootfs_info
;
38 extern struct flash_layout
*layout
;
39 extern uint32_t rootfs_ofs
;
40 extern uint32_t rootfs_align
;
42 extern int strip_padding
;
43 extern int add_jffs2_eof
;
45 static unsigned char jffs2_eof_mark
[4] = {0xde, 0xad, 0xc0, 0xde};
47 void fill_header(char *buf
, int len
);
49 struct flash_layout
*find_layout(struct flash_layout
*layouts
, const char *id
)
51 struct flash_layout
*ret
;
52 struct flash_layout
*l
;
55 for (l
= layouts
; l
->id
!= NULL
; l
++){
56 if (strcasecmp(id
, l
->id
) == 0) {
65 void get_md5(const char *data
, int size
, uint8_t *md5
)
70 MD5_Update(&ctx
, data
, size
);
74 int get_file_stat(struct file_info
*fdata
)
79 if (fdata
->file_name
== NULL
)
82 res
= stat(fdata
->file_name
, &st
);
84 ERRS("stat failed on %s", fdata
->file_name
);
88 fdata
->file_size
= st
.st_size
;
92 int read_to_buf(const struct file_info
*fdata
, char *buf
)
95 int ret
= EXIT_FAILURE
;
97 f
= fopen(fdata
->file_name
, "r");
99 ERRS("could not open \"%s\" for reading", fdata
->file_name
);
104 fread(buf
, fdata
->file_size
, 1, f
);
106 ERRS("unable to read from file \"%s\"", fdata
->file_name
);
118 static int pad_jffs2(char *buf
, int currlen
, int maxlen
)
124 pad_mask
= (64 * 1024);
125 while ((len
< maxlen
) && (pad_mask
!= 0)) {
129 for (i
= 10; i
< 32; i
++) {
135 len
= ALIGN(len
, mask
);
137 for (i
= 10; i
< 32; i
++) {
139 if ((len
& (mask
- 1)) == 0)
143 for (i
= 0; i
< sizeof(jffs2_eof_mark
); i
++)
144 buf
[len
+ i
] = jffs2_eof_mark
[i
];
146 len
+= sizeof(jffs2_eof_mark
);
152 int write_fw(const char *ofname
, const char *data
, int len
)
155 int ret
= EXIT_FAILURE
;
157 f
= fopen(ofname
, "w");
159 ERRS("could not open \"%s\" for writing", ofname
);
164 fwrite(data
, len
, 1, f
);
166 ERRS("unable to write output file");
170 DBG("firmware file \"%s\" completed", ofname
);
177 if (ret
!= EXIT_SUCCESS
) {
184 /* Helper functions to inspect_fw() representing different output formats */
185 inline void inspect_fw_pstr(const char *label
, const char *str
)
187 printf("%-23s: %s\n", label
, str
);
190 inline void inspect_fw_phex(const char *label
, uint32_t val
)
192 printf("%-23s: 0x%08x\n", label
, val
);
195 inline void inspect_fw_phexdec(const char *label
, uint32_t val
)
197 printf("%-23s: 0x%08x / %8u bytes\n", label
, val
, val
);
200 inline void inspect_fw_pmd5sum(const char *label
, const uint8_t *val
, const char *text
)
204 printf("%-23s:", label
);
205 for (i
=0; i
<MD5SUM_LEN
; i
++)
206 printf(" %02x", val
[i
]);
207 printf(" %s\n", text
);
210 // header_size = sizeof(struct fw_header)
211 int build_fw(size_t header_size
)
216 int ret
= EXIT_FAILURE
;
219 writelen
= header_size
+ kernel_len
;
224 buflen
= layout
->fw_max_len
;
226 buf
= malloc(buflen
);
228 ERR("no memory for buffer\n");
232 memset(buf
, 0xff, buflen
);
233 p
= buf
+ header_size
;
234 ret
= read_to_buf(&kernel_info
, p
);
242 p
= buf
+ rootfs_ofs
;
244 ret
= read_to_buf(&rootfs_info
, p
);
249 writelen
+= rootfs_info
.file_size
;
251 writelen
= rootfs_ofs
+ rootfs_info
.file_size
;
254 writelen
= pad_jffs2(buf
, writelen
, layout
->fw_max_len
);
260 fill_header(buf
, writelen
);
261 ret
= write_fw(ofname
, buf
, writelen
);