rpcd: iwinfo plugin fixes
[openwrt.git] / tools / firmware-utils / src / hcsmakeimage.c
1 #include <stdlib.h>
2 #include <sys/types.h>
3 #include <stdio.h>
4 #include <inttypes.h>
5 #include <string.h>
6 #include <getopt.h>
7 #include <unistd.h>
8 #include <sys/time.h>
9 #include <sys/stat.h>
10 #include <libgen.h>
11 #include "bcmalgo.h"
12
13
14 int flag_print_version;
15 int flag_print_help;
16 int flag_compress;
17
18 uint16_t sa2100_magic  = 0x2100;
19 uint16_t sa3349_magic  = 0x3349;
20 uint32_t default_date = 0x00000000; //A long time ago in a galaxy far far away....
21 uint32_t default_load_address = 0x80010000; //The default load_address for the firmware image
22
23 static void print_help ( const char* ename )
24 {
25         printf ( "Firmware image packer and calculator for broadcom-based modems.\n" );
26         printf ( "Part of bcm-utils package.\n" );
27         printf ( "(c) 2009 Necromant (http://necromant.ath.cx). Thanks to Luke-jr for his initial work.\n" );
28         printf ( "usage: %s [options]\n", ename );
29         printf ( "Valid options are:\n" );
30         printf ( "--magic_bytes=value \t- specify magic bytes at the beginning of the image. default - 3349\n" );
31         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" );
32         printf ( "--compress \t\t - Make use of LZMA (weird!) compression (Doesn't work yet).\n" );
33         printf ( "--rev_maj=value\t\t - major revision number. default 0\n" );
34         printf ( "--rev_min=value\t\t - minor revision number default 0\n" );
35         printf ( "--filename=value\t - use this filename in header instead of default (input filename)\n" );
36         printf ( "--ldaddress=value\t - hex value of the target load address. defaults to 0x80010000\n" );
37         printf ( "--input_file=value\t - What file are we packing?\n" );
38         printf ( "--output_file=value\t - What file shall we write? (default: image.bin)\n" );
39 #ifdef _HAX0RSTYLE
40         printf ( "--credz\t - Give some credz!\n" );
41 #endif
42         printf ( "\n" );
43 }
44
45
46 int main ( int argc, char** argv )
47 {
48         if ( argc<2 )
49         {
50                 print_help ( argv[0] );
51         }
52
53         static struct option long_options[] =
54         {
55                 {"magic_bytes",          required_argument,   0,        'm'},
56                 {"rev_maj",        required_argument,   0,      'j'},
57                 {"rev_min",       required_argument,   0,     'n'},
58                 {"ldaddress",       required_argument,   0,     'l'},
59                 {"filename",       required_argument,   0,     'f'},
60                 {"input_file",       required_argument,   0,     'i'},
61                 {"output_file",       required_argument,   0,     'o'},
62                 {"compress",     no_argument,       &flag_compress,    'c'},
63                 {"version",     no_argument,       &flag_print_version,    'v'},
64                 {"help",        no_argument,       &flag_print_help,    'h'},
65                 {0, 0, 0, 0}
66         };
67         int option_index = 0;
68         int opt_result=0;
69         char* filename=NULL;
70         char* input=NULL;
71         char* magic=NULL;
72         char* major=NULL;
73         char* minor=NULL;
74         char* ldaddr=NULL;
75         char* output=NULL;
76
77         while ( opt_result>=0 )
78         {
79                 opt_result = getopt_long ( argc, argv, "m:j:n:f:i:o:vh", long_options, &option_index );
80                 switch ( opt_result )
81                 {
82                         case 0:
83                                 printf ( "o!\n" );
84                                 break;
85                         case 'h':
86                                 print_help ( argv[0] );
87                                 break;
88                         case 'l':
89                                 ldaddr=optarg;
90                                 break;
91                         case 'f':
92                                 filename=optarg;
93                                 break;
94                         case 'i':
95                                 input=optarg;
96                                 break;
97                         case 'o':
98                                 output=optarg;
99                                 break;
100                         case 'm':
101                                 magic=optarg;
102                                 break;
103                         case 'j':
104                                 major=optarg;
105                                 break;
106                         case 'n':
107                                 minor=optarg;
108                                 break;
109                 }
110         }
111         if ( input==NULL )
112         {
113                 printf ( "Telepaths are still on holidays. I guess you should tell me what file should I process.\n\n" );
114                 exit ( 1 );
115         }
116         if ( access ( input,R_OK ) !=0 )
117         {
118                 printf ( "I cannot access the file %s. Is it there? Am I allowed?\n\n", input );
119                 exit ( 1 );
120         }
121         uint32_t magicnum=sa2100_magic;
122
123         if ( magic )
124         {
125                 if ( strcmp ( magic,"sa2100" ) ==0 ) magicnum=sa2100_magic; else
126                                 if ( strcmp ( magic,"sa3349" ) ==0 ) magicnum=sa3349_magic; else
127                         {
128                                 sscanf ( magic, "0x%04X", &magicnum );
129                         }
130         }
131         unsigned int majrev=0;
132         if ( major )
133         {
134                 sscanf ( major, "%d", &majrev );
135         }
136         unsigned int minrev=0;
137         if ( minor )
138         {
139                 sscanf ( minor, "%d", &minrev );
140         }
141         uint32_t ldaddress = default_load_address;
142         if ( ldaddr )
143         {
144                 sscanf ( ldaddr, "0x%08X", &ldaddress );
145         }
146         char* dupe = strdup(input);
147         char* fname = basename ( dupe );
148         if ( filename )
149         {
150                 fname = filename;
151         }
152         struct timeval tm;
153         gettimeofday ( &tm,NULL );
154         struct stat buf;
155         stat ( input,&buf );
156         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 ) );
157         free(dupe);
158         //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
159         //FILE* fd = fopen ("/tftpboot/haxorware11rev32.bin","r");
160         //fread(head,sizeof(ldr_header_t),1,fd);
161         char* filebuffer = malloc ( buf.st_size+10 );
162         FILE* fd = fopen ( input,"r" );
163         fread ( filebuffer, 1, buf.st_size,fd );
164         if (!output)
165                 {
166                 output = malloc(strlen(input+5));
167                 strcpy(output,input);
168                 strcat(output,".bin");
169                 }
170         dump_header ( head );
171         FILE* fd_out = fopen ( output,"w+" );
172         if (!fd_out)
173                 {
174                 fprintf(stderr, "Failed to open output file: %s\n", output);
175                 exit(1);
176                 }
177         fwrite ( head,1,sizeof ( ldr_header_t ),fd_out );
178         fwrite ( filebuffer,1,buf.st_size,fd_out );
179         printf("Firmware image %s is ready\n", output);
180         return 0;
181 }