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