VirtualBox

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

Last change on this file since 13168 was 13158, checked in by vboxsync, 16 years ago

biossums: set checksum of DMI+SMBIOS as well

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