VirtualBox

source: vbox/trunk/src/bldprogs/biossums.c@ 13510

Last change on this file since 13510 was 13438, checked in by vboxsync, 16 years ago

OSE headers fixes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.7 KB
Line 
1/* $Id: biossums.c 13438 2008-10-21 13:08:56Z vboxsync $ */
2/** @file
3 * Tool for modifying a BIOS image to write the BIOS checksum.
4 */
5
6/*
7 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22#include <stdlib.h>
23#include <stdio.h>
24#include <string.h>
25#include <errno.h>
26
27typedef unsigned char uint8_t;
28
29static uint8_t abBios[64*1024];
30
31/**
32 * Calculate the checksum.
33 */
34static uint8_t calculateChecksum(uint8_t *pb, size_t cb, unsigned int iChecksum)
35{
36 uint8_t u8Sum = 0;
37 unsigned int i;
38
39 for (i = 0; i < cb; i++)
40 if (i != iChecksum)
41 u8Sum += pb[i];
42
43 return -u8Sum;
44}
45
46/**
47 * @param pb Where to search for the signature
48 * @param cb Size of the search area
49 * @param pbHeader Pointer to the start of the signature
50 * @returns 0 if signature was not found, 1 if found or
51 * 2 if more than one signature was found */
52static int searchHeader(uint8_t *pb, size_t cb, const char *pszHeader, uint8_t **pbHeader)
53{
54 int fFound = 0;
55 unsigned int i;
56 size_t cbSignature = strlen(pszHeader);
57
58 for (i = 0; i < cb; i += 16)
59 if (!memcmp(pb + i, pszHeader, cbSignature))
60 {
61 if (fFound++)
62 return 2;
63 *pbHeader = pb + i;
64 }
65
66 return fFound;
67}
68
69int main(int argc, char **argv)
70{
71 FILE *pIn, *pOut;
72 size_t cbIn, cbOut;
73 int fAdapterBios = 0;
74
75 if (argc != 3)
76 {
77 printf("Input file name and output file name required.\n");
78 exit(-1);
79 }
80
81 pIn = fopen(argv[1], "rb");
82 if (!pIn)
83 {
84 printf("Error opening '%s' for reading (%s).\n", argv[1], strerror(errno));
85 exit(-1);
86 }
87
88 pOut = fopen(argv[2], "wb");
89 if (!pOut)
90 {
91 printf("Error opening '%s' for writing (%s).\n", argv[2], strerror(errno));
92 exit(-1);
93 }
94
95 /* safety precaution */
96 memset(abBios, 0, sizeof(abBios));
97
98 cbIn = fread(abBios, 1, sizeof(abBios), pIn);
99 if (ferror(pIn))
100 {
101 printf("Error reading from '%s' (%s).\n", argv[1], strerror(errno));
102 fclose(pIn);
103 exit(-1);
104 }
105 fclose(pIn);
106
107 fAdapterBios = abBios[0] == 0x55 && abBios[1] == 0xaa;
108
109 /* align size to page size */
110 if ((cbIn % 4096) != 0)
111 cbIn = (cbIn + 4095) & ~4095;
112
113 if (!fAdapterBios && cbIn != 64*1024)
114 {
115 printf("Size of system BIOS is not 64KB!\n");
116 fclose(pOut);
117 exit(-1);
118 }
119
120 if (fAdapterBios)
121 {
122 /* adapter BIOS */
123
124 /* set the length indicator */
125 abBios[2] = (uint8_t)(cbIn / 512);
126 }
127 else
128 {
129 /* system BIOS */
130 size_t cbChecksum;
131 uint8_t u8Checksum;
132 uint8_t *pbHeader;
133
134 /* Set the BIOS32 header checksum. */
135 switch (searchHeader(abBios, cbIn, "_32_", &pbHeader))
136 {
137 case 0:
138 printf("No BIOS32 header not found!\n");
139 exit(-1);
140 case 2:
141 printf("More than one BIOS32 header found!\n");
142 exit(-1);
143 case 1:
144 cbChecksum = (size_t)pbHeader[9] * 16;
145 u8Checksum = calculateChecksum(pbHeader, cbChecksum, 10);
146 pbHeader[10] = u8Checksum;
147 break;
148 }
149
150 /* Set the PIR header checksum according to PCI IRQ Routing table
151 * specification version 1.0, Microsoft Corporation, 1996 */
152 switch (searchHeader(abBios, cbIn, "$PIR", &pbHeader))
153 {
154 case 0:
155 printf("No PCI IRQ routing table found!\n");
156 exit(-1);
157 case 2:
158 printf("More than one PCI IRQ routing table found!\n");
159 exit(-1);
160 case 1:
161 cbChecksum = (size_t)pbHeader[6] + (size_t)pbHeader[7] * 256;
162 u8Checksum = calculateChecksum(pbHeader, cbChecksum, 31);
163 pbHeader[31] = u8Checksum;
164 break;
165 }
166
167 /* Set the SMBIOS header checksum according to System Management BIOS
168 * Reference Specification Version 2.5, DSP0134. */
169 switch (searchHeader(abBios, cbIn, "_SM_", &pbHeader))
170 {
171 case 0:
172 printf("No SMBIOS header found!\n");
173 exit(-1);
174 case 2:
175 printf("More than one SMBIOS header found!\n");
176 exit(-1);
177 case 1:
178 /* at first fix the DMI header starting at SMBIOS header offset 16 */
179 u8Checksum = calculateChecksum(pbHeader+16, 15, 5);
180 pbHeader[21] = u8Checksum;
181
182 /* now fix the checksum of the whole SMBIOS header */
183 cbChecksum = (size_t)pbHeader[5];
184 u8Checksum = calculateChecksum(pbHeader, cbChecksum, 4);
185 pbHeader[4] = u8Checksum;
186 break;
187 }
188 }
189
190 /* set the BIOS checksum */
191 abBios[cbIn-1] = calculateChecksum(abBios, cbIn, cbIn - 1);
192
193 cbOut = fwrite(abBios, 1, cbIn, pOut);
194 if (ferror(pOut))
195 {
196 printf("Error writing to '%s' (%s).\n", argv[2], strerror(errno));
197 fclose(pOut);
198 exit(-1);
199 }
200
201 fclose(pOut);
202
203 return 0;
204}
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