1 /* biossums.c --- written by Eike W. */
6 typedef unsigned char byte;
8 void check( int value, char* message );
10 #define LEN_BIOS_DATA 0x10000
11 #define MAX_OFFSET (LEN_BIOS_DATA - 1)
14 #define BIOS_OFFSET 0xFFFF
16 long chksum_bios_get_offset( byte* data, long offset );
17 byte chksum_bios_calc_value( byte* data, long offset );
18 byte chksum_bios_get_value( byte* data, long offset );
19 void chksum_bios_set_value( byte* data, long offset, byte value );
23 #define _32__CHKSUM 10
25 #define _32__MINHDR 16
27 long chksum__32__get_offset( byte* data, long offset );
28 byte chksum__32__calc_value( byte* data, long offset );
29 byte chksum__32__get_value( byte* data, long offset );
30 void chksum__32__set_value( byte* data, long offset, byte value );
34 #define _MP__CHKSUM 10
36 #define _MP__MINHDR 16
38 long chksum__mp__get_offset( byte* data, long offset );
39 byte chksum__mp__calc_value( byte* data, long offset );
40 byte chksum__mp__get_value( byte* data, long offset );
41 void chksum__mp__set_value( byte* data, long offset, byte value );
44 #define PCMP_BASELEN 4
46 #define PCMP_EXT_LEN 40
47 #define PCMP_EXT_CHKSUM 42
49 #define PCMP_MINHDR 42
51 long chksum_pcmp_get_offset( byte* data, long offset );
52 byte chksum_pcmp_calc_value( byte* data, long offset );
53 byte chksum_pcmp_get_value( byte* data, long offset );
54 void chksum_pcmp_set_value( byte* data, long offset, byte value );
58 #define _PIR_CHKSUM 31
60 #define _PIR_MINHDR 32
62 long chksum__pir_get_offset( byte *data, long offset );
63 byte chksum__pir_calc_value( byte* data, long offset );
64 byte chksum__pir_get_value( byte* data, long offset );
65 void chksum__pir_set_value( byte* data, long offset, byte value );
68 byte bios_data[LEN_BIOS_DATA];
71 int main( int argc, char* argv[] ) {
74 long offset, tmp_offset;
75 byte cur_val = 0, new_val = 0;
80 printf( "Error. Need a file-name as an argument.\n" );
84 if(( stream = fopen( argv[1], "rb" )) == NULL ) {
85 printf( "Error opening %s for reading.\n", argv[1] );
88 if( fread( bios_data, 1, LEN_BIOS_DATA, stream ) < LEN_BIOS_DATA ) {
89 printf( "Error reading 64KBytes from %s.\n", argv[1] );
97 while( (tmp_offset = chksum__32__get_offset( bios_data, offset )) != -1L ) {
99 cur_val = chksum__32__get_value( bios_data, offset );
100 new_val = chksum__32__calc_value( bios_data, offset );
101 printf( "\n\nPCI-Bios header at: 0x%4lX\n", offset );
102 printf( "Current checksum: 0x%02X\n", cur_val );
103 printf( "Calculated checksum: 0x%02X ", new_val );
106 if( hits == 1 && cur_val != new_val ) {
107 printf( "Setting checksum." );
108 chksum__32__set_value( bios_data, offset, new_val );
111 printf( "Multiple PCI headers! No checksum set." );
120 while( (tmp_offset = chksum__mp__get_offset( bios_data, offset )) != -1L ) {
122 cur_val = chksum__mp__get_value( bios_data, offset );
123 new_val = chksum__mp__calc_value( bios_data, offset );
124 printf( "\n\nMP header at: 0x%4lX\n", offset );
125 printf( "Current checksum: 0x%02X\n", cur_val );
126 printf( "Calculated checksum: 0x%02X ", new_val );
129 if( hits == 1 && cur_val != new_val ) {
130 printf( "Setting checksum." );
131 chksum__mp__set_value( bios_data, offset, new_val );
134 printf( "Warning! Multiple MP headers. No checksum set." );
143 while( (tmp_offset = chksum_pcmp_get_offset( bios_data, offset )) != -1L ) {
145 cur_val = chksum_pcmp_get_value( bios_data, offset );
146 new_val = chksum_pcmp_calc_value( bios_data, offset );
147 printf( "\n\nPCMP header at: 0x%4lX\n", offset );
148 printf( "Current checksum: 0x%02X\n", cur_val );
149 printf( "Calculated checksum: 0x%02X ", new_val );
152 if( hits == 1 && cur_val != new_val ) {
153 printf( "Setting checksum." );
154 chksum_pcmp_set_value( bios_data, offset, new_val );
157 printf( "Warning! Multiple PCMP headers. No checksum set." );
166 while( (tmp_offset = chksum__pir_get_offset( bios_data, offset )) != -1L ) {
168 cur_val = chksum__pir_get_value( bios_data, offset );
169 new_val = chksum__pir_calc_value( bios_data, offset );
170 printf( "\n\n$PIR header at: 0x%4lX\n", offset );
171 printf( "Current checksum: 0x%02X\n", cur_val );
172 printf( "Calculated checksum: 0x%02X\n ", new_val );
175 if( hits == 1 && cur_val != new_val ) {
176 printf( "Setting checksum." );
177 chksum__pir_set_value( bios_data, offset, new_val );
180 printf( "Warning! Multiple $PIR headers. No checksum set." );
188 offset = chksum_bios_get_offset( bios_data, offset );
189 cur_val = chksum_bios_get_value( bios_data, offset );
190 new_val = chksum_bios_calc_value( bios_data, offset );
191 printf( "\n\nBios checksum at: 0x%4lX\n", offset );
192 printf( "Current checksum: 0x%02X\n", cur_val );
193 printf( "Calculated checksum: 0x%02X ", new_val );
194 if( cur_val != new_val ) {
195 printf( "Setting checksum." );
196 chksum_bios_set_value( bios_data, offset, new_val );
201 if(( stream = fopen( argv[1], "wb" )) == NULL ) {
202 printf( "Error opening %s for writing.\n", argv[1] );
203 exit( EXIT_FAILURE );
205 if( fwrite( bios_data, 1, LEN_BIOS_DATA, stream ) < LEN_BIOS_DATA ) {
206 printf( "Error writing 64KBytes to %s.\n", argv[1] );
208 exit( EXIT_FAILURE );
212 return( EXIT_SUCCESS );
216 void check( int okay, char* message ) {
219 printf( "\n\nError. %s.\n", message );
220 exit( EXIT_FAILURE );
225 long chksum_bios_get_offset( byte* data, long offset ) {
227 return( BIOS_OFFSET );
231 byte chksum_bios_calc_value( byte* data, long offset ) {
237 for( i = 0; i < MAX_OFFSET; i++ ) {
238 sum = sum + *( data + i );
240 sum = -sum; /* iso ensures -s + s == 0 on unsigned types */
245 byte chksum_bios_get_value( byte* data, long offset ) {
247 return( *( data + BIOS_OFFSET ) );
251 void chksum_bios_set_value( byte* data, long offset, byte value ) {
253 *( data + BIOS_OFFSET ) = value;
257 byte chksum__32__calc_value( byte* data, long offset ) {
263 check( offset + _32__MINHDR <= MAX_OFFSET, "_32_ header out of bounds" );
264 len = *( data + offset + _32__LEN ) << 4;
265 check( offset + len <= MAX_OFFSET, "_32_ header-length out of bounds" );
267 for( i = 0; i < len; i++ ) {
268 if( i != _32__CHKSUM ) {
269 sum = sum + *( data + offset + i );
277 long chksum__32__get_offset( byte* data, long offset ) {
281 offset = offset + 0x0F;
282 offset = offset & ~( 0x0F );
283 while( offset + 16 < MAX_OFFSET ) {
284 offset = offset + 16;
285 if( *( data + offset + 0 ) == '_' && \
286 *( data + offset + 1 ) == '3' && \
287 *( data + offset + 2 ) == '2' && \
288 *( data + offset + 3 ) == '_' ) {
297 byte chksum__32__get_value( byte* data, long offset ) {
299 check( offset + _32__CHKSUM <= MAX_OFFSET, "PCI-Bios checksum out of bounds" );
300 return( *( data + offset + _32__CHKSUM ) );
304 void chksum__32__set_value( byte* data, long offset, byte value ) {
306 check( offset + _32__CHKSUM <= MAX_OFFSET, "PCI-Bios checksum out of bounds" );
307 *( data + offset + _32__CHKSUM ) = value;
311 byte chksum__mp__calc_value( byte* data, long offset ) {
317 check( offset + _MP__MINHDR <= MAX_OFFSET, "_MP_ header out of bounds" );
318 len = *( data + offset + _MP__LEN ) << 4;
319 check( offset + len <= MAX_OFFSET, "_MP_ header-length out of bounds" );
321 for( i = 0; i < len; i++ ) {
322 if( i != _MP__CHKSUM ) {
323 sum = sum + *( data + offset + i );
331 long chksum__mp__get_offset( byte* data, long offset ) {
335 offset = offset + 0x0F;
336 offset = offset & ~( 0x0F );
337 while( offset + 16 < MAX_OFFSET ) {
338 offset = offset + 16;
339 if( *( data + offset + 0 ) == '_' && \
340 *( data + offset + 1 ) == 'M' && \
341 *( data + offset + 2 ) == 'P' && \
342 *( data + offset + 3 ) == '_' ) {
351 byte chksum__mp__get_value( byte* data, long offset ) {
353 check( offset + _MP__CHKSUM <= MAX_OFFSET, "MP checksum out of bounds" );
354 return( *( data + offset + _MP__CHKSUM ) );
358 void chksum__mp__set_value( byte* data, long offset, byte value ) {
360 check( offset + _MP__CHKSUM <= MAX_OFFSET, "MP checksum out of bounds" );
361 *( data + offset + _MP__CHKSUM ) = value;
365 byte chksum_pcmp_calc_value( byte* data, long offset ) {
371 check( offset + PCMP_MINHDR <= MAX_OFFSET, "PCMP header out of bounds" );
372 len = *( data + offset + PCMP_BASELEN ) + \
373 ( *( data + offset + PCMP_BASELEN + 1 ) << 8 );
374 check( offset + len <= MAX_OFFSET, "PCMP header-length out of bounds" );
375 if( *( data + offset + PCMP_EXT_LEN ) | \
376 *( data + offset + PCMP_EXT_LEN + 1 ) | \
377 *( data + offset + PCMP_EXT_CHKSUM ) ) {
378 check( 0, "PCMP header indicates extended tables (unsupported)" );
381 for( i = 0; i < len; i++ ) {
382 if( i != PCMP_CHKSUM ) {
383 sum = sum + *( data + offset + i );
391 long chksum_pcmp_get_offset( byte* data, long offset ) {
395 offset = offset + 0x0F;
396 offset = offset & ~( 0x0F );
397 while( offset + 16 < MAX_OFFSET ) {
398 offset = offset + 16;
399 if( *( data + offset + 0 ) == 'P' && \
400 *( data + offset + 1 ) == 'C' && \
401 *( data + offset + 2 ) == 'M' && \
402 *( data + offset + 3 ) == 'P' ) {
411 byte chksum_pcmp_get_value( byte* data, long offset ) {
413 check( offset + PCMP_CHKSUM <= MAX_OFFSET, "PCMP checksum out of bounds" );
414 return( *( data + offset + PCMP_CHKSUM ) );
418 void chksum_pcmp_set_value( byte* data, long offset, byte value ) {
420 check( offset + PCMP_CHKSUM <= MAX_OFFSET, "PCMP checksum out of bounds" );
421 *( data + offset + PCMP_CHKSUM ) = value;
425 byte chksum__pir_calc_value( byte* data, long offset ) {
431 check( offset + _PIR_MINHDR <= MAX_OFFSET, "$PIR header out of bounds" );
432 len = *( data + offset + _PIR_LEN ) + \
433 ( *( data + offset + _PIR_LEN + 1 ) << 8 );
434 check( offset + len <= MAX_OFFSET, "$PIR header-length out of bounds" );
436 for( i = 0; i < len; i++ ) {
437 if( i != _PIR_CHKSUM ) {
438 sum = sum + *( data + offset + i );
446 long chksum__pir_get_offset( byte* data, long offset ) {
450 offset = offset + 0x0F;
451 offset = offset & ~( 0x0F );
452 while( offset + 16 < MAX_OFFSET ) {
453 offset = offset + 16;
454 if( *( data + offset + 0 ) == '$' && \
455 *( data + offset + 1 ) == 'P' && \
456 *( data + offset + 2 ) == 'I' && \
457 *( data + offset + 3 ) == 'R' ) {
466 byte chksum__pir_get_value( byte* data, long offset ) {
468 check( offset + _PIR_CHKSUM <= MAX_OFFSET, "$PIR checksum out of bounds" );
469 return( *( data + offset + _PIR_CHKSUM ) );
473 void chksum__pir_set_value( byte* data, long offset, byte value ) {
475 check( offset + _PIR_CHKSUM <= MAX_OFFSET, "$PIR checksum out of bounds" );
476 *( data + offset + _PIR_CHKSUM ) = value;