> andy:~$ gcc -o firmware firmware.c -DSTANDALONE_EXTRACTER > firmware.c:43:17: crc.h: No such file or directory > firmware.c:529:17: crc.c: No such file or directory > andy:~$ > > Looks like it needs crc.c and crc.h.
Yes, sorry about that. I've included all needed files at the end of this email. > So I untarred the speedtouch-1.3.1, > cd'd into speedtouch-1.3.1/src and then did > > gcc -o firmware firmware.c -DSTANDALONE_EXTRACTER > > That worked fine. Except that it's not quite the same firmware.c... > > Then do > > > > ./firmware KQD6_3.012 > > > > This will create speedtch-1.bin and speedtch-2.bin. > > > > I copied the KQD6_3.012 into speedtouch-1.3.1/src and then did > > andy:~/Desktop/speedtouch-1.3.1/src$ ./firmware KQD6_3.012 > Firmware info (CRC:0xd80bf9f7, Size:991, Checked: Yes, Alcatel/Thomson > Boot block (old)) > Firmware info (CRC:0x78039fed, Size:762650, Checked: Yes, 3.0.6 - MacOSX > - Win32) > ** Boot block from KQD6_3.012: > CRC: 0xd80bf9f7 > Length: 991 > ** Firmware block from KQD6_3.012: > CRC: 0x78039fed > Length: 762650 > andy:~/Desktop/speedtouch-1.3.1/src$ > > > > That made two files, boot.bin and firmware.bin. Were these the > speedtch-1.bin and speedtch-2.bin that you were referring to? Yes. The difference between the firmware.c I supplied and the one from the user space driver is simply that it names the files speedtch-1.bin etc. > I renamed > them speedtch-1.bin (the small one, 991 bytes) and speedtch-2.bin and > copied them to /lib/firmware. But when I reboot, no joy, the firmware > doesn't load. I think I'm getting close here but I'm not sure. Perhaps > the problem is with hotplug? If you compile your kernel with CONFIG_USB_DEBUG=y then you will get a pile of maybe helpful messages in your system logs. Even without this config setting, various messages are printed so please check the logs. Ciao, Duncan. ===> crc.h /* * ALCATEL SpeedTouch USB modem utility : CRC lib * Copyright (C) 2001 Edouard Gomez * * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Author : Edouard Gomez ([EMAIL PROTECTED]) * Creation : 08/08/2001 * * $Id: crc.h,v 1.1 2004/10/15 15:00:56 duncan Exp $ */ #ifndef _CRC_H_ #define _CRC_H_ /****************************************************************************** * Constants ******************************************************************************/ #define AAL5_CRC32_REMAINDER 0xCBF43926 #define AAL5_CRC32_INITIAL 0xffffffff #define ATM_HEADER_REMAINDER 0x107 #define ATM_HEADER_COSET_LEADER 0x055 /****************************************************************************** * Prototype ******************************************************************************/ extern unsigned int aal5_calc_crc(unsigned char *mem, int len, unsigned int initial); extern unsigned char atm_calc_hec(unsigned char *header); #endif ===> crc.c /* * ALCATEL SpeedTouch USB modem utility : CRC lib * Copyright (C) 2001 Edouard Gomez * * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Author : Edouard Gomez ([EMAIL PROTECTED]) * Creation : 08/08/2001 * * $Id: crc.c,v 1.1 2004/10/15 15:00:56 duncan Exp $ */ #ifndef _CRC_C_ #define _CRC_C_ /* Some stuff */ #include "crc.h" /****************************************************************************** * Macros (This is used to speedup code in the calc_crc first while loop) ******************************************************************************/ #define DO1(c, crc) ((crc) = crc32tab[((unsigned int)((crc)>>24) ^ (*c++)) & 0xff] ^ ((crc) << 8)) #define DO2(c, crc) DO1(c, crc); DO1(c, crc); #define DO4(c, crc) DO2(c, crc); DO2(c, crc); #define DO8(c, crc) DO4(c, crc); DO4(c, crc); /****************************************************************************** * Precomputed AAL5 CRC32 lookup table ******************************************************************************/ static unsigned long crc32tab[256] = { 0x00000000L, 0x04C11DB7L, 0x09823B6EL, 0x0D4326D9L, 0x130476DCL, 0x17C56B6BL, 0x1A864DB2L, 0x1E475005L, 0x2608EDB8L, 0x22C9F00FL, 0x2F8AD6D6L, 0x2B4BCB61L, 0x350C9B64L, 0x31CD86D3L, 0x3C8EA00AL, 0x384FBDBDL, 0x4C11DB70L, 0x48D0C6C7L, 0x4593E01EL, 0x4152FDA9L, 0x5F15ADACL, 0x5BD4B01BL, 0x569796C2L, 0x52568B75L, 0x6A1936C8L, 0x6ED82B7FL, 0x639B0DA6L, 0x675A1011L, 0x791D4014L, 0x7DDC5DA3L, 0x709F7B7AL, 0x745E66CDL, 0x9823B6E0L, 0x9CE2AB57L, 0x91A18D8EL, 0x95609039L, 0x8B27C03CL, 0x8FE6DD8BL, 0x82A5FB52L, 0x8664E6E5L, 0xBE2B5B58L, 0xBAEA46EFL, 0xB7A96036L, 0xB3687D81L, 0xAD2F2D84L, 0xA9EE3033L, 0xA4AD16EAL, 0xA06C0B5DL, 0xD4326D90L, 0xD0F37027L, 0xDDB056FEL, 0xD9714B49L, 0xC7361B4CL, 0xC3F706FBL, 0xCEB42022L, 0xCA753D95L, 0xF23A8028L, 0xF6FB9D9FL, 0xFBB8BB46L, 0xFF79A6F1L, 0xE13EF6F4L, 0xE5FFEB43L, 0xE8BCCD9AL, 0xEC7DD02DL, 0x34867077L, 0x30476DC0L, 0x3D044B19L, 0x39C556AEL, 0x278206ABL, 0x23431B1CL, 0x2E003DC5L, 0x2AC12072L, 0x128E9DCFL, 0x164F8078L, 0x1B0CA6A1L, 0x1FCDBB16L, 0x018AEB13L, 0x054BF6A4L, 0x0808D07DL, 0x0CC9CDCAL, 0x7897AB07L, 0x7C56B6B0L, 0x71159069L, 0x75D48DDEL, 0x6B93DDDBL, 0x6F52C06CL, 0x6211E6B5L, 0x66D0FB02L, 0x5E9F46BFL, 0x5A5E5B08L, 0x571D7DD1L, 0x53DC6066L, 0x4D9B3063L, 0x495A2DD4L, 0x44190B0DL, 0x40D816BAL, 0xACA5C697L, 0xA864DB20L, 0xA527FDF9L, 0xA1E6E04EL, 0xBFA1B04BL, 0xBB60ADFCL, 0xB6238B25L, 0xB2E29692L, 0x8AAD2B2FL, 0x8E6C3698L, 0x832F1041L, 0x87EE0DF6L, 0x99A95DF3L, 0x9D684044L, 0x902B669DL, 0x94EA7B2AL, 0xE0B41DE7L, 0xE4750050L, 0xE9362689L, 0xEDF73B3EL, 0xF3B06B3BL, 0xF771768CL, 0xFA325055L, 0xFEF34DE2L, 0xC6BCF05FL, 0xC27DEDE8L, 0xCF3ECB31L, 0xCBFFD686L, 0xD5B88683L, 0xD1799B34L, 0xDC3ABDEDL, 0xD8FBA05AL, 0x690CE0EEL, 0x6DCDFD59L, 0x608EDB80L, 0x644FC637L, 0x7A089632L, 0x7EC98B85L, 0x738AAD5CL, 0x774BB0EBL, 0x4F040D56L, 0x4BC510E1L, 0x46863638L, 0x42472B8FL, 0x5C007B8AL, 0x58C1663DL, 0x558240E4L, 0x51435D53L, 0x251D3B9EL, 0x21DC2629L, 0x2C9F00F0L, 0x285E1D47L, 0x36194D42L, 0x32D850F5L, 0x3F9B762CL, 0x3B5A6B9BL, 0x0315D626L, 0x07D4CB91L, 0x0A97ED48L, 0x0E56F0FFL, 0x1011A0FAL, 0x14D0BD4DL, 0x19939B94L, 0x1D528623L, 0xF12F560EL, 0xF5EE4BB9L, 0xF8AD6D60L, 0xFC6C70D7L, 0xE22B20D2L, 0xE6EA3D65L, 0xEBA91BBCL, 0xEF68060BL, 0xD727BBB6L, 0xD3E6A601L, 0xDEA580D8L, 0xDA649D6FL, 0xC423CD6AL, 0xC0E2D0DDL, 0xCDA1F604L, 0xC960EBB3L, 0xBD3E8D7EL, 0xB9FF90C9L, 0xB4BCB610L, 0xB07DABA7L, 0xAE3AFBA2L, 0xAAFBE615L, 0xA7B8C0CCL, 0xA379DD7BL, 0x9B3660C6L, 0x9FF77D71L, 0x92B45BA8L, 0x9675461FL, 0x8832161AL, 0x8CF30BADL, 0x81B02D74L, 0x857130C3L, 0x5D8A9099L, 0x594B8D2EL, 0x5408ABF7L, 0x50C9B640L, 0x4E8EE645L, 0x4A4FFBF2L, 0x470CDD2BL, 0x43CDC09CL, 0x7B827D21L, 0x7F436096L, 0x7200464FL, 0x76C15BF8L, 0x68860BFDL, 0x6C47164AL, 0x61043093L, 0x65C52D24L, 0x119B4BE9L, 0x155A565EL, 0x18197087L, 0x1CD86D30L, 0x029F3D35L, 0x065E2082L, 0x0B1D065BL, 0x0FDC1BECL, 0x3793A651L, 0x3352BBE6L, 0x3E119D3FL, 0x3AD08088L, 0x2497D08DL, 0x2056CD3AL, 0x2D15EBE3L, 0x29D4F654L, 0xC5A92679L, 0xC1683BCEL, 0xCC2B1D17L, 0xC8EA00A0L, 0xD6AD50A5L, 0xD26C4D12L, 0xDF2F6BCBL, 0xDBEE767CL, 0xE3A1CBC1L, 0xE760D676L, 0xEA23F0AFL, 0xEEE2ED18L, 0xF0A5BD1DL, 0xF464A0AAL, 0xF9278673L, 0xFDE69BC4L, 0x89B8FD09L, 0x8D79E0BEL, 0x803AC667L, 0x84FBDBD0L, 0x9ABC8BD5L, 0x9E7D9662L, 0x933EB0BBL, 0x97FFAD0CL, 0xAFB010B1L, 0xAB710D06L, 0xA6322BDFL, 0xA2F33668L, 0xBCB4666DL, 0xB8757BDAL, 0xB5365D03L, 0xB1F740B4L }; /****************************************************************************** * Precomputed ATM CRC8 lookup table ******************************************************************************/ unsigned char hec_table[256]= { 0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15, 0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d, 0x70, 0x77, 0x7e, 0x79, 0x6c, 0x6b, 0x62, 0x65, 0x48, 0x4f, 0x46, 0x41, 0x54, 0x53, 0x5a, 0x5d, 0xe0, 0xe7, 0xee, 0xe9, 0xfc, 0xfb, 0xf2, 0xf5, 0xd8, 0xdf, 0xd6, 0xd1, 0xc4, 0xc3, 0xca, 0xcd, 0x90, 0x97, 0x9e, 0x99, 0x8c, 0x8b, 0x82, 0x85, 0xa8, 0xaf, 0xa6, 0xa1, 0xb4, 0xb3, 0xba, 0xbd, 0xc7, 0xc0, 0xc9, 0xce, 0xdb, 0xdc, 0xd5, 0xd2, 0xff, 0xf8, 0xf1, 0xf6, 0xe3, 0xe4, 0xed, 0xea, 0xb7, 0xb0, 0xb9, 0xbe, 0xab, 0xac, 0xa5, 0xa2, 0x8f, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9d, 0x9a, 0x27, 0x20, 0x29, 0x2e, 0x3b, 0x3c, 0x35, 0x32, 0x1f, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0d, 0x0a, 0x57, 0x50, 0x59, 0x5e, 0x4b, 0x4c, 0x45, 0x42, 0x6f, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7d, 0x7a, 0x89, 0x8e, 0x87, 0x80, 0x95, 0x92, 0x9b, 0x9c, 0xb1, 0xb6, 0xbf, 0xb8, 0xad, 0xaa, 0xa3, 0xa4, 0xf9, 0xfe, 0xf7, 0xf0, 0xe5, 0xe2, 0xeb, 0xec, 0xc1, 0xc6, 0xcf, 0xc8, 0xdd, 0xda, 0xd3, 0xd4, 0x69, 0x6e, 0x67, 0x60, 0x75, 0x72, 0x7b, 0x7c, 0x51, 0x56, 0x5f, 0x58, 0x4d, 0x4a, 0x43, 0x44, 0x19, 0x1e, 0x17, 0x10, 0x05, 0x02, 0x0b, 0x0c, 0x21, 0x26, 0x2f, 0x28, 0x3d, 0x3a, 0x33, 0x34, 0x4e, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5c, 0x5b, 0x76, 0x71, 0x78, 0x7f, 0x6a, 0x6d, 0x64, 0x63, 0x3e, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2c, 0x2b, 0x06, 0x01, 0x08, 0x0f, 0x1a, 0x1d, 0x14, 0x13, 0xae, 0xa9, 0xa0, 0xa7, 0xb2, 0xb5, 0xbc, 0xbb, 0x96, 0x91, 0x98, 0x9f, 0x8a, 0x8d, 0x84, 0x83, 0xde, 0xd9, 0xd0, 0xd7, 0xc2, 0xc5, 0xcc, 0xcb, 0xe6, 0xe1, 0xe8, 0xef, 0xfa, 0xfd, 0xf4, 0xf3 }; /****************************************************************************** * Functions ******************************************************************************/ /* * Function : aal5_calc_crc * Return Value : crc calculated for the given buffer ( needs to be xor'ed) * Description : none */ unsigned int aal5_calc_crc(unsigned char *mem, int len, unsigned int initial) { register unsigned int crc; crc = initial; while( len >= 8) { DO8(mem, crc); len -= 8; } while( len ) { DO1(mem, crc); len--; } return(crc); } unsigned char atm_calc_hec(unsigned char *header) { register unsigned char hec,i; hec = 0; for(i=0; i<4; i++) hec = hec_table[hec^header[i]]; return(hec^ATM_HEADER_COSET_LEADER); } #endif ===> firmware.h #ifndef __FIRMWARE_H__ #define __FIRMWARE_H__ typedef struct { unsigned long crc; unsigned long length; const char *id; } stusb_firmware_id_t; typedef struct { unsigned char *phase1; unsigned char *phase2; unsigned long phase1_length; unsigned long phase2_length; } stusb_firmware_t; stusb_firmware_t * extract_firmware(const char *boot_file, const char *firm_file, int rev4); void free_firmware(stusb_firmware_t *f); #endif ===> firmware.c /* * ALCATEL SpeedTouch USB modem microcode extract utility * Copyright (C) 2001 Benoit PAPILLAULT * * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Author : Edouard Gomez <[EMAIL PROTECTED]> * Creation : 14/02/2004 * * Searching for the microcode is done in a two step process: * - the boot code. * - the main firmware. * * The bootcode is always loaded at 0x00000000 in the modem RAM, so we look for * this base address mixed in a special file format signature. The end of the * boot code is marked by a command that tells the ARM to jump at the base * address and execute (aka boot) * * The base address of the main firmware depends on the modem revision (as of * 2004-02-14, only rev4 is different). The end pattern is also a jump command. * * $Id: firmware.c,v 1.1 2004/10/15 15:00:56 duncan Exp $ */ #ifndef _FIRMWARE_C_ #define _FIRMWARE_C_ #ifndef STANDALONE_EXTRACTER #include "pppoa3.h" #endif #include "crc.h" #include "firmware.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <sys/stat.h> /***************************************************************************** * Local Prototypes *****************************************************************************/ static stusb_firmware_t * extract_firmware_phase(const char *file, const unsigned char *start_pattern, const unsigned char *end_pattern, const int pattern_length, const stusb_firmware_id_t *ids); static int search_pattern(const unsigned char *buffer, const unsigned char *pattern, const int buffer_length, const int pattern_length); static unsigned char * load_file(const char * file, int * size); /****************************************************************************** * Main Lib Function ******************************************************************************/ /* * Function : check_firmware * Results : return 1 if the firmware is OK, 0 otherwise. * Description : check that the firmware found is valid */ int check_firmware(unsigned char * buf, int len) { unsigned char * current_block; int remaining_len; unsigned int addr; unsigned int size, extra_size; int boot_block_seen = 0; int last_block_seen = 0; current_block = buf; remaining_len = len; while (remaining_len > 0) { if (remaining_len < 8) { /* not enougth data to make a block, abort */ return(0); } addr = current_block[2] | (current_block[3]<<8) | (current_block[4]<<16) | (current_block[5]<<24); size = current_block[6] | (current_block[7]<<8); extra_size = current_block[1] | ((current_block[0]&0x80)<<1); switch (current_block[0]) { case 0x08: case 0x88: /* determine the type of block */ if (extra_size <= 0x1f8 && extra_size > 6) { /* last data block & last data block */ if (boot_block_seen || last_block_seen) return 0; if (extra_size < 0x1f8) last_block_seen = 1; if (extra_size != size + 6) return 0; /* skip over header */ current_block += 2; remaining_len -= 2; if (remaining_len < extra_size) return(0); /* skip over data */ current_block += extra_size; remaining_len -= extra_size; if (remaining_len < 3) return(0); if (current_block[0] != 0x40 || current_block[1] != 0x01 || current_block[2] != 0x12) return(0); /* skip over trailer */ current_block += 3; remaining_len -= 3; } else if (extra_size == 4) { /* boot block */ if (boot_block_seen) return(0); boot_block_seen = 1; /* skip over header */ current_block += 2; remaining_len -= 2; if (remaining_len < extra_size) return(0); /* skip over data */ current_block += extra_size; remaining_len -= extra_size; if (remaining_len < 3) return(0); if (current_block[0] != 0x00 || current_block[1] != 0x01 || current_block[2] != 0x14) return(0); /* skip over trailer */ current_block += 3; remaining_len -= 3; } else { /* unknown block again, abort */ return(0); } break; default: /* unknown block, abort */ return(0); } } return(1); } /* * Function : extract_microcode * Return Value : NULL on error * valid pointer to the microcode on success * Description : We are searching for the best match of a start and end * sequence. * Those sequence delimits the microcode. You won't get 100% * probability, but it will work anyway, for all the microcode * I've tested. */ #define PATTERN_LENGTH 8 stusb_firmware_t * extract_firmware(const char *file1, const char *file2, int rev4) { /* Specific byte sequences that mark the start/end of the encapsulated ARM code in firmware files */ const unsigned char boot_patterns[2][PATTERN_LENGTH] = { /* The base address is always 0x00000000 */ {0x88, 0xf8, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x01}, /* start */ {0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x14} /* stop */ }; const unsigned char firm_patterns[2][2][PATTERN_LENGTH] = { { /* The base address is 0x00400000 */ {0x88, 0xf8, 0x00, 0x40, 0x00, 0x00, 0xf2, 0x01}, /* start for stusb rev 1,2,3 */ {0x04, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, 0x14} /* stop for stusb rev 1,2,3 */ }, { /* The base address is 0x00000010 */ {0x88, 0xf8, 0x00, 0x00, 0x00, 0x10, 0xf2, 0x01}, /* start for stusb rev 4 */ {0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x14} /* stop for stusb rev 4 */ } }; const stusb_firmware_id_t stusb_phase1_ids[] = { {0xd3e33990, 883, "Ian's Free Software Boot block"}, {0xd80bf9f7, 991, "Alcatel/Thomson Boot block (old)"}, {0x69636579, 935, "Alcatel/Thomson Boot block (new)"}, {0x00000000, 0, NULL} }; const stusb_firmware_id_t stusb_phase2_ids[] = { {0xae3ff81f, 526239, "1.3.1 - GNU/Linux"}, {0xa719bc0e, 523436, "1.3.1 - Win32"}, {0x94a45435, 526187, "1.3.3 - GNU/Linux - Win32"}, {0x61914198, 527093, "1.4.0 - Win32(3.0.1800)"}, {0x37c189ed, 527752, "1.4.0 - Win32(4.0.100)"}, {0x99cc1c1a, 528738, "1.4.2 - Win32(2.0.500)"}, {0xe0251a5e, 671665, "1.6.1 - Win32(5.0.1801)"}, {0x3b4a5854, 671653, "1.6.1 - MacOSX - Win32(1.0.1800)"}, {0xd673923f, 672264, "2.0.0 - Win32(07)"}, {0x5bca7d16, 677641, "2.0.1 - MacOSX - Win32(2.0.0)"}, {0x78039fed, 762650, "3.0.6 - MacOSX - Win32"}, {0x698eb734, 761389, "3.0.0 - Win32"}, {0xd7864c39, 774192, "3.0.0 - Win32 (rev 4)"}, {0x0223733c, 775509, "1.0.10 - Win32 Rev 0400 SACHU3"}, {0x41d4143c, 775545, "0.0.0 - testing firmware from Thomson"}, {0x00000000, 0, NULL} }; stusb_firmware_t *boot, *firmware; if (file2 == NULL) return(NULL); /* If we are not passed a phase1 file, try to find it in the phase2 * file. It was the usual way firmwares were packed together in olds * alcatel/thomson drivers */ if (file1 == NULL) file1 = file2; /* Extract the phase1 (boot block) part */ boot = extract_firmware_phase(file1, boot_patterns[0], boot_patterns[1], PATTERN_LENGTH, stusb_phase1_ids); /* Extract the modem's firmware now */ firmware = extract_firmware_phase(file2, firm_patterns[(rev4)?1:0][0], firm_patterns[(rev4)?1:0][1], PATTERN_LENGTH, stusb_phase2_ids); /* firmware is used as the returned value, it MUST be valid */ if (firmware == NULL) { free_firmware(boot); return(NULL); } /* Data is now loaded, put it where it belongs to * NB: - phase1 slot may be empty, it's up to the caller to fill it with * default boot block * - phase2 slot is mandatory and triggers an error if it's missing */ firmware->phase2 = firmware->phase1; firmware->phase2_length = firmware->phase1_length; firmware->phase1 = (boot!=NULL)?boot->phase1:NULL; firmware->phase1_length = (boot!=NULL)?boot->phase1_length:0; /* Free allocated structure (if any) but not the its fields */ if (boot) free(boot); return(firmware); } static stusb_firmware_t * extract_firmware_phase(const char *file, const unsigned char *start_pattern, const unsigned char *stop_pattern, const int pattern_length, const stusb_firmware_id_t *ids) { unsigned char *buf; int start_offset, length; stusb_firmware_t *firmware; length = 0; start_offset = 0; /* Loads the file into memory (yes, it's a lame, why not a mmap ?) */ if ((buf = load_file(file, &length)) == NULL) return(NULL); /* Searches the start and end offsets */ start_offset = search_pattern(buf, start_pattern, length, pattern_length); if (start_offset < 0) { free(buf); return(NULL); } length = search_pattern(buf + start_offset, stop_pattern, length - start_offset, pattern_length); if (length < 0) { free(buf); return(NULL); } /* We must add the pattern length to obtain the real length */ length += PATTERN_LENGTH; /* Initialize the returned firmware struct */ if ((firmware = malloc(sizeof(stusb_firmware_t))) == NULL) { free(buf); return(NULL); } memset(firmware, 0, sizeof(stusb_firmware_t)); if ((firmware->phase1 = malloc(length)) == NULL) { free(firmware); free(buf); return(NULL); } /* Copy the data into the returned firmware * Data is put into phase1 fields -- The caller function may then do * whatever it likes with this data. */ memcpy(firmware->phase1, buf+start_offset, length); firmware->phase1_length = length; /* We don't need the file buffer anymore */ free(buf); { unsigned long crc; const stusb_firmware_id_t *id = ids; const char *idstr = "Unknown revision - Please report the CRC " "and length with the revision number to " "[EMAIL PROTECTED]"; int checked; /* Computes this value once */ crc = ~aal5_calc_crc(firmware->phase1, firmware->phase1_length,~0); /* Browse the "known" firmware array */ while (id->length != 0) { if(id->length == length && id->crc == crc) { idstr = id->id; break; } id++; } checked = check_firmware(firmware->phase1, firmware->phase1_length); #ifndef STANDALONE_EXTRACTER report(1, REPORT_INFO, "Firmware info (CRC:0x%08x, Size:%d, Checked: %s, %s)\n", crc, length, checked?"Yes":"No",idstr); #else printf("Firmware info (CRC:0x%08x, Size:%d, Checked: %s, %s)\n", crc, length, checked?"Yes":"No",idstr); #endif } /* Returns a pointer to the start adress */ return(firmware); } /***************************************************************************** * Local sub routines *****************************************************************************/ /* * Function : load_file * Return Value : null in case of error * a pointer to a buffer allocated using malloc() on success * NB : *size contains the returned buffer size */ static unsigned char * load_file(const char * file, int * size) { struct stat statbuf; int len; unsigned char * buf; int fd; *size = 0; /* Opens the file */ if ((fd = open(file, O_RDONLY)) < 0) { perror(file); return(NULL); } /* Retrieves file informations */ if (fstat(fd, &statbuf) != 0) { perror("stat"); return(NULL); } /* Gets length */ len = statbuf.st_size; /* Allocates the buffer */ if((buf = (unsigned char *)malloc(len)) == NULL) { perror("malloc"); close (fd); return(NULL); } /* Read all contents in buffer */ if (read(fd, buf, len) != len) { perror(file); free (buf); close (fd); return(NULL); } /* Closes the file */ close(fd); /* Sets size */ *size = len; return(buf); } /* * Function : search_match * Return value : -1 in case of error * best match offset on success * Description : Search for the longest match of buf2 inside buf1. * */ static int search_pattern(const unsigned char *buffer, const unsigned char *pattern, const int buffer_length, const int pattern_length) { /* Number of bytes match with pattern */ int best_match = 0; /* Best offset*/ int best_offset = -1; /* Zone where the pattern can reside */ int potential_length = (buffer_length - pattern_length + 1); /* Loop counter */ int cur_offset; for(cur_offset=0; cur_offset< potential_length; cur_offset++) { int i; int cur_match; /* Compute the matching number of bytes at this offset */ for(i=0, cur_match=0;i<pattern_length;i++) if (buffer[cur_offset+i] == pattern[i]) cur_match++; /* Compare to the best known matching offset */ if(cur_match > best_match) { best_offset = cur_offset; best_match = cur_match; /* Stops as soon as a perfect match is found */ if (best_match == pattern_length) break; } } #ifndef STANDALONE_EXTRACTER report(1, REPORT_INFO, "Best offset %6d with probability %3d%%\n", best_offset, (100*best_match)/pattern_length); #endif return((best_match == pattern_length)?best_offset:-1); } void free_firmware(stusb_firmware_t *f) { if (f) { if (f->phase1) { free(f->phase1); f->phase1 = NULL; f->phase1_length = 0; } if (f->phase2) { free(f->phase2); f->phase2 = NULL; f->phase2_length = 0; } free(f); } } /****************************************************************************** * A main function to test the extract function ******************************************************************************/ #ifdef STANDALONE_EXTRACTER #include "crc.c" void usage(char *progname) { fprintf(stderr, "Usage: %s [boot file] <firmware file>\n\n", progname); } void extract_new(char *file); int main(int argc, char *argv[]) { char *file1 = NULL; char *file2 = NULL; stusb_firmware_t *firmware; if (argc != 2 && argc != 3) { usage(argv[0]); return(-1); } /* Binds filenames where they belong */ file2 = argv[argc-1]; file1 = (argc==2)? file2 : argv[argc-2]; /* Get the firmware */ firmware = extract_firmware(file1, file2, 0); if (firmware == NULL) firmware = extract_firmware(file1, file2, 1); /* Report to user all informations that can be useful */ printf("** Boot block from %s:\n", file1); if (firmware && firmware->phase1) { int o; printf(" CRC: 0x%08x\n", ~aal5_calc_crc(firmware->phase1, firmware->phase1_length,~0)); printf(" Length: %d\n", (int)firmware->phase1_length); o = open("boot.bin", O_CREAT|O_WRONLY|O_TRUNC, 0644); if (o != -1) { write(o, firmware->phase1, firmware->phase1_length); close(o); } } else { printf(" Not found\n"); } printf("** Firmware block from %s:\n", file2); if (firmware && firmware->phase2) { int o; printf(" CRC: 0x%08x\n", ~aal5_calc_crc(firmware->phase2, firmware->phase2_length,~0)); printf(" Length: %d\n", (int)firmware->phase2_length); o = open("firmware.bin", O_CREAT|O_WRONLY|O_TRUNC, 0644); if (o != -1) { write(o, firmware->phase2, firmware->phase2_length); close(o); } } else { printf(" Not found\n"); } /* Free the firmware */ free_firmware(firmware); return(0); } #endif /* STANDALONE_EXTRACTER */ #endif /* #ifndef _FIRMWARE_C_ */ Liste de diffusion modem ALCATEL SpeedTouch USB Pour se désinscrire : mailto:[EMAIL PROTECTED]