VirtualBox

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

Last change on this file since 13002 was 11982, checked in by vboxsync, 16 years ago

All: license header changes for 2.0 (OSE headers, add Sun GPL/LGPL disclaimer)

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