aboutsummaryrefslogtreecommitdiffstats
path: root/tools/firmware-utils/src/makeamitbin.c
blob: 5c334424e69cb26ffe29ebf2d47949a97f322d68 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
/*
 *  makeamitbin - create firmware binaries for MGB100
 *
 *  Copyright (C) 2007 Volker Weiss     <dev@tintuc.de>
 *                     Christian Welzel <dev@welzel-online.ch>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 * 
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 * 
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>


/* defaults: Level One WAP-0007 */
static char *ascii1 = "DDC_RUS001";
static char *ascii2 = "Queen";

static struct hdrinfo {
  char *name;
	unsigned long unknown; /* can probably be any number, maybe version number */
	int topalign;
	unsigned int addr;
	unsigned int size;
} hdrinfo[] = {
	{ "bios", 0xc76be111, 1, 0x3fa000, 0x006000 },        /* BIOS */
	{ "recovery", 0xc76be222, 0, 0x3f0000, 0x004000 },    /* Recovery Loader */
	{ "linux", 0xc76bee9d, 0, 0x000000, 0x100000 },       /* Linux */
	{ "ramdisk", 0xc76bee9d, 0, 0x100000, 0x280000 },     /* ramdisk */
	{ "amitconfig", 0xc76bee8b, 0, 0x380000, 0x060000 },  /* AMIT config */
	{ "redboot", 0x00000000, 1, 0x3d0000, 0x030000 },     /* Redboot 128kB image */
	{ "redbootlow", 0, 0, 0x3e0000, 0x18000 },            /* Redboot 1. part */
	{ "redboothigh", 0, 0, 0x3fa000, 0x6000 },            /* Redboot 2. part */
	{ "linux3g", 0xcb5f06b5, 0, 0x000000, 0x100000 },       /* Linux */
	{ "ramdisk3g", 0xcb5f06b5, 0, 0x100000, 0x280000 },     /* ramdisk */
	{ NULL }
};

/*
CHD2WLANU_R400b7

11e1 6bc7
22e2 6bc7
5dc3 47c8
5cc3 47c8
21c3 47c8
*/

/*
20060106_DDC_WAP-0007_R400b4

11e1 6bc7
22e2 6bc7
9dee 6bc7
9dee 6bc7
8bee 6bc7
*/

/*
WMU-6000FS_R400b6

11e1 6bc7
22e2 6bc7
6d2d 0fc8
6c2d 0fc8
542d 0fc8
*/

/*
WAP-0007(R4.00b8)_2006-10-02

9979 5fc8
22e2 6bc7
c46e cec8
c36e cec8
a76e cec8
*/



#define HDRSIZE              80

#define COPY_SHORT(d, o, v)  d[o+0] = (unsigned char)((v) & 0xff); \
                             d[o+1] = (unsigned char)(((v) >> 8) & 0xff)
#define COPY_LONG(d, o, v)   d[o+0] = (unsigned char)((v) & 0xff); \
                             d[o+1] = (unsigned char)(((v) >> 8) & 0xff); \
													   d[o+2] = (unsigned char)(((v) >> 16) & 0xff); \
													   d[o+3] = (unsigned char)(((v) >> 24) & 0xff)
#define READ_SHORT(d, o)     ((unsigned short)(d[o+0]) + \
                             (((unsigned short)(d[o+1])) << 8))

/*
00..0d ASCII product ID
0e..0f checksum of payload
10..1b ASCII Queen
1c..1f AMIT BIOS: 11e1 6bc7, Recovery Tool: 22e2 6bc7
       Linux: 5dc3 47c8, ramdisk: 5cc3 47c8
			 AMIT FS: 21c3 47c8    VERSION NUMBER??????
20..23 offset in flash aligned to segment boundary
24..27 length in flash aligned to segment boundary
28..2b offset in flash (payload)
2c..2f length (payload)
30..3f always 0
40..47 always 4248 0101 5000 0001 (last maybe .....0501)
48..4b same as 20..23
4c..4d always 0b00
4e..4f inverted checksum of header
*/

unsigned short checksum(unsigned char *data, long size)
{
	long n;
	unsigned short d, cs = 0;
	for (n = 0; n < size; n += 2)
	{
		d = READ_SHORT(data, n);
		cs += d;
		if (cs < d)
			cs++;
	}
	if (size & 1)
	{
		d = data[n];
		cs += d;
		if (cs < d)
			cs++;
	}
	return cs;
}

void showhdr(unsigned char *hdr)
{
	int i, j;
	for (j = 0; j < 5; j++)
	{
		for (i = 0; i < 16; i++)
		{
			printf("%02x ", (unsigned int)(hdr[j * 16 + i]));
		}
		printf("   ");
		for (i = 0; i < 16; i++)
		{
			unsigned char d = hdr[j * 16 + i];
			printf("%c", (d >= ' ' && d < 127) ? d : '.');
		}
		printf("\n");
	}
}

void makehdr(unsigned char *hdr, struct hdrinfo *info,
             unsigned char *data, long size, int last)
{
	unsigned int offset = info->addr + 0x10;
	memset(hdr, 0, HDRSIZE);
	if (info->topalign)
		offset = info->addr + info->size - size;	/* top align */
	strncpy((char *)hdr + 0x00, ascii1, 14);
	strncpy((char *)hdr + 0x10, ascii2, 12);
	COPY_LONG(hdr, 0x1c, info->unknown);
	COPY_LONG(hdr, 0x20, info->addr);
	COPY_LONG(hdr, 0x24, info->size);
	COPY_LONG(hdr, 0x28, offset);
	COPY_LONG(hdr, 0x2c, size);
	COPY_LONG(hdr, 0x40, 0x01014842);
	COPY_LONG(hdr, 0x44, last ? 0x01050050 : 0x01000050);
	COPY_LONG(hdr, 0x48, info->addr);
	COPY_SHORT(hdr, 0x4c, info->unknown == 0xcb5f06b5 ? 0x0016 : 0x000b);
	COPY_SHORT(hdr, 0x0e, checksum(data, size));
	COPY_SHORT(hdr, 0x4e, ~checksum(hdr, HDRSIZE));
}

unsigned char *read_file(const char *name, long *size)
{
	FILE *f;
	unsigned char *data = NULL;
	*size = 0;
	f = fopen(name, "r");
	if (f != NULL)
	{
		if (fseek(f, 0, SEEK_END) == 0)
		{
	    *size = ftell(f);
			if (*size != -1)
			{
				if (fseek(f, 0, SEEK_SET) == 0)
				{
					data = (unsigned char *)malloc(*size);
					if (data != NULL)
					{
						if (fread(data, sizeof(char), *size, f) != *size)
						{
							free(data);
							data = NULL;
						}
					}
				}
			}
		}
		fclose(f);
	}
	return data;
}

struct hdrinfo *find_hdrinfo(const char *name)
{
	int n;
	for (n = 0; hdrinfo[n].name != NULL; n++)
	{
		if (strcmp(name, hdrinfo[n].name) == 0)
			return &hdrinfo[n];
	}
	return NULL;
}

void oferror(FILE *f)
{
	printf("file error\n");
	exit(2);
}

void showhelp(void)
{
	printf("Syntax: makeamitbin [options]\n");
	printf("Options:\n");
	printf("  -1 ID1\tFirmware identifier 1, e.g. 'DDC_RUS001' for manufacturer LevelOne\n");
	printf("  -2 ID2\tFirmware identifier 2, 'Queen' in all known cases\n");
	printf("  -o FILE\tOutput file\n");
	printf("  -ids\t\tShow a list of known firmware identifiers.\n");
	exit(1);
}

void show_fwids(void)
{
	printf("List of known firmware identifiers:\n");
	printf("Manufacturer\t\tProduct\t\tIdentifier\n");
	printf("=====================================================\n");
	printf("Conceptronic\t\tCHD2WLANU\tLLM_RUS001\n");
	printf("Pearl\t\t\tPE6643\t\tQueen\n");
	printf("Micronica\t\tMGB100\t\tQueen\n");
	printf("LevelOne\t\tWAP-0007\tDDC_RUS001\n");
	printf("SMC\t\t\tWAPS-G\t\tSMC_RUS001\n");
	printf("OvisLink (AirLive)\tWMU-6\t\tOVS_RUS001\n");
	printf("SafeCom SWSAPUR-5\tFMW\t\tSafeco_RPS001\n");
	exit(1);
}

int main(int argc, char *argv[])
{
	unsigned char hdr[HDRSIZE];
	unsigned char *data;
	FILE *of;
	char *outfile = NULL;
	char *type;
	struct hdrinfo *info;
	long size;
	int last = 0;
	int n;
	for (n = 1; n < argc; n++)
	{
		if (strcmp(argv[n], "-1") == 0)
			ascii1 = argv[n+1];
		if (strcmp(argv[n], "-2") == 0)
			ascii2 = argv[n+1];
		if (strcmp(argv[n], "-o") == 0)
			outfile = argv[n+1];
		if (strcmp(argv[n], "-ids") == 0)
			show_fwids();
	}
	if (ascii1 == NULL || ascii2 == NULL || outfile == NULL)
		showhelp();
	of = fopen(outfile, "w");
	if (of == NULL)
		oferror(of);
	for (n = 1; n < argc; n++)
	{
		if (strncmp(argv[n], "-", 1) != 0)
		{
			type = argv[n++];
			if (n >= argc)
				showhelp();
			last = ((n + 1) >= argc);		/* dirty, options first! */
			info = find_hdrinfo(type);
			if (info == NULL)
				showhelp();
			data = read_file(argv[n], &size);
			if (data == NULL)
				showhelp();
			makehdr(hdr, info, data, size, last);
			/* showhdr(hdr); */
			if (fwrite(hdr, HDRSIZE, 1, of) != 1)
				oferror(of);
			if (fwrite(data, size, 1, of) != 1)
				oferror(of);
			free(data);
		}
		else
			n++;
	}
	if (fclose(of) != 0)
		oferror(NULL);
	return 0;
}
egister polling in place of the * global "Transmitting" flag. The change has been reverted in this release. Projects built upon the demo * should upgrade to the latest code. * - The HID class demos did not implement the mandatory GetReport HID class request. Projects built upon the HID * demos should upgrade to the latest code. * - The HID class demos incorrectly reported themselves as boot-protocol enabled HID devices in their descriptors. * Projects built upon the HID demos should upgrade to the latest code. * - The MIDI device demo had incorrect AudioStreaming interface descriptors. Projects built upon the MIDI demo * should upgrade to the latest code. * - The AudioOut demo did not correctly tristate the speaker pins when USB was disconnected, wasting power. * Projects built upon the AudioOut demo should upgrade to the latest code. * * * \section Sec_Migration141 Migrating from V1.4.1 to V1.5.0 * * <b>Library Demos</b> * - Previous versions of the library demos had incorrectly encoded BCD version numbers in the descriptors. To * avoid such mistakes in the future, the VERSION_BCD macro has been added to StdDescriptors.h. Existing * projects should at least manually correct the BCD version numbers, or preferably update the descriptors to * encode the version number in BCD format using the new macro. * - The mandatory GetReport class-specific request was accidentally omitted from previous versions of the demos * based on the Human Interface Device (HID) class. This has been corrected, and any user projects based on the * HID demos should also be updated accordingly. * - The CDC demos now correctly send an empty packet directly after a full packet, to end the transmission. * Failure to do this on projects which always or frequently send full packets will cause buffering issues on * the host OS. All CDC user projects are advised to update their transmission routines in the same manner as * the library CDC demos. * - The previous interrupt-driven Endpoint/Pipe demos did not properly save and restore the currently selected * Endpoint/Pipe when the ISR fired. This has been corrected - user projects based on the interrupt driven * demos should also update to properly save and restore the selected Endpoint/Pipe. * * <b>Non-USB Library Components</b> * - The Atomic.h and ISRMacro.h header files in MyUSB/Common have been removed, as the library is now only * compatible with avr-libc library versions newer than the time before the functionality of the deleted * headers was available. * * <b>Device Mode</b> * - The GetDescriptor function (see StdDescriptors.h) now has a new prototype, with altered parameter names and * functions. Existing projects will need to update the GetDescriptor implementation to reflect the new API. * The previously split Type and Index parameters are now passed as the original wValue parameter to the * function, to make way for the USB specification wIndex parameter which is <i>not</i> the same as the * previous Index parameter. * - The USB_UnhandledControlPacket event (see Events.h) now has new parameter names, to be in line with the * official USB specification. Existing code will need to be altered to use the new parameter names. * - The USB_CreateEndpoints event (see Events.h) has been renamed to USB_ConfigurationChanged, which is more * appropriate. It fires in an identical manner to the previously named event, thus the only change to be made * is the event name itself in the user project. * - The USB_Descriptor_Language_t structure no longer exists in StdDescriptors.h, as this was a * pseudo-descriptor modeled on the string descriptor. It is replaced by the true USB_Descriptor_String_t type * descriptor as indicated in the USB specification, thus all device code must be updated accordingly. * - The names of several Endpoint macros have been changed to be more consistent with the rest of the library, * with no implementation changes. This means that existing code can be altered to use the new macro names * with no other considerations required. See Endpoint.h for the new macro names. * - The previous version of the MassStorage demo had an incorrect value in the SCSI_Request_Sense_Response_t * structure named SenseData in SCSI.c which caused some problems with some hosts. User projects based on this * demo should correct the structure value to maintain compatibility across multiple OS platforms. * - By default, the descriptor structures use the official USB specification names for the elements. Previous * versions of the library used non-standard (but more verbose) names, which are still usable in the current * and future releases when the correct compile time option is enabled. See the StdDescriptors.h file * documentation for more details. * * <b>Host Mode</b> * - The USB_Host_Request_Header_t structure in HostChapter9.h (used for issuing control requests) has had its * members renamed to the official USB specification names for requests. Existing code will need to be updated * to use the new names. * - The names of several Pipe macros have been changed to be more consistent with the rest of the library, * with no implementation changes. This means that existing code can be altered to use the new macro names * with no other considerations required. See Pipe.h for the new macro names. * - By default, the descriptor structures use the official USB specification names for the elements. Previous * versions of the library used non-standard (but more verbose) names, which are still usable in the current * and future releases when the correct compile time option is enabled. See the StdDescriptors.h file * documentation for more details. * - The names of the macros in Host.h for controlling the SOF generation have been renamed, see the Host.h * module documentation for the new macro names. * * <b>Dual Role Mode</b> * - The OTG.h header file has been corrected so that the macros now perform their stated functions. Any existing * projects using custom headers to fix the broken OTG header should now be altered to once again use the OTG * header inside the library. * - The USB_DeviceEnumerationComplete event (see Events.h) now also fires in Device mode, when the host has * finished enumerating the device. Projects relying on the event only firing in Host mode should be updated * so that the event action only occurs when the USB_Mode global is set to USB_MODE_HOST. */