genhdr.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. #include <stdio.h>
  2. #include <stdint.h>
  3. #include <fcntl.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #define ll8(x) (x & 0xff)
  7. #define lh8(x) ((x >> 8) & 0xff)
  8. #define hl8(x) ((x >> 16) & 0xff)
  9. #define hh8(x) ((x >> 24) & 0xff)
  10. /* Generated on Thu Feb 17 10:57:01 2011,
  11. * by pycrc v0.7.1, http://www.tty1.net/pycrc/
  12. */
  13. uint32_t crc_reflect( uint32_t data, size_t data_len )
  14. {
  15. unsigned int i;
  16. uint32_t ret;
  17. ret = data & 0x01;
  18. for ( i = 1; i < data_len; i++ )
  19. {
  20. data >>= 1;
  21. ret = ( ret << 1 ) | ( data & 0x01 );
  22. }
  23. return ret;
  24. }
  25. uint32_t crc_update( uint32_t crc, const uint8_t *buf, uint32_t len )
  26. {
  27. unsigned int i;
  28. uint32_t bit;
  29. uint8_t c;
  30. while ( len-- )
  31. {
  32. c = *buf++;
  33. for ( i = 0x01; i & 0xff; i <<= 1 )
  34. {
  35. bit = crc & 0x80000000;
  36. if ( c & i )
  37. {
  38. bit = bit ? 0 : 1;
  39. }
  40. crc <<= 1;
  41. if ( bit )
  42. {
  43. crc ^= 0x04c11db7;
  44. }
  45. }
  46. crc &= 0xffffffff;
  47. }
  48. return crc & 0xffffffff;
  49. }
  50. int main( int argc, char **argv )
  51. {
  52. FILE *f;
  53. size_t flen;
  54. if ( argc < 3 )
  55. {
  56. printf( "Usage: genhdr <input file> <signature> <version>\n"
  57. " input file: file to be headered\n"
  58. " signature : magic value at start of header (4-char string)\n"
  59. " version : firmware version (decimal uint32)\n"
  60. "Output is written in place.\n" );
  61. return 1;
  62. }
  63. if ( ( f = fopen( argv[1], "rb+" ) ) == NULL )
  64. {
  65. printf( "Unable to open input file %s", argv[1] );
  66. perror( "" );
  67. return 1;
  68. }
  69. fseek( f, 0, SEEK_END );
  70. flen = ftell( f );
  71. if ( flen + 256 < flen )
  72. {
  73. printf( "File too large ;)\n" );
  74. return 1;
  75. }
  76. char *remaining = NULL;
  77. uint32_t version = ( uint32_t )strtol( argv[3], &remaining, 0 );
  78. if ( *remaining )
  79. {
  80. printf( "could not parse version number (remaining portion: %s)\n", remaining );
  81. fclose( f );
  82. return 1;
  83. }
  84. if ( strlen( argv[2] ) > 4 )
  85. {
  86. printf( "Magic string '%s' too long. Truncated to 4 characters.\n", argv[2] );
  87. }
  88. uint8_t *buf = malloc( flen + 256 );
  89. if ( !buf )
  90. {
  91. perror( "malloc" );
  92. }
  93. memset( buf, 0xff, 256 );
  94. fseek( f, 0, SEEK_SET );
  95. fread( buf + 256, 1, flen, f );
  96. uint32_t crcc = 0xffffffff, crc;
  97. crcc = crc_update( crcc, buf + 256, flen );
  98. crcc = crc_reflect( crcc, 32 );
  99. crc = crcc ^ 0xffffffff;
  100. memset( buf, 0, 4 );
  101. strncpy( ( char * )buf, argv[2], 4 );
  102. buf[4] = ll8( version );
  103. buf[5] = lh8( version );
  104. buf[6] = hl8( version );
  105. buf[7] = hh8( version );
  106. buf[8] = ll8( flen );
  107. buf[9] = lh8( flen );
  108. buf[10] = hl8( flen );
  109. buf[11] = hh8( flen );
  110. buf[12] = ll8( crc );
  111. buf[13] = lh8( crc );
  112. buf[14] = hl8( crc );
  113. buf[15] = hh8( crc );
  114. buf[16] = ll8( crcc );
  115. buf[17] = lh8( crcc );
  116. buf[18] = hl8( crcc );
  117. buf[19] = hh8( crcc );
  118. fseek( f, 0, SEEK_SET );
  119. fwrite( buf, 1, 256 + flen, f );
  120. fclose( f );
  121. return 0;
  122. }