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