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