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
;