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

Sources/firmware-utils/src/makeamitbin.c

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 /*
  3  *  makeamitbin - create firmware binaries for MGB100
  4  *
  5  *  Copyright (C) 2007 Volker Weiss     <dev@tintuc.de>
  6  *                     Christian Welzel <dev@welzel-online.ch>
  7  */
  8 
  9 
 10 #include <stdlib.h>
 11 #include <stdio.h>
 12 #include <string.h>
 13 
 14 
 15 /* defaults: Level One WAP-0007 */
 16 static char *ascii1 = "DDC_RUS001";
 17 static char *ascii2 = "Queen";
 18 
 19 static struct hdrinfo {
 20   char *name;
 21         unsigned long unknown; /* can probably be any number, maybe version number */
 22         int topalign;
 23         unsigned int addr;
 24         unsigned int size;
 25 } hdrinfo[] = {
 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 */
 36         { NULL }
 37 };
 38 
 39 /*
 40 CHD2WLANU_R400b7
 41 
 42 11e1 6bc7
 43 22e2 6bc7
 44 5dc3 47c8
 45 5cc3 47c8
 46 21c3 47c8
 47 */
 48 
 49 /*
 50 20060106_DDC_WAP-0007_R400b4
 51 
 52 11e1 6bc7
 53 22e2 6bc7
 54 9dee 6bc7
 55 9dee 6bc7
 56 8bee 6bc7
 57 */
 58 
 59 /*
 60 WMU-6000FS_R400b6
 61 
 62 11e1 6bc7
 63 22e2 6bc7
 64 6d2d 0fc8
 65 6c2d 0fc8
 66 542d 0fc8
 67 */
 68 
 69 /*
 70 WAP-0007(R4.00b8)_2006-10-02
 71 
 72 9979 5fc8
 73 22e2 6bc7
 74 c46e cec8
 75 c36e cec8
 76 a76e cec8
 77 */
 78 
 79 
 80 
 81 #define HDRSIZE              80
 82 
 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))
 91 
 92 /*
 93 00..0d ASCII product ID
 94 0e..0f checksum of payload
 95 10..1b ASCII Queen
 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)
103 30..3f always 0
104 40..47 always 4248 0101 5000 0001 (last maybe .....0501)
105 48..4b same as 20..23
106 4c..4d always 0b00
107 4e..4f inverted checksum of header
108 */
109 
110 unsigned short checksum(unsigned char *data, long size)
111 {
112         long n;
113         unsigned short d, cs = 0;
114         for (n = 0; n < size; n += 2)
115         {
116                 d = READ_SHORT(data, n);
117                 cs += d;
118                 if (cs < d)
119                         cs++;
120         }
121         if (size & 1)
122         {
123                 d = data[n];
124                 cs += d;
125                 if (cs < d)
126                         cs++;
127         }
128         return cs;
129 }
130 
131 void showhdr(unsigned char *hdr)
132 {
133         int i, j;
134         for (j = 0; j < 5; j++)
135         {
136                 for (i = 0; i < 16; i++)
137                 {
138                         printf("%02x ", (unsigned int)(hdr[j * 16 + i]));
139                 }
140                 printf("   ");
141                 for (i = 0; i < 16; i++)
142                 {
143                         unsigned char d = hdr[j * 16 + i];
144                         printf("%c", (d >= ' ' && d < 127) ? d : '.');
145                 }
146                 printf("\n");
147         }
148 }
149 
150 void makehdr(unsigned char *hdr, struct hdrinfo *info,
151              unsigned char *data, long size, int last)
152 {
153         unsigned int offset = info->addr + 0x10;
154         memset(hdr, 0, HDRSIZE);
155         if (info->topalign)
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));
170 }
171 
172 unsigned char *read_file(const char *name, long *size)
173 {
174         FILE *f;
175         unsigned char *data = NULL;
176         *size = 0;
177         f = fopen(name, "r");
178         if (f != NULL)
179         {
180                 if (fseek(f, 0, SEEK_END) == 0)
181                 {
182             *size = ftell(f);
183                         if (*size != -1)
184                         {
185                                 if (fseek(f, 0, SEEK_SET) == 0)
186                                 {
187                                         data = (unsigned char *)malloc(*size);
188                                         if (data != NULL)
189                                         {
190                                                 if (fread(data, sizeof(char), *size, f) != *size)
191                                                 {
192                                                         free(data);
193                                                         data = NULL;
194                                                 }
195                                         }
196                                 }
197                         }
198                 }
199                 fclose(f);
200         }
201         return data;
202 }
203 
204 struct hdrinfo *find_hdrinfo(const char *name)
205 {
206         int n;
207         for (n = 0; hdrinfo[n].name != NULL; n++)
208         {
209                 if (strcmp(name, hdrinfo[n].name) == 0)
210                         return &hdrinfo[n];
211         }
212         return NULL;
213 }
214 
215 void oferror(FILE *f)
216 {
217         printf("file error\n");
218         exit(2);
219 }
220 
221 void showhelp(void)
222 {
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");
229         exit(1);
230 }
231 
232 void show_fwids(void)
233 {
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");
244         exit(1);
245 }
246 
247 int main(int argc, char *argv[])
248 {
249         unsigned char hdr[HDRSIZE];
250         unsigned char *data;
251         FILE *of;
252         char *outfile = NULL;
253         char *type;
254         struct hdrinfo *info;
255         long size;
256         int last = 0;
257         int n;
258         for (n = 1; n < argc; n++)
259         {
260                 if (strcmp(argv[n], "-1") == 0)
261                         ascii1 = argv[n+1];
262                 if (strcmp(argv[n], "-2") == 0)
263                         ascii2 = argv[n+1];
264                 if (strcmp(argv[n], "-o") == 0)
265                         outfile = argv[n+1];
266                 if (strcmp(argv[n], "-ids") == 0)
267                         show_fwids();
268         }
269         if (ascii1 == NULL || ascii2 == NULL || outfile == NULL)
270                 showhelp();
271         of = fopen(outfile, "w");
272         if (of == NULL)
273                 oferror(of);
274         for (n = 1; n < argc; n++)
275         {
276                 if (strncmp(argv[n], "-", 1) != 0)
277                 {
278                         type = argv[n++];
279                         if (n >= argc)
280                                 showhelp();
281                         last = ((n + 1) >= argc);               /* dirty, options first! */
282                         info = find_hdrinfo(type);
283                         if (info == NULL)
284                                 showhelp();
285                         data = read_file(argv[n], &size);
286                         if (data == NULL)
287                                 showhelp();
288                         makehdr(hdr, info, data, size, last);
289                         /* showhdr(hdr); */
290                         if (fwrite(hdr, HDRSIZE, 1, of) != 1)
291                                 oferror(of);
292                         if (fwrite(data, size, 1, of) != 1)
293                                 oferror(of);
294                         free(data);
295                 }
296                 else
297                         n++;
298         }
299         if (fclose(of) != 0)
300                 oferror(NULL);
301         return 0;
302 }
303 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt