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 <sys/time.h> 10 #include <sys/stat.h> 11 #include "bcmalgo.h" 12 13 14 #define UTIL_VERSION "0.1" 15 #define ENDIAN_REVERSE_NEEDED 16 17 uint32_t reverse_endian32 ( uint32_t data ) 18 { 19 #ifdef ENDIAN_REVERSE_NEEDED 20 return 0 | ( data & 0x000000ff ) << 24 21 | ( data & 0x0000ff00 ) << 8 22 | ( data & 0x00ff0000 ) >> 8 23 | ( data & 0xff000000 ) >> 24; 24 #else 25 return data; 26 #endif 27 } 28 29 uint16_t reverse_endian16 ( uint16_t data ) 30 { 31 #ifdef ENDIAN_REVERSE_NEEDED 32 return 0 | ( data & 0x00ff ) << 8 33 | ( data & 0xff00 ) >> 8; 34 #else 35 return data; 36 #endif 37 } 38 39 40 41 uint32_t get_buffer_crc ( char* filebuffer,size_t size ) 42 { 43 44 long crc=0xffffffffL; 45 long crcxor = 0xffffffffL; 46 long num4 = 0xffffffffL; 47 long num5 = size; 48 long num6 = 0x4c11db7L; 49 long num7 = 0x80000000L; 50 int i; 51 long j; 52 for ( i = 0; i < ( num5 ); i++ ) 53 { 54 long num2 = filebuffer[i]; 55 for ( j = 0x80L; j != 0L; j = j >> 1 ) 56 { 57 long num3 = crc & num7; 58 crc = crc << 1; 59 if ( ( num2 & j ) != 0L ) 60 { 61 num3 ^= num7; 62 } 63 if ( num3 != 0L ) 64 { 65 crc ^= num6; 66 } 67 } 68 } 69 crc ^= crcxor; 70 crc &= num4; 71 72 uint8_t b1 = ( uint8_t ) ( ( crc & -16777216L ) >> 0x18 ); 73 uint8_t b2 = ( uint8_t ) ( ( crc & 0xff0000L ) >> 0x10 ); 74 uint8_t b3 = ( uint8_t ) ( ( crc & 0xff00L ) >> 8 ); 75 uint8_t b4 = ( uint8_t ) ( crc & 0xffL ); 76 int32_t crc_result = ( b1 | b2 << 8| b3 << 16| b4 <<24 ); 77 return reverse_endian32 ( crc_result ); 78 } 79 80 //Thnx to Vector for the algo. 81 uint32_t get_file_crc ( char* filename ) 82 { 83 struct stat buf; 84 stat ( filename,&buf ); 85 char* filebuffer = malloc ( buf.st_size+10 ); 86 FILE* fd = fopen ( filename,"r" ); 87 fread ( filebuffer, 1, buf.st_size,fd ); 88 fclose ( fd ); 89 uint32_t crc = get_buffer_crc ( filebuffer,buf.st_size ); 90 free ( filebuffer ); 91 return crc; 92 } 93 94 95 96 uint16_t get_hcs ( ldr_header_t* hd ) 97 { 98 uint8_t* head = ( uint8_t* ) hd; 99 uint8_t hcs_minor; 100 uint8_t hcs_major; 101 uint16_t n = 0xffff; 102 int state = 0; 103 int i,j; 104 for ( i = 0; i < 0x54; i++ ) 105 { 106 uint16_t m = head[i]; 107 m = m << 8; 108 for ( j = 0; j < 8; j++ ) 109 { 110 if ( ( ( n ^ m ) & 0x8000 ) == 0 ) 111 { 112 state = 0; 113 } 114 else 115 { 116 state = 1; 117 } 118 n = n << 1; 119 if ( state ) 120 { 121 n ^= 0x1021; 122 } 123 m = m << 1; 124 } 125 n &= 0xffff; 126 } 127 n ^= 0xffff; 128 hcs_major = ( uint8_t ) ( ( n & 0xff00 ) >> 8 ); 129 hcs_minor = ( uint8_t ) ( n & 0xff ); 130 uint16_t hcs = hcs_major <<8 | hcs_minor; 131 return hcs; 132 } 133 134 ldr_header_t* construct_header ( 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_data ) 135 { 136 ldr_header_t* hd = malloc ( sizeof ( ldr_header_t ) ); 137 hd->magic=reverse_endian16 ( magic ); 138 hd->control=0; //FixMe: Make use of it once compression is around 139 hd->rev_min = reverse_endian16 ( rev_min ); 140 hd->rev_maj = reverse_endian16 ( rev_maj ); 141 hd->build_date = reverse_endian32 ( build_date ); 142 hd->filelen = reverse_endian32 ( filelen ); 143 hd->ldaddress = reverse_endian32 ( ldaddress ); 144 printf ( "Creating header for %s...\n", filename ); 145 if ( strlen ( filename ) >63 ) 146 { 147 printf ( "[!] Filename too long - stripping it to 63 bytes.\n" ); 148 strncpy ( ( char* ) &hd->filename, filename, 63 ); 149 hd->filename[63]=0x00; 150 } 151 else 152 { 153 strcpy ( ( char* ) &hd->filename, filename ); 154 } 155 hd->crc=reverse_endian32 ( crc_data ); 156 hd->hcs = reverse_endian16 ( get_hcs ( hd ) ); 157 return hd; 158 } 159 160 static char control_unc[] = "Uncompressed"; 161 static char control_lz[] = "LZRW1/KH"; 162 static char control_mlzo[] = "mini-LZO"; 163 static char control_nrv[] = "NRV2D99 [Bootloader?]"; 164 static char control_nstdlzma[] = "(non-standard) LZMA"; 165 static char control_unk[] = "Unknown"; 166 char* get_control_info ( uint16_t control ) 167 { 168 control = reverse_endian16 ( control ); 169 switch ( control ) 170 { 171 case 0: 172 return control_unc; 173 break; 174 case 1: 175 return control_lz; 176 break; 177 case 2: 178 return control_mlzo; 179 break; 180 case 3: 181 return control_unc; 182 break; 183 case 4: 184 return control_nrv; 185 break; 186 case 5: 187 return control_nstdlzma; 188 break; 189 case 6: 190 return control_unc; 191 break; 192 case 7: 193 return control_unc; 194 break; 195 default: 196 return control_unk; 197 break; 198 } 199 200 } 201 202 int dump_header ( ldr_header_t* hd ) 203 { 204 printf ( "=== Header Information ===\n" ); 205 printf ( "Header magic:\t0x%04X\n",reverse_endian16 ( hd->magic ) ); 206 printf ( "Control:\t0x%04X (%s)\n",reverse_endian16 ( hd->control ), get_control_info ( hd->control ) ); 207 printf ( "Major rev. :\t0x%04X\n",reverse_endian16 ( hd->rev_maj ) ); 208 printf ( "Minor rev. :\t0x%04X\n",reverse_endian16 ( hd->rev_min ) ); 209 printf ( "File name :\t%s\n", ( char* ) &hd->filename ); 210 printf ( "File length:\t%d bytes\n", reverse_endian32 ( hd->filelen ) ); 211 printf ( "Build time:\t0x%08X //FixMe: print in human-readable form\n", reverse_endian32 ( hd->build_date ) ); //FixMe: 212 printf ( "HCS:\t\t0x%04X ",reverse_endian16 ( hd->hcs ) ); 213 uint16_t hcs = get_hcs ( hd ); 214 int ret=0; 215 if ( hcs ==reverse_endian16 ( hd->hcs ) ) 216 { 217 printf ( "(OK!)\n" ); 218 } 219 else 220 { 221 printf ( "(ERROR! expected 0x%04X)\n",hcs ); 222 ret=1; 223 } 224 //printf("HCS:\t0x%02X",reverse_endian32(hd->hcs)); 225 printf ( "Load address:\t0x%08X\n", reverse_endian32 ( hd->ldaddress ) ); //FixMe: 226 printf ( "HNW:\t\t0x%04X\n",reverse_endian16 ( hd->her_znaet_chto ) ); //Hell knows what 227 printf ( "CRC:\t\t0x%08X\n",reverse_endian32 ( hd->crc ) ); 228 printf ( "=== Binary Header Dump===\n" ); 229 int i; 230 uint8_t* head = ( uint8_t* ) hd; 231 for ( i=0;i<=sizeof ( ldr_header_t );i++ ) 232 { 233 if ( i % 8==0 ) 234 printf ( "\n" ); 235 printf ( "0x%02x ",head[i] ); 236 } 237 printf ( "\n\n== End Of Header dump ==\n" ); 238 return ret; 239 } 240 241 242 void print_copyright() 243 { 244 printf ( "Part of bcm-utils package ver. " UTIL_VERSION " \n" ); 245 printf ( "Copyright (C) 2009 Andrew 'Necromant' Andrianov\n" 246 "This is free software, and you are welcome to redistribute it\n" 247 "under certain conditions. See COPYING for details\n" ); 248 } 249
This page was automatically generated by LXR 0.3.1. • OpenWrt