1 // SPDX-License-Identifier: GPL-2.0-only
16 int flag_print_version
;
20 uint16_t sa2100_magic
= 0x2100;
21 uint16_t sa3349_magic
= 0x3349;
22 uint32_t default_date
= 0x00000000; //A long time ago in a galaxy far far away....
23 uint32_t default_load_address
= 0x80010000; //The default load_address for the firmware image
25 static void print_help ( const char* ename
)
27 printf ( "Firmware image packer and calculator for broadcom-based modems.\n" );
28 printf ( "Part of bcm-utils package.\n" );
29 printf ( "(c) 2009 Necromant (http://necromant.ath.cx). Thanks to Luke-jr for his initial work.\n" );
30 printf ( "usage: %s [options]\n", ename
);
31 printf ( "Valid options are:\n" );
32 printf ( "--magic_bytes=value \t- specify magic bytes at the beginning of the image. default - 3349\n" );
33 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" );
34 printf ( "--compress \t\t - Make use of LZMA (weird!) compression (Doesn't work yet).\n" );
35 printf ( "--rev_maj=value\t\t - major revision number. default 0\n" );
36 printf ( "--rev_min=value\t\t - minor revision number default 0\n" );
37 printf ( "--filename=value\t - use this filename in header instead of default (input filename)\n" );
38 printf ( "--ldaddress=value\t - hex value of the target load address. defaults to 0x80010000\n" );
39 printf ( "--input_file=value\t - What file are we packing?\n" );
40 printf ( "--output_file=value\t - What file shall we write? (default: image.bin)\n" );
42 printf ( "--credz\t - Give some credz!\n" );
47 static time_t source_date_epoch
= -1;
48 static void set_source_date_epoch() {
49 char *env
= getenv("SOURCE_DATE_EPOCH");
53 source_date_epoch
= strtoull(env
, &endptr
, 10);
54 if (errno
|| (endptr
&& *endptr
!= '\0')) {
55 fprintf(stderr
, "Invalid SOURCE_DATE_EPOCH");
61 int main ( int argc
, char** argv
)
65 print_help ( argv
[0] );
68 static struct option long_options
[] =
70 {"magic_bytes", required_argument
, 0, 'm'},
71 {"rev_maj", required_argument
, 0, 'j'},
72 {"rev_min", required_argument
, 0, 'n'},
73 {"ldaddress", required_argument
, 0, 'l'},
74 {"filename", required_argument
, 0, 'f'},
75 {"input_file", required_argument
, 0, 'i'},
76 {"output_file", required_argument
, 0, 'o'},
77 {"compress", no_argument
, &flag_compress
, 'c'},
78 {"version", no_argument
, &flag_print_version
, 'v'},
79 {"help", no_argument
, &flag_print_help
, 'h'},
92 while ( opt_result
>=0 )
94 opt_result
= getopt_long ( argc
, argv
, "m:j:n:f:i:o:vh", long_options
, &option_index
);
101 print_help ( argv
[0] );
128 printf ( "Telepaths are still on holidays. I guess you should tell me what file should I process.\n\n" );
131 if ( access ( input
,R_OK
) !=0 )
133 printf ( "I cannot access the file %s. Is it there? Am I allowed?\n\n", input
);
136 uint32_t magicnum
=sa2100_magic
;
140 if ( strcmp ( magic
,"sa2100" ) ==0 ) magicnum
=sa2100_magic
; else
141 if ( strcmp ( magic
,"sa3349" ) ==0 ) magicnum
=sa3349_magic
; else
143 sscanf ( magic
, "0x%04X", &magicnum
);
146 unsigned int majrev
=0;
149 sscanf ( major
, "%d", &majrev
);
151 unsigned int minrev
=0;
154 sscanf ( minor
, "%d", &minrev
);
156 uint32_t ldaddress
= default_load_address
;
159 sscanf ( ldaddr
, "0x%08X", &ldaddress
);
161 char* dupe
= strdup(input
);
162 char* fname
= basename ( dupe
);
169 set_source_date_epoch();
170 if (source_date_epoch
!= -1) {
171 t
= source_date_epoch
;
172 } else if ((time(&t
) == (time_t)(-1))) {
173 fprintf(stderr
, "time call failed\n");
179 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
) );
181 //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
182 //FILE* fd = fopen ("/tftpboot/haxorware11rev32.bin","r");
183 //fread(head,sizeof(ldr_header_t),1,fd);
184 char* filebuffer
= malloc ( buf
.st_size
+10 );
185 FILE* fd
= fopen ( input
,"r" );
186 fread ( filebuffer
, 1, buf
.st_size
,fd
);
190 output
= malloc(strlen(input
+5));
191 strcpy(output
,input
);
192 strcat(output
,".bin");
194 dump_header ( head
);
195 FILE* fd_out
= fopen ( output
,"w+" );
198 fprintf(stderr
, "Failed to open output file: %s\n", output
);
202 fwrite ( head
,1,sizeof ( ldr_header_t
),fd_out
);
203 fwrite ( filebuffer
,1,buf
.st_size
,fd_out
);
204 printf("Firmware image %s is ready\n", output
);