|
|
1.1 ! root 1: /* biossums.c --- written by Eike W. for the Bochs BIOS */ ! 2: /* adapted for the LGPL'd VGABIOS by vruppert */ ! 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: #include <stdlib.h> ! 19: #include <stdio.h> ! 20: #include <string.h> ! 21: ! 22: typedef unsigned char byte; ! 23: ! 24: void check( int value, char* message ); ! 25: ! 26: #define MAX_BIOS_DATA 0x10000 ! 27: ! 28: long chksum_bios_get_offset( byte* data, long offset ); ! 29: byte chksum_bios_calc_value( byte* data, long offset ); ! 30: byte chksum_bios_get_value( byte* data, long offset ); ! 31: void chksum_bios_set_value( byte* data, long offset, byte value ); ! 32: ! 33: #define PMID_LEN 20 ! 34: #define PMID_CHKSUM 19 ! 35: ! 36: long chksum_pmid_get_offset( byte* data, long offset ); ! 37: byte chksum_pmid_calc_value( byte* data, long offset ); ! 38: byte chksum_pmid_get_value( byte* data, long offset ); ! 39: void chksum_pmid_set_value( byte* data, long offset, byte value ); ! 40: ! 41: #define PCIR_LEN 24 ! 42: ! 43: long chksum_pcir_get_offset( byte* data, long offset ); ! 44: ! 45: ! 46: byte bios_data[MAX_BIOS_DATA]; ! 47: long bios_len; ! 48: ! 49: ! 50: int main(int argc, char* argv[]) ! 51: { ! 52: FILE* stream; ! 53: long offset, tmp_offset, pcir_offset; ! 54: byte bios_len_byte, cur_val = 0, new_val = 0; ! 55: int hits, modified; ! 56: ! 57: if (argc != 2) { ! 58: printf( "Error. Need a file-name as an argument.\n" ); ! 59: exit( EXIT_FAILURE ); ! 60: } ! 61: ! 62: if ((stream = fopen(argv[1], "rb")) == NULL) { ! 63: printf("Error opening %s for reading.\n", argv[1]); ! 64: exit(EXIT_FAILURE); ! 65: } ! 66: memset(bios_data, 0, MAX_BIOS_DATA); ! 67: bios_len = fread(bios_data, 1, MAX_BIOS_DATA, stream); ! 68: if (bios_len > MAX_BIOS_DATA) { ! 69: printf("Error reading max. 65536 Bytes from %s.\n", argv[1]); ! 70: fclose(stream); ! 71: exit(EXIT_FAILURE); ! 72: } ! 73: fclose(stream); ! 74: modified = 0; ! 75: if (bios_len < 0x8000) { ! 76: bios_len = 0x8000; ! 77: modified = 1; ! 78: } else if ((bios_len & 0x1FF) != 0) { ! 79: bios_len = (bios_len + 0x200) & ~0x1FF; ! 80: modified = 1; ! 81: } ! 82: bios_len_byte = (byte)(bios_len / 512); ! 83: if (bios_len_byte != bios_data[2]) { ! 84: if (modified == 0) { ! 85: bios_len += 0x200; ! 86: } ! 87: bios_data[2] = (byte)(bios_len / 512); ! 88: modified = 1; ! 89: } ! 90: ! 91: hits = 0; ! 92: offset = 0L; ! 93: while( (tmp_offset = chksum_pmid_get_offset( bios_data, offset )) != -1L ) { ! 94: offset = tmp_offset; ! 95: cur_val = chksum_pmid_get_value( bios_data, offset ); ! 96: new_val = chksum_pmid_calc_value( bios_data, offset ); ! 97: printf( "\nPMID entry at: 0x%4lX\n", offset ); ! 98: printf( "Current checksum: 0x%02X\n", cur_val ); ! 99: printf( "Calculated checksum: 0x%02X ", new_val ); ! 100: hits++; ! 101: } ! 102: if ((hits == 1) && (cur_val != new_val)) { ! 103: printf("Setting checksum."); ! 104: chksum_pmid_set_value( bios_data, offset, new_val ); ! 105: if (modified == 0) { ! 106: bios_len += 0x200; ! 107: bios_data[2]++; ! 108: } ! 109: modified = 1; ! 110: } ! 111: if (hits >= 2) { ! 112: printf( "Multiple PMID entries! No checksum set." ); ! 113: } ! 114: if (hits) { ! 115: printf("\n"); ! 116: } ! 117: ! 118: offset = 0L; ! 119: pcir_offset = chksum_pcir_get_offset( bios_data, offset ); ! 120: if (pcir_offset != -1L) { ! 121: if (bios_data[pcir_offset + 16] != bios_data[2]) { ! 122: bios_data[pcir_offset + 16] = bios_data[2]; ! 123: if (modified == 0) { ! 124: bios_len += 0x200; ! 125: bios_data[2]++; ! 126: bios_data[pcir_offset + 16]++; ! 127: } ! 128: modified = 1; ! 129: } ! 130: } ! 131: ! 132: offset = 0L; ! 133: do { ! 134: offset = chksum_bios_get_offset(bios_data, offset); ! 135: cur_val = chksum_bios_get_value(bios_data, offset); ! 136: new_val = chksum_bios_calc_value(bios_data, offset); ! 137: if ((cur_val != new_val) && (modified == 0)) { ! 138: bios_len += 0x200; ! 139: bios_data[2]++; ! 140: if (pcir_offset != -1L) { ! 141: bios_data[pcir_offset + 16]++; ! 142: } ! 143: modified = 1; ! 144: } else { ! 145: printf("\nBios checksum at: 0x%4lX\n", offset); ! 146: printf("Current checksum: 0x%02X\n", cur_val); ! 147: printf("Calculated checksum: 0x%02X ", new_val); ! 148: if (cur_val != new_val) { ! 149: printf("Setting checksum."); ! 150: chksum_bios_set_value(bios_data, offset, new_val); ! 151: cur_val = new_val; ! 152: modified = 1; ! 153: } ! 154: printf( "\n" ); ! 155: } ! 156: } while (cur_val != new_val); ! 157: ! 158: if (modified == 1) { ! 159: if ((stream = fopen( argv[1], "wb")) == NULL) { ! 160: printf("Error opening %s for writing.\n", argv[1]); ! 161: exit(EXIT_FAILURE); ! 162: } ! 163: if (fwrite(bios_data, 1, bios_len, stream) < bios_len) { ! 164: printf("Error writing %d KBytes to %s.\n", bios_len / 1024, argv[1]); ! 165: fclose(stream); ! 166: exit(EXIT_FAILURE); ! 167: } ! 168: fclose(stream); ! 169: } ! 170: ! 171: return (EXIT_SUCCESS); ! 172: } ! 173: ! 174: ! 175: void check( int okay, char* message ) { ! 176: ! 177: if( !okay ) { ! 178: printf( "\n\nError. %s.\n", message ); ! 179: exit( EXIT_FAILURE ); ! 180: } ! 181: } ! 182: ! 183: ! 184: long chksum_bios_get_offset( byte* data, long offset ) { ! 185: ! 186: return (bios_len - 1); ! 187: } ! 188: ! 189: ! 190: byte chksum_bios_calc_value( byte* data, long offset ) { ! 191: ! 192: int i; ! 193: byte sum; ! 194: ! 195: sum = 0; ! 196: for( i = 0; i < offset; i++ ) { ! 197: sum = sum + *( data + i ); ! 198: } ! 199: sum = -sum; /* iso ensures -s + s == 0 on unsigned types */ ! 200: return( sum ); ! 201: } ! 202: ! 203: ! 204: byte chksum_bios_get_value( byte* data, long offset ) { ! 205: ! 206: return( *( data + offset ) ); ! 207: } ! 208: ! 209: ! 210: void chksum_bios_set_value( byte* data, long offset, byte value ) { ! 211: ! 212: *( data + offset ) = value; ! 213: } ! 214: ! 215: ! 216: byte chksum_pmid_calc_value( byte* data, long offset ) { ! 217: ! 218: int i; ! 219: int len; ! 220: byte sum; ! 221: ! 222: len = PMID_LEN; ! 223: check((offset + len) <= (bios_len - 1), "PMID entry length out of bounds" ); ! 224: sum = 0; ! 225: for( i = 0; i < len; i++ ) { ! 226: if( i != PMID_CHKSUM ) { ! 227: sum = sum + *( data + offset + i ); ! 228: } ! 229: } ! 230: sum = -sum; ! 231: return( sum ); ! 232: } ! 233: ! 234: ! 235: long chksum_pmid_get_offset( byte* data, long offset ) { ! 236: ! 237: long result = -1L; ! 238: ! 239: while ((offset + PMID_LEN) < (bios_len - 1)) { ! 240: offset = offset + 1; ! 241: if( *( data + offset + 0 ) == 'P' && \ ! 242: *( data + offset + 1 ) == 'M' && \ ! 243: *( data + offset + 2 ) == 'I' && \ ! 244: *( data + offset + 3 ) == 'D' ) { ! 245: result = offset; ! 246: break; ! 247: } ! 248: } ! 249: return( result ); ! 250: } ! 251: ! 252: ! 253: byte chksum_pmid_get_value( byte* data, long offset ) { ! 254: ! 255: check((offset + PMID_CHKSUM) <= (bios_len - 1), "PMID checksum out of bounds" ); ! 256: return( *( data + offset + PMID_CHKSUM ) ); ! 257: } ! 258: ! 259: ! 260: void chksum_pmid_set_value( byte* data, long offset, byte value ) { ! 261: ! 262: check((offset + PMID_CHKSUM) <= (bios_len - 1), "PMID checksum out of bounds" ); ! 263: *( data + offset + PMID_CHKSUM ) = value; ! 264: } ! 265: ! 266: ! 267: long chksum_pcir_get_offset( byte* data, long offset ) { ! 268: ! 269: long result = -1L; ! 270: ! 271: while ((offset + PCIR_LEN) < (bios_len - 1)) { ! 272: offset = offset + 1; ! 273: if( *( data + offset + 0 ) == 'P' && \ ! 274: *( data + offset + 1 ) == 'C' && \ ! 275: *( data + offset + 2 ) == 'I' && \ ! 276: *( data + offset + 3 ) == 'R' ) { ! 277: result = offset; ! 278: break; ! 279: } ! 280: } ! 281: return( result ); ! 282: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.