hcsmakeimage.c 5.8 KB

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