1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * makeamitbin - create firmware binaries for MGB100
5 * Copyright (C) 2007 Volker Weiss <dev@tintuc.de>
6 * Christian Welzel <dev@welzel-online.ch>
15 /* defaults: Level One WAP-0007 */
16 static char *ascii1
= "DDC_RUS001";
17 static char *ascii2
= "Queen";
19 static struct hdrinfo
{
21 unsigned long unknown
; /* can probably be any number, maybe version number */
26 { "bios", 0xc76be111, 1, 0x3fa000, 0x006000 }, /* BIOS */
27 { "recovery", 0xc76be222, 0, 0x3f0000, 0x004000 }, /* Recovery Loader */
28 { "linux", 0xc76bee9d, 0, 0x000000, 0x100000 }, /* Linux */
29 { "ramdisk", 0xc76bee9d, 0, 0x100000, 0x280000 }, /* ramdisk */
30 { "amitconfig", 0xc76bee8b, 0, 0x380000, 0x060000 }, /* AMIT config */
31 { "redboot", 0x00000000, 1, 0x3d0000, 0x030000 }, /* Redboot 128kB image */
32 { "redbootlow", 0, 0, 0x3e0000, 0x18000 }, /* Redboot 1. part */
33 { "redboothigh", 0, 0, 0x3fa000, 0x6000 }, /* Redboot 2. part */
34 { "linux3g", 0xcb5f06b5, 0, 0x000000, 0x100000 }, /* Linux */
35 { "ramdisk3g", 0xcb5f06b5, 0, 0x100000, 0x280000 }, /* ramdisk */
50 20060106_DDC_WAP-0007_R400b4
70 WAP-0007(R4.00b8)_2006-10-02
83 #define COPY_SHORT(d, o, v) d[o+0] = (unsigned char)((v) & 0xff); \
84 d[o+1] = (unsigned char)(((v) >> 8) & 0xff)
85 #define COPY_LONG(d, o, v) d[o+0] = (unsigned char)((v) & 0xff); \
86 d[o+1] = (unsigned char)(((v) >> 8) & 0xff); \
87 d[o+2] = (unsigned char)(((v) >> 16) & 0xff); \
88 d[o+3] = (unsigned char)(((v) >> 24) & 0xff)
89 #define READ_SHORT(d, o) ((unsigned short)(d[o+0]) + \
90 (((unsigned short)(d[o+1])) << 8))
93 00..0d ASCII product ID
94 0e..0f checksum of payload
96 1c..1f AMIT BIOS: 11e1 6bc7, Recovery Tool: 22e2 6bc7
97 Linux: 5dc3 47c8, ramdisk: 5cc3 47c8
98 AMIT FS: 21c3 47c8 VERSION NUMBER??????
99 20..23 offset in flash aligned to segment boundary
100 24..27 length in flash aligned to segment boundary
101 28..2b offset in flash (payload)
102 2c..2f length (payload)
104 40..47 always 4248 0101 5000 0001 (last maybe .....0501)
105 48..4b same as 20..23
107 4e..4f inverted checksum of header
110 unsigned short checksum(unsigned char *data
, long size
)
113 unsigned short d
, cs
= 0;
114 for (n
= 0; n
< size
; n
+= 2)
116 d
= READ_SHORT(data
, n
);
131 void showhdr(unsigned char *hdr
)
134 for (j
= 0; j
< 5; j
++)
136 for (i
= 0; i
< 16; i
++)
138 printf("%02x ", (unsigned int)(hdr
[j
* 16 + i
]));
141 for (i
= 0; i
< 16; i
++)
143 unsigned char d
= hdr
[j
* 16 + i
];
144 printf("%c", (d
>= ' ' && d
< 127) ? d
: '.');
150 void makehdr(unsigned char *hdr
, struct hdrinfo
*info
,
151 unsigned char *data
, long size
, int last
)
153 unsigned int offset
= info
->addr
+ 0x10;
154 memset(hdr
, 0, HDRSIZE
);
156 offset
= info
->addr
+ info
->size
- size
; /* top align */
157 strncpy((char *)hdr
+ 0x00, ascii1
, 14);
158 strncpy((char *)hdr
+ 0x10, ascii2
, 12);
159 COPY_LONG(hdr
, 0x1c, info
->unknown
);
160 COPY_LONG(hdr
, 0x20, info
->addr
);
161 COPY_LONG(hdr
, 0x24, info
->size
);
162 COPY_LONG(hdr
, 0x28, offset
);
163 COPY_LONG(hdr
, 0x2c, size
);
164 COPY_LONG(hdr
, 0x40, 0x01014842);
165 COPY_LONG(hdr
, 0x44, last
? 0x01050050 : 0x01000050);
166 COPY_LONG(hdr
, 0x48, info
->addr
);
167 COPY_SHORT(hdr
, 0x4c, info
->unknown
== 0xcb5f06b5 ? 0x0016 : 0x000b);
168 COPY_SHORT(hdr
, 0x0e, checksum(data
, size
));
169 COPY_SHORT(hdr
, 0x4e, ~checksum(hdr
, HDRSIZE
));
172 unsigned char *read_file(const char *name
, long *size
)
175 unsigned char *data
= NULL
;
177 f
= fopen(name
, "r");
180 if (fseek(f
, 0, SEEK_END
) == 0)
185 if (fseek(f
, 0, SEEK_SET
) == 0)
187 data
= (unsigned char *)malloc(*size
);
190 if (fread(data
, sizeof(char), *size
, f
) != *size
)
204 struct hdrinfo
*find_hdrinfo(const char *name
)
207 for (n
= 0; hdrinfo
[n
].name
!= NULL
; n
++)
209 if (strcmp(name
, hdrinfo
[n
].name
) == 0)
215 void oferror(FILE *f
)
217 printf("file error\n");
223 printf("Syntax: makeamitbin [options]\n");
224 printf("Options:\n");
225 printf(" -1 ID1\tFirmware identifier 1, e.g. 'DDC_RUS001' for manufacturer LevelOne\n");
226 printf(" -2 ID2\tFirmware identifier 2, 'Queen' in all known cases\n");
227 printf(" -o FILE\tOutput file\n");
228 printf(" -ids\t\tShow a list of known firmware identifiers.\n");
232 void show_fwids(void)
234 printf("List of known firmware identifiers:\n");
235 printf("Manufacturer\t\tProduct\t\tIdentifier\n");
236 printf("=====================================================\n");
237 printf("Conceptronic\t\tCHD2WLANU\tLLM_RUS001\n");
238 printf("Pearl\t\t\tPE6643\t\tQueen\n");
239 printf("Micronica\t\tMGB100\t\tQueen\n");
240 printf("LevelOne\t\tWAP-0007\tDDC_RUS001\n");
241 printf("SMC\t\t\tWAPS-G\t\tSMC_RUS001\n");
242 printf("OvisLink (AirLive)\tWMU-6\t\tOVS_RUS001\n");
243 printf("SafeCom SWSAPUR-5\tFMW\t\tSafeco_RPS001\n");
247 int main(int argc
, char *argv
[])
249 unsigned char hdr
[HDRSIZE
];
252 char *outfile
= NULL
;
254 struct hdrinfo
*info
;
258 for (n
= 1; n
< argc
; n
++)
260 if (strcmp(argv
[n
], "-1") == 0)
262 if (strcmp(argv
[n
], "-2") == 0)
264 if (strcmp(argv
[n
], "-o") == 0)
266 if (strcmp(argv
[n
], "-ids") == 0)
269 if (ascii1
== NULL
|| ascii2
== NULL
|| outfile
== NULL
)
271 of
= fopen(outfile
, "w");
274 for (n
= 1; n
< argc
; n
++)
276 if (strncmp(argv
[n
], "-", 1) != 0)
281 last
= ((n
+ 1) >= argc
); /* dirty, options first! */
282 info
= find_hdrinfo(type
);
285 data
= read_file(argv
[n
], &size
);
288 makehdr(hdr
, info
, data
, size
, last
);
290 if (fwrite(hdr
, HDRSIZE
, 1, of
) != 1)
292 if (fwrite(data
, size
, 1, of
) != 1)