VirtualBox

source: vbox/trunk/src/VBox/Devices/PC/BIOS/biossums.c@ 10719

Last change on this file since 10719 was 9532, checked in by vboxsync, 17 years ago

biossums.c license taken from BOCHS

  • Property svn:eol-style set to native
File size: 12.8 KB
Line 
1/*
2 * $Id: biossums.c,v 1.4 2007/05/28 08:09:13 vruppert Exp $
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19/* biossums.c --- written by Eike W. */
20
21#include <stdlib.h>
22#include <stdio.h>
23
24typedef unsigned char byte;
25
26void check( int value, char* message );
27
28#define LEN_BIOS_DATA 0x10000
29#define MAX_OFFSET (LEN_BIOS_DATA - 1)
30
31
32#define BIOS_OFFSET 0xFFFF
33
34long chksum_bios_get_offset( byte* data, long offset );
35byte chksum_bios_calc_value( byte* data, long offset );
36byte chksum_bios_get_value( byte* data, long offset );
37void chksum_bios_set_value( byte* data, long offset, byte value );
38
39
40#define _32__LEN 9
41#define _32__CHKSUM 10
42
43#define _32__MINHDR 16
44
45long chksum__32__get_offset( byte* data, long offset );
46byte chksum__32__calc_value( byte* data, long offset );
47byte chksum__32__get_value( byte* data, long offset );
48void chksum__32__set_value( byte* data, long offset, byte value );
49
50
51#define _MP__LEN 8
52#define _MP__CHKSUM 10
53
54#define _MP__MINHDR 16
55
56long chksum__mp__get_offset( byte* data, long offset );
57byte chksum__mp__calc_value( byte* data, long offset );
58byte chksum__mp__get_value( byte* data, long offset );
59void chksum__mp__set_value( byte* data, long offset, byte value );
60
61
62#define PCMP_BASELEN 4
63#define PCMP_CHKSUM 7
64#define PCMP_EXT_LEN 40
65#define PCMP_EXT_CHKSUM 42
66
67#define PCMP_MINHDR 42
68
69long chksum_pcmp_get_offset( byte* data, long offset );
70byte chksum_pcmp_calc_value( byte* data, long offset );
71byte chksum_pcmp_get_value( byte* data, long offset );
72void chksum_pcmp_set_value( byte* data, long offset, byte value );
73
74
75#define _PIR_LEN 6
76#define _PIR_CHKSUM 31
77
78#define _PIR_MINHDR 32
79
80long chksum__pir_get_offset( byte *data, long offset );
81byte chksum__pir_calc_value( byte* data, long offset );
82byte chksum__pir_get_value( byte* data, long offset );
83void chksum__pir_set_value( byte* data, long offset, byte value );
84
85
86byte bios_data[LEN_BIOS_DATA];
87
88
89int main( int argc, char* argv[] ) {
90
91 FILE* stream;
92 long offset, tmp_offset;
93 byte cur_val = 0, new_val = 0;
94 int hits;
95
96
97 if( argc != 2 ) {
98 printf( "Error. Need a file-name as an argument.\n" );
99 exit( EXIT_FAILURE );
100 }
101
102 if(( stream = fopen( argv[1], "rb" )) == NULL ) {
103 printf( "Error opening %s for reading.\n", argv[1] );
104 exit( EXIT_FAILURE );
105 }
106 if( fread( bios_data, 1, LEN_BIOS_DATA, stream ) < LEN_BIOS_DATA ) {
107 printf( "Error reading 64KBytes from %s.\n", argv[1] );
108 fclose( stream );
109 exit( EXIT_FAILURE );
110 }
111 fclose( stream );
112
113 hits = 0;
114 offset = 0L;
115 while( (tmp_offset = chksum__32__get_offset( bios_data, offset )) != -1L ) {
116 offset = tmp_offset;
117 cur_val = chksum__32__get_value( bios_data, offset );
118 new_val = chksum__32__calc_value( bios_data, offset );
119 printf( "\nPCI-Bios header at: 0x%4lX\n", offset );
120 printf( "Current checksum: 0x%02X\n", cur_val );
121 printf( "Calculated checksum: 0x%02X ", new_val );
122 hits++;
123 }
124 if( hits == 1 && cur_val != new_val ) {
125 printf( "Setting checksum." );
126 chksum__32__set_value( bios_data, offset, new_val );
127 }
128 if( hits >= 2 ) {
129 printf( "Multiple PCI headers! No checksum set." );
130 }
131 if( hits ) {
132 printf( "\n" );
133 }
134
135
136 hits = 0;
137 offset = 0L;
138 while( (tmp_offset = chksum__mp__get_offset( bios_data, offset )) != -1L ) {
139 offset = tmp_offset;
140 cur_val = chksum__mp__get_value( bios_data, offset );
141 new_val = chksum__mp__calc_value( bios_data, offset );
142 printf( "\nMP header at: 0x%4lX\n", offset );
143 printf( "Current checksum: 0x%02X\n", cur_val );
144 printf( "Calculated checksum: 0x%02X ", new_val );
145 hits++;
146 }
147 if( hits == 1 && cur_val != new_val ) {
148 printf( "Setting checksum." );
149 chksum__mp__set_value( bios_data, offset, new_val );
150 }
151 if( hits >= 2 ) {
152 printf( "Warning! Multiple MP headers. No checksum set." );
153 }
154 if( hits ) {
155 printf( "\n" );
156 }
157
158
159 hits = 0;
160 offset = 0L;
161 while( (tmp_offset = chksum_pcmp_get_offset( bios_data, offset )) != -1L ) {
162 offset = tmp_offset;
163 cur_val = chksum_pcmp_get_value( bios_data, offset );
164 new_val = chksum_pcmp_calc_value( bios_data, offset );
165 printf( "\nPCMP header at: 0x%4lX\n", offset );
166 printf( "Current checksum: 0x%02X\n", cur_val );
167 printf( "Calculated checksum: 0x%02X ", new_val );
168 hits++;
169 }
170 if( hits == 1 && cur_val != new_val ) {
171 printf( "Setting checksum." );
172 chksum_pcmp_set_value( bios_data, offset, new_val );
173 }
174 if( hits >= 2 ) {
175 printf( "Warning! Multiple PCMP headers. No checksum set." );
176 }
177 if( hits ) {
178 printf( "\n" );
179 }
180
181
182 hits = 0;
183 offset = 0L;
184 while( (tmp_offset = chksum__pir_get_offset( bios_data, offset )) != -1L ) {
185 offset = tmp_offset;
186 cur_val = chksum__pir_get_value( bios_data, offset );
187 new_val = chksum__pir_calc_value( bios_data, offset );
188 printf( "\n$PIR header at: 0x%4lX\n", offset );
189 printf( "Current checksum: 0x%02X\n", cur_val );
190 printf( "Calculated checksum: 0x%02X ", new_val );
191 hits++;
192 }
193 if( hits == 1 && cur_val != new_val ) {
194 printf( "Setting checksum." );
195 chksum__pir_set_value( bios_data, offset, new_val );
196 }
197 if( hits >= 2 ) {
198 printf( "Warning! Multiple $PIR headers. No checksum set." );
199 }
200 if( hits ) {
201 printf( "\n" );
202 }
203
204
205 offset = 0L;
206 offset = chksum_bios_get_offset( bios_data, offset );
207 cur_val = chksum_bios_get_value( bios_data, offset );
208 new_val = chksum_bios_calc_value( bios_data, offset );
209 printf( "\nBios checksum at: 0x%4lX\n", offset );
210 printf( "Current checksum: 0x%02X\n", cur_val );
211 printf( "Calculated checksum: 0x%02X ", new_val );
212 if( cur_val != new_val ) {
213 printf( "Setting checksum." );
214 chksum_bios_set_value( bios_data, offset, new_val );
215 }
216 printf( "\n\n" );
217
218
219 if(( stream = fopen( argv[1], "wb" )) == NULL ) {
220 printf( "Error opening %s for writing.\n", argv[1] );
221 exit( EXIT_FAILURE );
222 }
223 if( fwrite( bios_data, 1, LEN_BIOS_DATA, stream ) < LEN_BIOS_DATA ) {
224 printf( "Error writing 64KBytes to %s.\n", argv[1] );
225 fclose( stream );
226 exit( EXIT_FAILURE );
227 }
228 fclose( stream );
229
230 return( EXIT_SUCCESS );
231}
232
233
234void check( int okay, char* message ) {
235
236 if( !okay ) {
237 printf( "\n\nError. %s.\n", message );
238 exit( EXIT_FAILURE );
239 }
240}
241
242
243long chksum_bios_get_offset( byte* data, long offset ) {
244
245 return( BIOS_OFFSET );
246}
247
248
249byte chksum_bios_calc_value( byte* data, long offset ) {
250
251 int i;
252 byte sum;
253
254 sum = 0;
255 for( i = 0; i < MAX_OFFSET; i++ ) {
256 sum = sum + *( data + i );
257 }
258 sum = -sum; /* iso ensures -s + s == 0 on unsigned types */
259 return( sum );
260}
261
262
263byte chksum_bios_get_value( byte* data, long offset ) {
264
265 return( *( data + BIOS_OFFSET ) );
266}
267
268
269void chksum_bios_set_value( byte* data, long offset, byte value ) {
270
271 *( data + BIOS_OFFSET ) = value;
272}
273
274
275byte chksum__32__calc_value( byte* data, long offset ) {
276
277 int i;
278 int len;
279 byte sum;
280
281 check( offset + _32__MINHDR <= MAX_OFFSET, "_32_ header out of bounds" );
282 len = *( data + offset + _32__LEN ) << 4;
283 check( offset + len <= MAX_OFFSET, "_32_ header-length out of bounds" );
284 sum = 0;
285 for( i = 0; i < len; i++ ) {
286 if( i != _32__CHKSUM ) {
287 sum = sum + *( data + offset + i );
288 }
289 }
290 sum = -sum;
291 return( sum );
292}
293
294
295long chksum__32__get_offset( byte* data, long offset ) {
296
297 long result = -1L;
298
299 offset = offset + 0x0F;
300 offset = offset & ~( 0x0F );
301 while( offset + 16 < MAX_OFFSET ) {
302 offset = offset + 16;
303 if( *( data + offset + 0 ) == '_' && \
304 *( data + offset + 1 ) == '3' && \
305 *( data + offset + 2 ) == '2' && \
306 *( data + offset + 3 ) == '_' ) {
307 result = offset;
308 break;
309 }
310 }
311 return( result );
312}
313
314
315byte chksum__32__get_value( byte* data, long offset ) {
316
317 check( offset + _32__CHKSUM <= MAX_OFFSET, "PCI-Bios checksum out of bounds" );
318 return( *( data + offset + _32__CHKSUM ) );
319}
320
321
322void chksum__32__set_value( byte* data, long offset, byte value ) {
323
324 check( offset + _32__CHKSUM <= MAX_OFFSET, "PCI-Bios checksum out of bounds" );
325 *( data + offset + _32__CHKSUM ) = value;
326}
327
328
329byte chksum__mp__calc_value( byte* data, long offset ) {
330
331 int i;
332 int len;
333 byte sum;
334
335 check( offset + _MP__MINHDR <= MAX_OFFSET, "_MP_ header out of bounds" );
336 len = *( data + offset + _MP__LEN ) << 4;
337 check( offset + len <= MAX_OFFSET, "_MP_ header-length out of bounds" );
338 sum = 0;
339 for( i = 0; i < len; i++ ) {
340 if( i != _MP__CHKSUM ) {
341 sum = sum + *( data + offset + i );
342 }
343 }
344 sum = -sum;
345 return( sum );
346}
347
348
349long chksum__mp__get_offset( byte* data, long offset ) {
350
351 long result = -1L;
352
353 offset = offset + 0x0F;
354 offset = offset & ~( 0x0F );
355 while( offset + 16 < MAX_OFFSET ) {
356 offset = offset + 16;
357 if( *( data + offset + 0 ) == '_' && \
358 *( data + offset + 1 ) == 'M' && \
359 *( data + offset + 2 ) == 'P' && \
360 *( data + offset + 3 ) == '_' ) {
361 result = offset;
362 break;
363 }
364 }
365 return( result );
366}
367
368
369byte chksum__mp__get_value( byte* data, long offset ) {
370
371 check( offset + _MP__CHKSUM <= MAX_OFFSET, "MP checksum out of bounds" );
372 return( *( data + offset + _MP__CHKSUM ) );
373}
374
375
376void chksum__mp__set_value( byte* data, long offset, byte value ) {
377
378 check( offset + _MP__CHKSUM <= MAX_OFFSET, "MP checksum out of bounds" );
379 *( data + offset + _MP__CHKSUM ) = value;
380}
381
382
383byte chksum_pcmp_calc_value( byte* data, long offset ) {
384
385 int i;
386 int len;
387 byte sum;
388
389 check( offset + PCMP_MINHDR <= MAX_OFFSET, "PCMP header out of bounds" );
390 len = *( data + offset + PCMP_BASELEN ) + \
391 ( *( data + offset + PCMP_BASELEN + 1 ) << 8 );
392 check( offset + len <= MAX_OFFSET, "PCMP header-length out of bounds" );
393 if( *( data + offset + PCMP_EXT_LEN ) | \
394 *( data + offset + PCMP_EXT_LEN + 1 ) | \
395 *( data + offset + PCMP_EXT_CHKSUM ) ) {
396 check( 0, "PCMP header indicates extended tables (unsupported)" );
397 }
398 sum = 0;
399 for( i = 0; i < len; i++ ) {
400 if( i != PCMP_CHKSUM ) {
401 sum = sum + *( data + offset + i );
402 }
403 }
404 sum = -sum;
405 return( sum );
406}
407
408
409long chksum_pcmp_get_offset( byte* data, long offset ) {
410
411 long result = -1L;
412
413 offset = offset + 0x0F;
414 offset = offset & ~( 0x0F );
415 while( offset + 16 < MAX_OFFSET ) {
416 offset = offset + 16;
417 if( *( data + offset + 0 ) == 'P' && \
418 *( data + offset + 1 ) == 'C' && \
419 *( data + offset + 2 ) == 'M' && \
420 *( data + offset + 3 ) == 'P' ) {
421 result = offset;
422 break;
423 }
424 }
425 return( result );
426}
427
428
429byte chksum_pcmp_get_value( byte* data, long offset ) {
430
431 check( offset + PCMP_CHKSUM <= MAX_OFFSET, "PCMP checksum out of bounds" );
432 return( *( data + offset + PCMP_CHKSUM ) );
433}
434
435
436void chksum_pcmp_set_value( byte* data, long offset, byte value ) {
437
438 check( offset + PCMP_CHKSUM <= MAX_OFFSET, "PCMP checksum out of bounds" );
439 *( data + offset + PCMP_CHKSUM ) = value;
440}
441
442
443byte chksum__pir_calc_value( byte* data, long offset ) {
444
445 int i;
446 int len;
447 byte sum;
448
449 check( offset + _PIR_MINHDR <= MAX_OFFSET, "$PIR header out of bounds" );
450 len = *( data + offset + _PIR_LEN ) + \
451 ( *( data + offset + _PIR_LEN + 1 ) << 8 );
452 check( offset + len <= MAX_OFFSET, "$PIR header-length out of bounds" );
453 sum = 0;
454 for( i = 0; i < len; i++ ) {
455 if( i != _PIR_CHKSUM ) {
456 sum = sum + *( data + offset + i );
457 }
458 }
459 sum = -sum;
460 return( sum );
461}
462
463
464long chksum__pir_get_offset( byte* data, long offset ) {
465
466 long result = -1L;
467
468 offset = offset + 0x0F;
469 offset = offset & ~( 0x0F );
470 while( offset + 16 < MAX_OFFSET ) {
471 offset = offset + 16;
472 if( *( data + offset + 0 ) == '$' && \
473 *( data + offset + 1 ) == 'P' && \
474 *( data + offset + 2 ) == 'I' && \
475 *( data + offset + 3 ) == 'R' ) {
476 result = offset;
477 break;
478 }
479 }
480 return( result );
481}
482
483
484byte chksum__pir_get_value( byte* data, long offset ) {
485
486 check( offset + _PIR_CHKSUM <= MAX_OFFSET, "$PIR checksum out of bounds" );
487 return( *( data + offset + _PIR_CHKSUM ) );
488}
489
490
491void chksum__pir_set_value( byte* data, long offset, byte value ) {
492
493 check( offset + _PIR_CHKSUM <= MAX_OFFSET, "$PIR checksum out of bounds" );
494 *( data + offset + _PIR_CHKSUM ) = value;
495}
496
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette