tools: add Broadcom cable modem firmware image creator
Signed-off-by: Florian Fainelli <florian@openwrt.org> SVN-Revision: 36873
This commit is contained in:
		| @@ -62,6 +62,7 @@ define Host/Compile | |||||||
| 	$(call cc, mkcameofw, -Wall) | 	$(call cc, mkcameofw, -Wall) | ||||||
| 	$(call cc,seama md5) | 	$(call cc,seama md5) | ||||||
| 	$(call cc,fix-u-media-header cyg_crc32,-Wall) | 	$(call cc,fix-u-media-header cyg_crc32,-Wall) | ||||||
|  | 	$(call cc,hcsmakeimage bcmalgo) | ||||||
| endef | endef | ||||||
|  |  | ||||||
| define Host/Install | define Host/Install | ||||||
|   | |||||||
							
								
								
									
										248
									
								
								tools/firmware-utils/src/bcmalgo.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										248
									
								
								tools/firmware-utils/src/bcmalgo.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,248 @@ | |||||||
|  | #include <stdlib.h> | ||||||
|  | #include <sys/types.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <inttypes.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include <getopt.h> | ||||||
|  | #include <unistd.h> | ||||||
|  | #include <sys/time.h> | ||||||
|  | #include <sys/stat.h> | ||||||
|  | #include "bcmalgo.h" | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #define UTIL_VERSION "0.1" | ||||||
|  | #define ENDIAN_REVERSE_NEEDED | ||||||
|  |  | ||||||
|  | uint32_t reverse_endian32 ( uint32_t data ) | ||||||
|  | { | ||||||
|  | #ifdef ENDIAN_REVERSE_NEEDED | ||||||
|  | 	return 0 | ( data & 0x000000ff ) << 24 | ||||||
|  | 	       | ( data & 0x0000ff00 ) << 8 | ||||||
|  | 	       | ( data & 0x00ff0000 ) >> 8 | ||||||
|  | 	       | ( data & 0xff000000 ) >> 24; | ||||||
|  | #else | ||||||
|  | 	return data; | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  |  | ||||||
|  | uint16_t reverse_endian16 ( uint16_t data ) | ||||||
|  | { | ||||||
|  | #ifdef ENDIAN_REVERSE_NEEDED | ||||||
|  | 	return 0 | ( data & 0x00ff ) << 8 | ||||||
|  | 	       | ( data & 0xff00 ) >> 8; | ||||||
|  | #else | ||||||
|  | 	return data; | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | uint32_t get_buffer_crc ( char* filebuffer,size_t size ) | ||||||
|  | { | ||||||
|  |  | ||||||
|  | 	long crc=0xffffffffL; | ||||||
|  | 	long crcxor = 0xffffffffL; | ||||||
|  | 	long num4 = 0xffffffffL; | ||||||
|  | 	long num5 = size; | ||||||
|  | 	long num6 = 0x4c11db7L; | ||||||
|  | 	long num7 = 0x80000000L; | ||||||
|  | 	int i; | ||||||
|  | 	long j; | ||||||
|  | 	for ( i = 0; i < ( num5 ); i++ ) | ||||||
|  | 	{ | ||||||
|  | 		long num2 = filebuffer[i]; | ||||||
|  | 		for ( j = 0x80L; j != 0L; j = j >> 1 ) | ||||||
|  | 		{ | ||||||
|  | 			long num3 = crc & num7; | ||||||
|  | 			crc = crc << 1; | ||||||
|  | 			if ( ( num2 & j ) != 0L ) | ||||||
|  | 			{ | ||||||
|  | 				num3 ^= num7; | ||||||
|  | 			} | ||||||
|  | 			if ( num3 != 0L ) | ||||||
|  | 			{ | ||||||
|  | 				crc ^= num6; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	crc ^= crcxor; | ||||||
|  | 	crc &= num4; | ||||||
|  |  | ||||||
|  | 	uint8_t b1 = ( uint8_t ) ( ( crc & -16777216L ) >> 0x18 ); | ||||||
|  | 	uint8_t b2 = ( uint8_t ) ( ( crc & 0xff0000L ) >> 0x10 ); | ||||||
|  | 	uint8_t b3 = ( uint8_t ) ( ( crc & 0xff00L ) >> 8 ); | ||||||
|  | 	uint8_t b4 = ( uint8_t ) ( crc & 0xffL ); | ||||||
|  | 	int32_t crc_result = ( b1 | b2 << 8| b3 << 16| b4 <<24 ); | ||||||
|  | 	return reverse_endian32 ( crc_result ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //Thnx to Vector for the algo. | ||||||
|  | uint32_t get_file_crc ( char* filename ) | ||||||
|  | { | ||||||
|  | 	struct stat buf; | ||||||
|  | 	stat ( filename,&buf ); | ||||||
|  | 	char* filebuffer = malloc ( buf.st_size+10 ); | ||||||
|  | 	FILE* fd = fopen ( filename,"r" ); | ||||||
|  | 	fread ( filebuffer, 1, buf.st_size,fd ); | ||||||
|  | 	fclose ( fd ); | ||||||
|  | 	uint32_t crc = get_buffer_crc ( filebuffer,buf.st_size ); | ||||||
|  | 	free ( filebuffer ); | ||||||
|  | 	return crc; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | uint16_t get_hcs ( ldr_header_t* hd ) | ||||||
|  | { | ||||||
|  | 	uint8_t* head = ( uint8_t* ) hd; | ||||||
|  | 	uint8_t hcs_minor; | ||||||
|  | 	uint8_t hcs_major; | ||||||
|  | 	uint16_t n = 0xffff; | ||||||
|  | 	uint16_t m = 0; | ||||||
|  | 	int state = 0; | ||||||
|  | 	int i,j; | ||||||
|  | 	for ( i = 0; i < 0x54; i++ ) | ||||||
|  | 	{ | ||||||
|  | 		uint16_t m = head[i]; | ||||||
|  | 		m = m << 8; | ||||||
|  | 		for ( j = 0; j < 8; j++ ) | ||||||
|  | 		{ | ||||||
|  | 			if ( ( ( n ^ m ) & 0x8000 ) == 0 ) | ||||||
|  | 			{ | ||||||
|  | 				state = 0; | ||||||
|  | 			} | ||||||
|  | 			else | ||||||
|  | 			{ | ||||||
|  | 				state = 1; | ||||||
|  | 			} | ||||||
|  | 			n = n << 1; | ||||||
|  | 			if ( state ) | ||||||
|  | 			{ | ||||||
|  | 				n ^= 0x1021; | ||||||
|  | 			} | ||||||
|  | 			m = m << 1; | ||||||
|  | 		} | ||||||
|  | 		n &= 0xffff; | ||||||
|  | 	} | ||||||
|  | 	n ^= 0xffff; | ||||||
|  | 	hcs_major = ( uint8_t ) ( ( n & 0xff00 ) >> 8 ); | ||||||
|  | 	hcs_minor = ( uint8_t ) ( n & 0xff ); | ||||||
|  | 	uint16_t hcs = hcs_major <<8 | hcs_minor; | ||||||
|  | 	return hcs; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | ldr_header_t* construct_header ( uint32_t magic, uint16_t rev_maj,uint16_t rev_min, uint32_t build_date, uint32_t filelen, uint32_t ldaddress, const char* filename, uint32_t crc_data ) | ||||||
|  | { | ||||||
|  | 	ldr_header_t* hd = malloc ( sizeof ( ldr_header_t ) ); | ||||||
|  | 	hd->magic=reverse_endian16 ( magic ); | ||||||
|  | 	hd->control=0; //FixMe: Make use of it once compression is around | ||||||
|  | 	hd->rev_min = reverse_endian16 ( rev_min ); | ||||||
|  | 	hd->rev_maj = reverse_endian16 ( rev_maj ); | ||||||
|  | 	hd->build_date = reverse_endian32 ( build_date ); | ||||||
|  | 	hd->filelen = reverse_endian32 ( filelen ); | ||||||
|  | 	hd->ldaddress = reverse_endian32 ( ldaddress ); | ||||||
|  | 	printf ( "Creating header for %s...\n", filename ); | ||||||
|  | 	if ( strlen ( filename ) >63 ) | ||||||
|  | 	{ | ||||||
|  | 		printf ( "[!] Filename too long - stripping it to 63 bytes.\n" ); | ||||||
|  | 		strncpy ( ( char* ) &hd->filename, filename, 63 ); | ||||||
|  | 		hd->filename[63]=0x00; | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		strcpy ( ( char* ) &hd->filename, filename ); | ||||||
|  | 	} | ||||||
|  | 	hd->crc=reverse_endian32 ( crc_data ); | ||||||
|  | 	hd->hcs = reverse_endian16 ( get_hcs ( hd ) ); | ||||||
|  | 	return hd; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static char control_unc[]  = "Uncompressed"; | ||||||
|  | static char control_lz[]   = "LZRW1/KH"; | ||||||
|  | static char control_mlzo[] = "mini-LZO"; | ||||||
|  | static char control_nrv[] = "NRV2D99 [Bootloader?]"; | ||||||
|  | static char control_nstdlzma[] = "(non-standard) LZMA"; | ||||||
|  | static char control_unk[] = "Unknown"; | ||||||
|  | char* get_control_info ( uint16_t control ) | ||||||
|  | { | ||||||
|  | 	control = reverse_endian16 ( control ); | ||||||
|  | 	switch ( control ) | ||||||
|  | 	{ | ||||||
|  | 		case 0: | ||||||
|  | 			return control_unc; | ||||||
|  | 			break; | ||||||
|  | 		case 1: | ||||||
|  | 			return control_lz; | ||||||
|  | 			break; | ||||||
|  | 		case 2: | ||||||
|  | 			return control_mlzo; | ||||||
|  | 			break; | ||||||
|  | 		case 3: | ||||||
|  | 			return control_unc; | ||||||
|  | 			break; | ||||||
|  | 		case 4: | ||||||
|  | 			return control_nrv; | ||||||
|  | 			break; | ||||||
|  | 		case 5: | ||||||
|  | 			return control_nstdlzma; | ||||||
|  | 			break; | ||||||
|  | 		case 6: | ||||||
|  | 			return control_unc; | ||||||
|  | 			break; | ||||||
|  | 		case 7: | ||||||
|  | 			return control_unc; | ||||||
|  | 			break; | ||||||
|  | 		default: | ||||||
|  | 			return control_unk; | ||||||
|  | 			break; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int dump_header ( ldr_header_t* hd ) | ||||||
|  | { | ||||||
|  | 	printf ( "=== Header Information ===\n" ); | ||||||
|  | 	printf ( "Header magic:\t0x%04X\n",reverse_endian16 ( hd->magic ) ); | ||||||
|  | 	printf ( "Control:\t0x%04X (%s)\n",reverse_endian16 ( hd->control ), get_control_info ( hd->control ) ); | ||||||
|  | 	printf ( "Major rev. :\t0x%04X\n",reverse_endian16 ( hd->rev_maj ) ); | ||||||
|  | 	printf ( "Minor rev. :\t0x%04X\n",reverse_endian16 ( hd->rev_min ) ); | ||||||
|  | 	printf ( "File name :\t%s\n", ( char* ) &hd->filename ); | ||||||
|  | 	printf ( "File length:\t%d bytes\n", reverse_endian32 ( hd->filelen ) ); | ||||||
|  | 	printf ( "Build time:\t0x%08X //FixMe: print in human-readable form\n", reverse_endian32 ( hd->build_date ) ); //FixMe: | ||||||
|  | 	printf ( "HCS:\t\t0x%04X  ",reverse_endian16 ( hd->hcs ) ); | ||||||
|  | 	uint16_t hcs = get_hcs ( hd ); | ||||||
|  | 	int ret=0; | ||||||
|  | 	if ( hcs ==reverse_endian16 ( hd->hcs ) ) | ||||||
|  | 	{ | ||||||
|  | 		printf ( "(OK!)\n" ); | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		printf ( "(ERROR! expected 0x%04X)\n",hcs ); | ||||||
|  | 		ret=1; | ||||||
|  | 	} | ||||||
|  | //printf("HCS:\t0x%02X",reverse_endian32(hd->hcs)); | ||||||
|  | 	printf ( "Load address:\t0x%08X\n", reverse_endian32 ( hd->ldaddress ) ); //FixMe: | ||||||
|  | 	printf ( "HNW:\t\t0x%04X\n",reverse_endian16 ( hd->her_znaet_chto ) ); //Hell knows what | ||||||
|  | 	printf ( "CRC:\t\t0x%08X\n",reverse_endian32 ( hd->crc ) ); | ||||||
|  | 	printf ( "=== Binary Header Dump===\n" ); | ||||||
|  | 	int i,j; | ||||||
|  | 	uint8_t* head = ( uint8_t* ) hd; | ||||||
|  | 	for ( i=0;i<=sizeof ( ldr_header_t );i++ ) | ||||||
|  | 	{ | ||||||
|  | 		if ( i % 8==0 ) | ||||||
|  | 			printf ( "\n" ); | ||||||
|  | 		printf ( "0x%02x   ",head[i] ); | ||||||
|  | 	} | ||||||
|  | 	printf ( "\n\n== End Of Header dump ==\n" ); | ||||||
|  | 	return ret; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void print_copyright() | ||||||
|  | { | ||||||
|  | 	printf ( "Part of bcm-utils package ver. " UTIL_VERSION " \n" ); | ||||||
|  | 	printf ( "Copyright (C) 2009  Andrew 'Necromant' Andrianov\n" | ||||||
|  | 	         "This is free software, and you are welcome to redistribute it\n" | ||||||
|  | 	         "under certain conditions. See COPYING for details\n" ); | ||||||
|  | } | ||||||
							
								
								
									
										83
									
								
								tools/firmware-utils/src/bcmalgo.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								tools/firmware-utils/src/bcmalgo.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,83 @@ | |||||||
|  | #ifndef bcmutils_H | ||||||
|  | #define bcmutils_H | ||||||
|  |  | ||||||
|  | typedef struct | ||||||
|  | { | ||||||
|  | 	uint16_t magic; | ||||||
|  | 	uint16_t control; | ||||||
|  | 	uint16_t rev_maj; | ||||||
|  | 	uint16_t rev_min; | ||||||
|  | 	uint32_t build_date; | ||||||
|  | 	uint32_t filelen; | ||||||
|  | 	uint32_t ldaddress; | ||||||
|  | 	char filename[64]; | ||||||
|  | 	uint16_t hcs; | ||||||
|  | 	uint16_t her_znaet_chto; //v dushe ne ebu | ||||||
|  | 	uint32_t crc; | ||||||
|  | } ldr_header_t; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Reverses endianess of a 32bit int, if the ENDIAN_REVERSE_NEEDED defined at compile-time | ||||||
|  |  * @param data | ||||||
|  |  * @return | ||||||
|  |  */ | ||||||
|  | uint32_t reverse_endian32 ( uint32_t data ); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Reverses endianess of a 16bit int, if the ENDIAN_REVERSE_NEEDED defined at compile-time | ||||||
|  |  * @param data | ||||||
|  |  * @return | ||||||
|  |  */ | ||||||
|  | uint16_t reverse_endian16 ( uint16_t data ); | ||||||
|  | /** | ||||||
|  |  * Calculates the strange crc (used by bcm modems) of the file. Thnx fly out to Vector for the algorithm. | ||||||
|  |  * @param filename | ||||||
|  |  * @return | ||||||
|  |  */ | ||||||
|  | uint32_t get_file_crc ( char* filename ); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Calculates HCS of the header. | ||||||
|  |  * @param hd | ||||||
|  |  * @return | ||||||
|  |  */ | ||||||
|  | uint16_t get_hcs ( ldr_header_t* hd ); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Constructs the header of the image with the information given It also automagically calculates HCS and writes it there. | ||||||
|  |  * @param magic - magic device bytes | ||||||
|  |  * @param rev_maj - major revision | ||||||
|  |  * @param rev_min - minor revision | ||||||
|  |  * @param build_date - build date (seconds from EPOCH UTC) | ||||||
|  |  * @param filelen - file length in bytes | ||||||
|  |  * @param ldaddress - Load adress | ||||||
|  |  * @param filename - filename | ||||||
|  |  * @param crc_data - the crc of the data | ||||||
|  |  * @return | ||||||
|  |  */ | ||||||
|  | ldr_header_t* construct_header ( uint32_t magic, uint16_t rev_maj,uint16_t rev_min, uint32_t build_date, uint32_t filelen, uint32_t ldaddress, const char* filename, uint32_t crc_data ); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Dumps header information to stdout. | ||||||
|  |  * @param hd | ||||||
|  |  */ | ||||||
|  | int dump_header ( ldr_header_t* hd ); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Returns a null terminated string describing what the control number meens | ||||||
|  |  * DO NOT FREE IT!!! | ||||||
|  |  * @param control | ||||||
|  |  * @return | ||||||
|  |  */ | ||||||
|  | char* get_control_info ( uint16_t control ); | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Calculates bcmCRC of a data buffer. | ||||||
|  |  * @param filebuffer - pointer to buffer | ||||||
|  |  * @param size - buffer size | ||||||
|  |  * @return | ||||||
|  |  */ | ||||||
|  | uint32_t get_buffer_crc ( char* filebuffer, size_t size ); | ||||||
							
								
								
									
										181
									
								
								tools/firmware-utils/src/hcsmakeimage.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										181
									
								
								tools/firmware-utils/src/hcsmakeimage.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,181 @@ | |||||||
|  | #include <stdlib.h> | ||||||
|  | #include <sys/types.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <inttypes.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include <getopt.h> | ||||||
|  | #include <unistd.h> | ||||||
|  | #include <sys/time.h> | ||||||
|  | #include <sys/stat.h> | ||||||
|  | #include <libgen.h> | ||||||
|  | #include "bcmalgo.h" | ||||||
|  |  | ||||||
|  |  | ||||||
|  | int flag_print_version; | ||||||
|  | int flag_print_help; | ||||||
|  | int flag_compress; | ||||||
|  |  | ||||||
|  | uint16_t sa2100_magic  = 0x2100; | ||||||
|  | uint16_t sa3349_magic  = 0x3349; | ||||||
|  | uint32_t default_date = 0x00000000; //A long time ago in a galaxy far far away.... | ||||||
|  | uint32_t default_load_address = 0x80010000; //The default load_address for the firmware image | ||||||
|  |  | ||||||
|  | static void print_help ( const char* ename ) | ||||||
|  | { | ||||||
|  | 	printf ( "Firmware image packer and calculator for broadcom-based modems.\n" ); | ||||||
|  | 	printf ( "Part of bcm-utils package.\n" ); | ||||||
|  | 	printf ( "(c) 2009 Necromant (http://necromant.ath.cx). Thanks to Luke-jr for his initial work.\n" ); | ||||||
|  | 	printf ( "usage: %s [options]\n", ename ); | ||||||
|  | 	printf ( "Valid options are:\n" ); | ||||||
|  | 	printf ( "--magic_bytes=value \t- specify magic bytes at the beginning of the image. default - 3349\n" ); | ||||||
|  | 	printf ( "\t\t\t these can be sa2100 (for DPC2100 modem),\n\t\t\t sa3349 (haxorware guys use this one for some reason),\n\t\t\t or a custom hex value e.g. 0xFFFF\n" ); | ||||||
|  | 	printf ( "--compress \t\t - Make use of LZMA (weird!) compression (Doesn't work yet).\n" ); | ||||||
|  | 	printf ( "--rev_maj=value\t\t - major revision number. default 0\n" ); | ||||||
|  | 	printf ( "--rev_min=value\t\t - minor revision number default 0\n" ); | ||||||
|  | 	printf ( "--filename=value\t - use this filename in header instead of default (input filename)\n" ); | ||||||
|  | 	printf ( "--ldaddress=value\t - hex value of the target load address. defaults to 0x80010000\n" ); | ||||||
|  | 	printf ( "--input_file=value\t - What file are we packing?\n" ); | ||||||
|  | 	printf ( "--output_file=value\t - What file shall we write? (default: image.bin)\n" ); | ||||||
|  | #ifdef _HAX0RSTYLE | ||||||
|  | 	printf ( "--credz\t - Give some credz!\n" ); | ||||||
|  | #endif | ||||||
|  | 	printf ( "\n" ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | int main ( int argc, char** argv ) | ||||||
|  | { | ||||||
|  | 	if ( argc<2 ) | ||||||
|  | 	{ | ||||||
|  | 		print_help ( argv[0] ); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	static struct option long_options[] = | ||||||
|  | 	{ | ||||||
|  | 		{"magic_bytes",          required_argument,   0,        'm'}, | ||||||
|  | 		{"rev_maj",        required_argument,   0,      'j'}, | ||||||
|  | 		{"rev_min",       required_argument,   0,     'n'}, | ||||||
|  | 		{"ldaddress",       required_argument,   0,     'l'}, | ||||||
|  | 		{"filename",       required_argument,   0,     'f'}, | ||||||
|  | 		{"input_file",       required_argument,   0,     'i'}, | ||||||
|  | 		{"output_file",       required_argument,   0,     'o'}, | ||||||
|  | 		{"compress",     no_argument,       &flag_compress,    'c'}, | ||||||
|  | 		{"version",     no_argument,       &flag_print_version,    'v'}, | ||||||
|  | 		{"help",        no_argument,       &flag_print_help,    'h'}, | ||||||
|  | 		{0, 0, 0, 0} | ||||||
|  | 	}; | ||||||
|  | 	int option_index = 0; | ||||||
|  | 	int opt_result=0; | ||||||
|  | 	char* filename=NULL; | ||||||
|  | 	char* input=NULL; | ||||||
|  | 	char* magic=NULL; | ||||||
|  | 	char* major=NULL; | ||||||
|  | 	char* minor=NULL; | ||||||
|  | 	char* ldaddr=NULL; | ||||||
|  | 	char* output=NULL; | ||||||
|  |  | ||||||
|  | 	while ( opt_result>=0 ) | ||||||
|  | 	{ | ||||||
|  | 		opt_result = getopt_long ( argc, argv, "m:j:n:f:i:o:vh", long_options, &option_index ); | ||||||
|  | 		switch ( opt_result ) | ||||||
|  | 		{ | ||||||
|  | 			case 0: | ||||||
|  | 				printf ( "o!\n" ); | ||||||
|  | 				break; | ||||||
|  | 			case 'h': | ||||||
|  | 				print_help ( argv[0] ); | ||||||
|  | 				break; | ||||||
|  | 			case 'l': | ||||||
|  | 				ldaddr=optarg; | ||||||
|  | 				break; | ||||||
|  | 			case 'f': | ||||||
|  | 				filename=optarg; | ||||||
|  | 				break; | ||||||
|  | 			case 'i': | ||||||
|  | 				input=optarg; | ||||||
|  | 				break; | ||||||
|  | 			case 'o': | ||||||
|  | 				output=optarg; | ||||||
|  | 				break; | ||||||
|  | 			case 'm': | ||||||
|  | 				magic=optarg; | ||||||
|  | 				break; | ||||||
|  | 			case 'j': | ||||||
|  | 				major=optarg; | ||||||
|  | 				break; | ||||||
|  | 			case 'n': | ||||||
|  | 				minor=optarg; | ||||||
|  | 				break; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	if ( input==NULL ) | ||||||
|  | 	{ | ||||||
|  | 		printf ( "Telepaths are still on holidays. I guess you should tell me what file should I process.\n\n" ); | ||||||
|  | 		exit ( 1 ); | ||||||
|  | 	} | ||||||
|  | 	if ( access ( input,R_OK ) !=0 ) | ||||||
|  | 	{ | ||||||
|  | 		printf ( "I cannot access the file %s. Is it there? Am I allowed?\n\n", input ); | ||||||
|  | 		exit ( 1 ); | ||||||
|  | 	} | ||||||
|  | 	uint32_t magicnum=sa2100_magic; | ||||||
|  |  | ||||||
|  | 	if ( magic ) | ||||||
|  | 	{ | ||||||
|  | 		if ( strcmp ( magic,"sa2100" ) ==0 ) magicnum=sa2100_magic; else | ||||||
|  | 				if ( strcmp ( magic,"sa3349" ) ==0 ) magicnum=sa3349_magic; else | ||||||
|  | 			{ | ||||||
|  | 				sscanf ( magic, "0x%04X", &magicnum ); | ||||||
|  | 			} | ||||||
|  | 	} | ||||||
|  | 	unsigned int majrev=0; | ||||||
|  | 	if ( major ) | ||||||
|  | 	{ | ||||||
|  | 		sscanf ( major, "%d", &majrev ); | ||||||
|  | 	} | ||||||
|  | 	unsigned int minrev=0; | ||||||
|  | 	if ( minor ) | ||||||
|  | 	{ | ||||||
|  | 		sscanf ( minor, "%d", &minrev ); | ||||||
|  | 	} | ||||||
|  | 	uint32_t ldaddress = default_load_address; | ||||||
|  | 	if ( ldaddr ) | ||||||
|  | 	{ | ||||||
|  | 		sscanf ( ldaddr, "0x%08X", &ldaddress ); | ||||||
|  | 	} | ||||||
|  | 	char* dupe = strdup(input); | ||||||
|  | 	char* fname = basename ( dupe ); | ||||||
|  | 	if ( filename ) | ||||||
|  | 	{ | ||||||
|  | 		fname = filename; | ||||||
|  | 	} | ||||||
|  | 	struct timeval tm; | ||||||
|  | 	gettimeofday ( &tm,NULL ); | ||||||
|  | 	struct stat buf; | ||||||
|  | 	stat ( input,&buf ); | ||||||
|  | 	ldr_header_t* head = construct_header ( magicnum, (uint16_t) majrev, (uint16_t) minrev, ( uint32_t ) tm.tv_sec, ( uint32_t ) buf.st_size, ldaddress, fname, get_file_crc ( input ) ); | ||||||
|  | 	free(dupe); | ||||||
|  | 	//uint32_t magic, uint16_t rev_maj,uint16_t rev_min, uint32_t build_date, uint32_t filelen, uint32_t ldaddress, const char* filename, uint32_t crc | ||||||
|  | 	//FILE* fd = fopen ("/tftpboot/haxorware11rev32.bin","r"); | ||||||
|  | 	//fread(head,sizeof(ldr_header_t),1,fd); | ||||||
|  | 	char* filebuffer = malloc ( buf.st_size+10 ); | ||||||
|  | 	FILE* fd = fopen ( input,"r" ); | ||||||
|  | 	fread ( filebuffer, 1, buf.st_size,fd ); | ||||||
|  | 	if (!output) | ||||||
|  | 		{ | ||||||
|  | 		output = malloc(strlen(input+5)); | ||||||
|  | 		strcpy(output,input); | ||||||
|  | 		strcat(output,".bin"); | ||||||
|  | 		} | ||||||
|  | 	dump_header ( head ); | ||||||
|  | 	FILE* fd_out = fopen ( output,"w+" ); | ||||||
|  | 	if (!fd_out) | ||||||
|  | 		{ | ||||||
|  | 		fprintf(stderr, "Failed to open output file: %s\n", output); | ||||||
|  | 		exit(1); | ||||||
|  | 		} | ||||||
|  | 	fwrite ( head,1,sizeof ( ldr_header_t ),fd_out ); | ||||||
|  | 	fwrite ( filebuffer,1,buf.st_size,fd_out ); | ||||||
|  | 	printf("Firmware image %s is ready\n", output); | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user
	 Florian Fainelli
					Florian Fainelli