1 // SPDX-License-Identifier: GPL-2.0-only
11 #if !defined(__BYTE_ORDER)
12 #error "Unknown byte order"
15 #if __BYTE_ORDER == __BIG_ENDIAN
16 #define cpu_to_be32(x) (x)
17 #elif __BYTE_ORDER == __LITTLE_ENDIAN
18 #define cpu_to_be32(x) bswap_32(x)
20 #error "Unsupported endianness"
26 #define DBG(...) {printf(__VA_ARGS__); }
31 #define ERR(...) {printf(__VA_ARGS__); }
34 * Fw Header Layout for Netgear / Sercomm devices (bytes)
36 * Size : 512 bytes + zipped image size
43 * swVer : 55-62 uint32_t in BE
45 * ChkSum : 511 Inverse value of the full image checksum while this location is 0x00
47 static const char* magic
= "sErCoMm"; /* 7 */
48 static const unsigned char version
[4] = { 0x00, 0x01, 0x00, 0x00 };
49 static const int header_sz
= 512;
50 static const int footer_sz
= 71;
52 static int is_header
= 1;
55 char* file_name
; /* name of the file */
56 char* file_data
; /* data of the file in memory */
57 u_int32_t file_size
; /* length of the file */
60 static u_int8_t
getCheckSum(char* data
, int len
) {
65 ERR("Invalid pointer provided!\n");
69 for (i
= 0; i
< len
; i
++) {
77 * read file into buffer
78 * add space for header/footer
80 static int copyToOutputBuf(struct file_info
* finfo
) {
88 if (!finfo
|| !finfo
->file_name
) {
89 ERR("Invalid pointer provided!\n");
93 DBG("Opening file: %s\n", finfo
->file_name
);
95 if (!(fp
= fopen(finfo
->file_name
, "rb"))) {
96 ERR("Error opening file: %s\n", finfo
->file_name
);
102 fseek(fp
, 0L, SEEK_END
);
107 ERR("Error getting filesize: %s\n", finfo
->file_name
);
113 extra_sz
= header_sz
;
117 extra_sz
= footer_sz
;
122 DBG("Filesize: %i\n", file_sz
);
123 finfo
->file_size
= file_sz
+ extra_sz
;
125 if (!(finfo
->file_data
= malloc(finfo
->file_size
))) {
126 ERR("Out of memory!\n");
131 /* init header/footer bytes */
132 memset(finfo
->file_data
+ hdr_pos
, 0, extra_sz
);
134 /* read file and take care of leading header if exists */
135 if (fread(finfo
->file_data
+ img_pos
, 1, file_sz
, fp
) != file_sz
) {
136 ERR("Error reading file %s\n", finfo
->file_name
);
141 DBG("File: read successful\n");
147 static int writeFile(struct file_info
* finfo
) {
150 if (!finfo
|| !finfo
->file_name
) {
151 ERR("Invalid pointer provided!\n");
155 DBG("Opening file: %s\n", finfo
->file_name
);
157 if (!(fp
= fopen(finfo
->file_name
, "w"))) {
158 ERR("Error opening file: %s\n", finfo
->file_name
);
162 DBG("Writing file: %s\n", finfo
->file_name
);
164 if (fwrite(finfo
->file_data
, 1, finfo
->file_size
, fp
) != finfo
->file_size
) {
165 ERR("Wanted to write, but something went wrong!\n");
174 static void usage(char* argv
[]) {
175 printf("Usage: %s [OPTIONS...]\n"
178 " -f add sercom footer (if absent, header)\n"
179 " -b <hwid> use hardware id specified with <hwid> (ASCII)\n"
180 " -r <hwrev> use hardware revision specified with <hwrev> (ASCII)\n"
181 " -v <version> set image version to <version> (decimal, hex or octal notation)\n"
182 " -i <file> input file\n"
186 int main(int argc
, char* argv
[]) {
187 struct file_info image
= { 0 };
198 c
= getopt(argc
, argv
, "b:i:r:v:f");
210 image
.file_name
= optarg
;
216 swVer
= (u_int32_t
) strtol(optarg
, NULL
, 0);
217 swVer
= cpu_to_be32(swVer
);
225 if (!hwID
|| !hwVer
|| !image
.file_name
) {
231 * copy input to buffer, add extra space for header/footer and return
234 hdr_offset
= copyToOutputBuf(&image
);
238 DBG("Filling header: %s %s %2X %s\n", hwID
, hwVer
, swVer
, magic
);
240 strncpy(image
.file_data
+ hdr_offset
+ 0, magic
, 7);
241 memcpy(image
.file_data
+ hdr_offset
+ 7, version
, sizeof(version
));
242 strncpy(image
.file_data
+ hdr_offset
+ 11, hwID
, 34);
243 strncpy(image
.file_data
+ hdr_offset
+ 45, hwVer
, 10);
244 memcpy(image
.file_data
+ hdr_offset
+ 55, &swVer
, sizeof(swVer
));
245 strncpy(image
.file_data
+ hdr_offset
+ 63, magic
, 7);
247 /* calculate checksum and invert checksum */
249 chkSum
= getCheckSum(image
.file_data
, image
.file_size
);
250 chkSum
= (chkSum
^ 0xFF) + 1;
251 DBG("Checksum for Image: %hhX\n", chkSum
);
253 /* write checksum to header */
254 image
.file_data
[511] = (char) chkSum
;
257 /* overwrite input file */
258 if (writeFile(&image
))