]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/CCode/Source/GenBsfFixup/GenBsfFixup.c
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1931 6f19259b...
[mirror_edk2.git] / Tools / CCode / Source / GenBsfFixup / GenBsfFixup.c
1 /*++
2
3 Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
4 This software and associated documentation (if any) is furnished
5 under a license and may only be used or copied in accordance
6 with the terms of the license. Except as permitted by such
7 license, no part of this software or documentation may be
8 reproduced, stored in a retrieval system, or transmitted in any
9 form or by any means without the express written consent of
10 Intel Corporation.
11
12
13 Module Name:
14
15 GenBsfFixup.c
16
17 Abstract:
18
19 Utility to Fixup the SEC component for IA32. This is an
20 interim tool in place of the full GenBsfImage support for
21 IA32.
22 This tool supports the Synch3 update
23
24 --*/
25
26 #include "BaseTypes.h"
27 #include "UefiBaseTypes.h"
28 #include "EfiImage.h"
29 #include "FirmwareVolumeHeader.h"
30 #include "FirmwareVolumeImageFormat.h"
31 #include "ParseInf.h"
32 #include "CommonLib.h"
33 #include "FirmwareFileSystem.h"
34 #include "FvLib.h"
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <assert.h>
39
40 //
41 // BugBug -- this port to the new FFS is really weird.
42 // A lot of the file-header stuff has been ported, but
43 // not the section information.
44 //
45 #define TOOLVERSION "0.1"
46
47 UINT32 gFixup;
48
49 UINT32
50 GetOccupiedSize (
51 IN UINT32 ActualSize,
52 IN UINT32 Alignment
53 )
54 /*++
55
56 Routine Description:
57
58 GC_TODO: Add function description
59
60 Arguments:
61
62 ActualSize - GC_TODO: add argument description
63 Alignment - GC_TODO: add argument description
64
65 Returns:
66
67 GC_TODO: add return values
68
69 --*/
70 {
71 UINT32 OccupiedSize;
72
73 OccupiedSize = ActualSize;
74 while ((OccupiedSize & (Alignment - 1)) != 0) {
75 OccupiedSize++;
76 }
77
78 return OccupiedSize;
79 }
80
81 int
82 ReadHeader (
83 FILE *In,
84 UINT32 *FvSize
85 )
86 /*++
87
88 Routine Description:
89
90 Reads in Firmware Volume information from the volume header file.
91
92 Arguments:
93
94 In: Firmware Volume header file to read from
95 FvSize: Size of Firmware Volume
96
97 Returns:
98
99 int: Number of bytes read
100
101 --*/
102 {
103 EFI_FIRMWARE_VOLUME_HEADER VolumeHeader;
104 EFI_FV_BLOCK_MAP_ENTRY BlockMap;
105 INT32 SigTemp[2];
106 INT32 Invert;
107 INT32 bytesread;
108 UINT32 size;
109
110 size = 0;
111 Invert = 0;
112 bytesread = 0;
113
114 if (In == NULL) {
115 printf ("Error: Input file is NULL.\n");
116 return -1;
117 }
118
119 fread (&VolumeHeader, sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, In);
120 bytesread = sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY);
121 SigTemp[0] = VolumeHeader.Signature;
122 SigTemp[1] = 0;
123
124 if (VolumeHeader.Attributes & EFI_FVB_ERASE_POLARITY) {
125 Invert = 1;
126 }
127
128 do {
129 fread (&BlockMap, sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, In);
130 bytesread += sizeof (EFI_FV_BLOCK_MAP_ENTRY);
131
132 if (BlockMap.NumBlocks != 0) {
133 size += BlockMap.NumBlocks * BlockMap.BlockLength;
134 }
135
136 } while (BlockMap.NumBlocks != 0);
137
138 *FvSize = size;
139 rewind (In);
140
141 if (Invert == 1) {
142 bytesread *= -1;
143 }
144
145 return bytesread;
146 }
147
148 UINT32
149 GetSectionLength (
150 IN UINT32 *Length
151 )
152 /*++
153
154 Routine Description:
155
156 Converts a UINT8[3] array to a UINT32
157
158 Arguments:
159
160 Length A pointer to a 3 byte array
161
162 Returns:
163
164 UINT32: The length.
165
166 --*/
167 {
168 return *Length & 0x00FFFFFF;
169 }
170
171 int
172 Readfile (
173 UINT8 *FvImage,
174 int bytes,
175 int Invert
176 )
177 /*++
178
179 Routine Description:
180
181 GC_TODO: Add function description
182
183 Arguments:
184
185 FvImage - GC_TODO: add argument description
186 bytes - GC_TODO: add argument description
187 Invert - GC_TODO: add argument description
188
189 Returns:
190
191 GC_TODO: add return values
192
193 --*/
194 {
195 UINT32 FileLength;
196 UINT32 OccupiedFileLength;
197 EFI_FFS_FILE_HEADER *FileHeader;
198 UINT8 FileState;
199 UINT8 Checksum;
200 UINT8 *Ptr;
201 UINT32 SectionLength;
202 EFI_COMMON_SECTION_HEADER *SectionHeader;
203 EFI_IMAGE_NT_HEADERS *PeHeader;
204 UINT32 PeiCoreOffset;
205
206 Ptr = FvImage + bytes;
207
208 FileHeader = (EFI_FFS_FILE_HEADER *) Ptr;
209
210 FileState = GetFileState ((UINT8) Invert, FileHeader);
211
212 switch (FileState) {
213 case EFI_FILE_HEADER_CONSTRUCTION:
214 case EFI_FILE_HEADER_INVALID:
215 return sizeof (EFI_FFS_FILE_HEADER);
216
217 case EFI_FILE_HEADER_VALID:
218 Checksum = CalculateSum8 ((UINT8 *) FileHeader, sizeof (EFI_FFS_FILE_HEADER));
219 Checksum = (UINT8) (Checksum - FileHeader->IntegrityCheck.Checksum.File);
220 Checksum = (UINT8) (Checksum - FileHeader->State);
221 if (Checksum != 0) {
222 return -1;
223 }
224 //
225 // Now do the fixup stuff - begin
226 //
227 if (FileHeader->Type == EFI_FV_FILETYPE_PEI_CORE) {
228 SectionHeader = (EFI_COMMON_SECTION_HEADER *) FileHeader + sizeof (EFI_FFS_FILE_HEADER);
229 SectionLength = GetSectionLength ((UINT32 *) &SectionHeader->Size[0]);
230
231 printf ("Section length is 0x%X\n", SectionLength);
232
233 if (SectionHeader->Type == EFI_SECTION_PE32) {
234
235 gFixup = bytes + sizeof (EFI_FFS_FILE_HEADER) + sizeof (EFI_COMMON_SECTION_HEADER);
236
237 PeHeader = (EFI_IMAGE_NT_HEADERS *) Ptr + sizeof (EFI_FFS_FILE_HEADER) + sizeof (EFI_COMMON_SECTION_HEADER);
238
239 if (((EFI_IMAGE_DOS_HEADER *) PeHeader)->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
240 //
241 // DOS image header is present, so read the PE header after the DOS image header
242 //
243 PeHeader = (EFI_IMAGE_NT_HEADERS *) ((UINTN) PeHeader + (UINTN) ((((EFI_IMAGE_DOS_HEADER *) PeHeader)->e_lfanew) & 0x0ffff));
244
245 }
246
247 PeiCoreOffset = (UINTN) ((UINTN) (PeHeader->OptionalHeader.AddressOfEntryPoint & 0x0ffffffff));
248
249 gFixup += PeiCoreOffset;
250 }
251 }
252
253 FileLength = GetLength (FileHeader->Size);
254 OccupiedFileLength = GetOccupiedSize (FileLength, 8);
255 return OccupiedFileLength;
256
257 case EFI_FILE_DATA_VALID:
258 //
259 // Calculate header checksum
260 //
261 Checksum = CalculateSum8 ((UINT8 *) FileHeader, sizeof (EFI_FFS_FILE_HEADER));
262 Checksum = (UINT8) (Checksum - FileHeader->IntegrityCheck.Checksum.File);
263 Checksum = (UINT8) (Checksum - FileHeader->State);
264 if (Checksum != 0) {
265 return -1;
266 }
267 //
268 // Determine file length
269 //
270 FileLength = GetLength (FileHeader->Size);
271 OccupiedFileLength = GetOccupiedSize (FileLength, 8);
272
273 //
274 // Determine if file checksum is valid or fixed
275 //
276 if (FileHeader->Attributes & FFS_ATTRIB_CHECKSUM) {
277 Checksum = CalculateSum8 (Ptr, FileLength);
278 Checksum = (UINT8) (Checksum - FileHeader->State);
279 if (Checksum != 0) {
280 return -1;
281 }
282 } else {
283 if (FileHeader->IntegrityCheck.Checksum.File != FFS_FIXED_CHECKSUM) {
284 return -1;
285 }
286 }
287 break;
288
289 case EFI_FILE_MARKED_FOR_UPDATE:
290 case EFI_FILE_DELETED:
291 //
292 // Calculate header checksum
293 //
294 Checksum = CalculateSum8 ((UINT8 *) FileHeader, sizeof (EFI_FFS_FILE_HEADER));
295 Checksum = (UINT8) (Checksum - FileHeader->IntegrityCheck.Checksum.File);
296 Checksum = (UINT8) (Checksum - FileHeader->State);
297 if (Checksum != 0) {
298 return -1;
299 }
300 //
301 // Determine file length
302 //
303 FileLength = GetLength (FileHeader->Size);
304 OccupiedFileLength = GetOccupiedSize (FileLength, 8);
305
306 //
307 // Determine if file checksum is valid or fixed
308 //
309 if (FileHeader->Attributes & FFS_ATTRIB_CHECKSUM) {
310 Checksum = CalculateSum8 (Ptr, FileLength);
311 Checksum = (UINT8) (Checksum - FileHeader->State);
312 if (Checksum != 0) {
313 return -1;
314 }
315 } else {
316 if (FileHeader->IntegrityCheck.Checksum.File != FFS_FIXED_CHECKSUM) {
317 return -1;
318 }
319 }
320
321 return OccupiedFileLength;
322
323 default:
324 return sizeof (EFI_FFS_FILE_HEADER);
325 }
326
327 return OccupiedFileLength;
328 }
329
330 int
331 main (
332 int argc,
333 char*argv[]
334 )
335 /*++
336
337 Routine Description:
338
339 Runs GenBsfFixup
340
341 Arguments:
342
343 argc: number of command line arguments
344
345 arg[0] = This file name
346 arg[1] = Firmware Volume Name
347 arg[2] = Base Address to relocate
348 arg[3] = Relative offset of the fixup to perform
349 arg[4] = Output File Name
350
351 Returns:
352
353 int: 0 code success, -1 code failure
354
355 --*/
356 {
357 FILE *In;
358 FILE *Out;
359 int ByteStart;
360 int Invert;
361 int Index;
362 int cnt;
363 UINT8 *FvImage;
364 int ByteRead;
365 UINT32 FvSize;
366 UINT64 delta;
367 UINT32 Idx;
368 UINT64 FvOffset;
369 EFI_STATUS Status;
370
371 Index = 0;
372 Invert = 0;
373 printf (
374 "GenBsfFixup EFI 2.0. Version %s, %s\n""Copyright (c) 2000-2001, Intel Corporation\n\n",
375 TOOLVERSION,
376 __DATE__
377 );
378
379 if (argc != 5) {
380 printf ("Usage:\n"" GenBsfFixup FvVolumeImageFile AddressOfFvInMemory OffsetOfFixup OutputFileName\n");
381 return -1;
382 }
383
384 In = fopen (argv[1], "rb");
385
386 if (In == NULL) {
387 printf ("Unable to open FV image file \"%s\"\n", argv[1]);
388 return -1;
389 }
390
391 ByteStart = ReadHeader (In, &FvSize);
392
393 if (ByteStart < 0) {
394 Invert = 1;
395 ByteStart *= -1;
396 }
397
398 FvImage = malloc (FvSize);
399 if (FvImage == NULL) {
400 printf ("Cannot allocate memory\n");
401 fclose (In);
402 return -1;
403 }
404
405 ByteRead = fread (FvImage, 1, FvSize, In);
406
407 if ((unsigned int) ByteRead != FvSize) {
408 printf ("Read File error\n");
409 fclose (In);
410 return -1;
411 }
412
413 cnt = 0;
414 while ((unsigned int) ByteStart < FvSize && cnt != -1) {
415 cnt = Readfile (FvImage, ByteStart, Invert);
416
417 if (cnt != -1) {
418 ByteStart += cnt;
419 }
420
421 if (cnt != sizeof (EFI_FFS_FILE_HEADER)) {
422 Index++;
423 }
424 }
425
426 if (cnt == -1) {
427 printf ("Firmware Volume image corrupted\n");
428 return -1;
429 }
430
431 fclose (In);
432
433 Out = fopen (argv[4], "wb");
434
435 if (Out == NULL) {
436 printf ("Unable to open FV image file \"%s\"\n", argv[4]);
437 return -1;
438 }
439
440 In = fopen (argv[1], "rb");
441
442 if (In == NULL) {
443 printf ("Unable to open FV image file \"%s\"\n", argv[1]);
444 return -1;
445 }
446
447 if (gFixup != 0) {
448
449 printf ("Fixup of 0x%X\n", gFixup);
450
451 Status = AsciiStringToUint64 (argv[2], TRUE, &FvOffset);
452
453 gFixup += (UINT32) FvOffset;
454
455 ByteStart = ReadHeader (In, &FvSize);
456
457 Readfile (FvImage, ByteStart, Invert);
458
459 cnt = 0;
460 Status = AsciiStringToUint64 (argv[3], TRUE, &delta);
461
462 fclose (In);
463 In = fopen (argv[1], "rb");
464
465 if (In == NULL) {
466 printf ("Unable to open FV image file \"%s\"\n", argv[1]);
467 return -1;
468 }
469
470 for (Idx = 0; Idx < delta - FvOffset; Idx++) {
471 fputc (fgetc (In), Out);
472 }
473
474 fwrite (&gFixup, sizeof (UINT32), 1, Out);
475 fseek (In, sizeof (UINT32), SEEK_CUR);
476
477 for (Idx = 0; Idx < FvSize - (delta - FvOffset) - sizeof (UINT32); Idx++) {
478 fputc (fgetc (In), Out);
479 }
480
481 fclose (In);
482 fclose (Out);
483 } else {
484 printf ("There was no fixup to perform\n");
485 }
486
487 free (FvImage);
488
489 return 0;
490 }