4 GenFfsFileTaks is to generate ffs file.
6 Copyright (c) 2006, Intel Corporation
7 All rights reserved. This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 package org
.tianocore
.framework
.tasks
;
18 import java
.io
.DataInputStream
;
19 import java
.io
.DataOutputStream
;
21 import java
.io
.FileInputStream
;
22 import java
.io
.FileOutputStream
;
23 import java
.util
.ArrayList
;
24 import java
.util
.Iterator
;
25 import java
.util
.List
;
27 import org
.apache
.tools
.ant
.BuildException
;
28 import org
.apache
.tools
.ant
.Project
;
29 import org
.apache
.tools
.ant
.Task
;
34 GenFfsFileTaks is to generate ffs file.
37 public class GenFfsFileTask
extends Task
implements EfiDefine
, FfsTypes
{
39 * GenFfsFile Task Class
41 * -baseName : module baseName
42 * -ffsFileGuid : module Guid.
43 * -ffsFileType : Ffs file type.
44 * -ffsAttributeRecovery : The file is required for recovery.
45 * -ffsAligment : The file data alignment (0 if none required). See FFS
46 * specification for supported alignments (0-7 are only possible
48 * -ffsAttributeCheckSum : The file data is checksummed. If this is FALSE a
49 * value of 0x5A will be inserted in the file
50 * checksum field of the file header. *
51 * -sectFileDir : specifies the full path to the component build directory.
53 * -ffsAttrib : Data recorde attribute added result.
54 * -sectionList : List recorded all section elemet in task.
63 String ffsFileGuid
= "";
67 String ffsFileType
= "";
69 /// ffsAttribHeaderExtension value is used to set the corresponding bit in
70 /// the output FFS file header
72 boolean ffsAttribHeaderExtension
= false;
74 /// ffsAttribTailPresent value is used to set the corresponding bit in the
75 /// output FFS file header
77 boolean ffsAttribTailPresent
= false;
79 /// ffsAttribRecovery value is used to set the corresponding bit in the
80 /// output FFS file header
82 boolean ffsAttribRecovery
= false;
84 /// ffsAligenment value is used to set the corresponding bit in the output
85 /// FFS file header.The specified FFS alignment must be a value between 0
90 /// ffsAttribChecksum value is used to set the corresponding bit in the
91 /// output FFS file header
93 boolean FfsAttribChecksum
= false;
95 /// Attribute is used to record the sum of all bit in the output FFS file.
99 /// The output directory of ffs file.
101 String outputDir
= "";
105 List
<Object
> sectionList
= new ArrayList
<Object
>();
108 /// The path of Framewor_Tools_Paht.
110 static String path
= "";
115 GenFfsFileTask execute is to generate ffs file according to input section
116 dscriptive information.
118 public void execute() throws BuildException
{
123 FfsHeader ffsHeader
= new FfsHeader();
124 String ffsSuffix
= "";
125 String outputPath
= "";
128 // Get Fraemwork_Tools_Path
130 Project pj
= this.getOwningTarget().getProject();
131 path
= pj
.getProperty("env.Framework_Tools_Path");
134 // Check does the BaseName, Guid, FileType set value.
136 if (this.baseName
.equals("")) {
137 throw new BuildException ("Must set BaseName!\n");
140 if (this.ffsFileGuid
.equals("")) {
141 throw new BuildException ("Must set ffsFileGuid!\n");
144 if (this.ffsFileType
.equals("")) {
145 throw new BuildException ("Must set ffsFileType!\n");
149 // Create ffs file. File name = FfsFileGuid + BaseName + ffsSuffix.
150 // If outputDir's value was set, file will output to the outputDir.
152 ffsSuffix
= TypeToSuffix (this.ffsFileType
);
153 if (!this.outputDir
.equals("")) {
155 outputPath
= this.outputDir
;
156 temp
= outputPath
.replace('\\', File
.separatorChar
);
157 outputPath
= temp
.replace('/', File
.separatorChar
);
158 if (outputPath
.charAt(outputPath
.length()-1) != File
.separatorChar
) {
159 outputPath
= outputPath
+ File
.separator
;
164 ffsFile
= new File (outputPath
+ this.ffsFileGuid
+ '-' + this.baseName
+ ffsSuffix
);
165 System
.out
.print("General Ffs file: file name is:\n");
166 System
.out
.print(outputPath
+ this.ffsFileGuid
+ '-' + this.baseName
+ ffsSuffix
);
167 System
.out
.print("\n");
170 // Create file output stream -- dataBuffer.
173 FileOutputStream dataFs
= new FileOutputStream (ffsFile
.getAbsolutePath());
174 DataOutputStream dataBuffer
= new DataOutputStream (dataFs
);
177 // Search SectionList find earch section and call it's
178 // ToBuffer function.
180 Iterator sectionIter
= this.sectionList
.iterator();
181 while (sectionIter
.hasNext()) {
182 sect
= (Section
)sectionIter
.next();
186 // The last section don't need 4 byte ffsAligment.
188 sect
.toBuffer((DataOutputStream
)dataBuffer
);
189 } catch (Exception e
) {
190 throw new BuildException (e
.getMessage());
194 } catch (Exception e
) {
195 throw new BuildException (e
.getMessage());
199 // Creat Ffs file header
204 // create input stream to read file data
206 byte[] fileBuffer
= new byte[(int)ffsFile
.length()];
207 FileInputStream fi
= new FileInputStream (ffsFile
.getAbsolutePath());
208 DataInputStream di
= new DataInputStream (fi
);
214 // Add GUID to header struct
216 if (this.ffsFileGuid
!= null) {
217 stringToGuid (this.ffsFileGuid
, ffsHeader
.name
);
220 ffsHeader
.ffsAttributes
= this.attributes
;
221 if ((ffsHeader
.fileType
= stringToType(this.ffsFileType
))== -1) {
222 throw new BuildException ("FFS_FILE_TYPE unknow!\n");
227 // Adjust file size. The function is used to tripe the last
228 // section padding of 4 binary boundary.
231 if (ffsHeader
.fileType
!= EFI_FV_FILETYPE_RAW
) {
233 fileDataSize
= adjustFileSize (fileBuffer
);
236 fileDataSize
= fileBuffer
.length
;
240 // 1. add header size to file size
242 fileSize
= fileDataSize
+ ffsHeader
.getSize();
244 if ((ffsHeader
.ffsAttributes
& FFS_ATTRIB_TAIL_PRESENT
) != 0) {
245 if (ffsHeader
.fileType
== EFI_FV_FILETYPE_FFS_PAD
) {
247 throw new BuildException (
248 "FFS_ATTRIB_TAIL_PRESENT=TRUE is " +
249 "invalid for PAD files"
252 if (fileSize
== ffsHeader
.getSize()) {
253 throw new BuildException (
254 "FFS_ATTRIB_TAIL_PRESENT=TRUE is " +
255 "invalid for 0-length files"
258 fileSize
= fileSize
+ 2;
262 // 2. set file size to header struct
264 ffsHeader
.ffsFileSize
[0] = (byte)(fileSize
& 0x00FF);
265 ffsHeader
.ffsFileSize
[1] = (byte)((fileSize
& 0x00FF00)>>8);
266 ffsHeader
.ffsFileSize
[2] = (byte)(((int)fileSize
& 0xFF0000)>>16);
269 // Fill in checksums and state, these must be zero for checksumming
271 ffsHeader
.integrityCheck
.header
= calculateChecksum8 (
272 ffsHeader
.structToBuffer(),
276 if ((this.attributes
& FFS_ATTRIB_CHECKSUM
) != 0) {
277 if ((this.attributes
& FFS_ATTRIB_TAIL_PRESENT
) != 0) {
278 ffsHeader
.integrityCheck
.file
= calculateChecksum8 (
283 ffsHeader
.integrityCheck
.file
= calculateChecksum8 (
289 ffsHeader
.integrityCheck
.file
= FFS_FIXED_CHECKSUM
;
293 // Set the state now. Spec says the checksum assumes the state is 0.
295 ffsHeader
.ffsState
= EFI_FILE_HEADER_CONSTRUCTION
|
296 EFI_FILE_HEADER_VALID
|
301 // create output stream to first write header data in file, then write sect data in file.
303 FileOutputStream headerFfs
= new FileOutputStream (ffsFile
.getAbsolutePath());
304 DataOutputStream ffsBuffer
= new DataOutputStream (headerFfs
);
307 // Add header struct and file data to FFS file
309 ffsBuffer
.write(ffsHeader
.structToBuffer());
310 for (int i
= 0; i
< fileDataSize
; i
++) {
311 ffsBuffer
.write(fileBuffer
[i
]);
315 // If there is a tail, then set it
317 if ((this.attributes
& FFS_ATTRIB_TAIL_PRESENT
) != 0) {
319 byte [] tailByte
= new byte[2];
322 // reverse tailvalue , integritycheck.file as hight byte, and
323 // integritycheck.header as low byte.
325 tailValue
= (short)(ffsHeader
.integrityCheck
.header
& 0xff);
326 tailValue
= (short)((tailValue
) | ((ffsHeader
.integrityCheck
.file
<< 8) & 0xff00));
327 tailValue
= (short)~tailValue
;
330 // Change short to byte[2]
332 tailByte
[0] = (byte)(tailValue
& 0xff);
333 tailByte
[1] = (byte)((tailValue
& 0xff00)>>8);
334 ffsBuffer
.write(tailByte
[0]);
335 ffsBuffer
.write(tailByte
[1]);
339 // close output stream. Note if don't close output stream
340 // the buffer can't be rewritten to file.
343 System
.out
.print ("Successful create ffs file!\n");
344 } catch (Exception e
) {
345 throw new BuildException (e
.getMessage());
352 This function is to add compress section to section list.
353 @param compress Section of compress
355 public void addCompress(CompressSection compress
) {
356 this.sectionList
.add(compress
);
362 This function is to add tool section to section list.
363 @param tool Section of tool
365 public void addTool(Tool tool
) {
366 this.sectionList
.add(tool
);
372 This function is to add sectFile section to section list.
373 @param sectFile Section of sectFile.
375 public void addSectFile (SectFile sectFile
) {
376 this.sectionList
.add(sectFile
);
382 This function is to get basename
384 @return String of base name
386 public String
getBaseName() {
387 return this.baseName
;
393 This function is to set base name.
396 public void setBaseName(String baseName
) {
397 this.baseName
= baseName
.trim();
403 This function is to get the ffsAligment
404 @return The value of ffsAligment.
406 public int getFfsAligment() {
407 return this.ffsAlignment
;
413 This function is to set ffsAligment
414 @param ffsAligment The value of ffsAligment.
416 public void setFfsAligment(int ffsAligment
) {
417 this.ffsAlignment
= ffsAligment
;
418 if (this.ffsAlignment
> 7) {
419 throw new BuildException ("FFS_ALIGMENT Scope is 0-7");
421 attributes
|= (((byte)this.ffsAlignment
) << 3);
428 This function is to get ffsAttribCheckSum
430 @return Value of ffsAttribChecksum
432 public boolean getFfsAttribChecksum() {
433 return this.FfsAttribChecksum
;
439 This function is to set ffsAttribChecksum
440 @param ffsAttributeCheckSum Value of ffsAttribCheckSum
442 public void setFfsAttribChecksum(boolean ffsAttributeCheckSum
) {
443 this.FfsAttribChecksum
= ffsAttributeCheckSum
;
444 if (ffsAttributeCheckSum
) {
445 attributes
|= FFS_ATTRIB_CHECKSUM
;
452 This function is to get ffsAttribRecovery
453 @return Value of ffsAttribRecovery
455 public boolean getFfsAttribRecovery() {
456 return this.ffsAttribRecovery
;
462 This function is to set ffsAttributeRecovery
464 @param ffsAttributeRecovery Value of ffsAttributeRecovery
466 public void setRecovery(boolean ffsAttributeRecovery
) {
467 this.ffsAttribRecovery
= ffsAttributeRecovery
;
468 if (ffsAttributeRecovery
) {
469 attributes
|= FFS_ATTRIB_RECOVERY
;
476 This function is to get fileGuid
479 public String
getFileGuid() {
480 return this.ffsFileGuid
;
486 This function is to set fileGuid
487 @param ffsFileGuid String of GUID
489 public void setFileGuid(String ffsFileGuid
) {
490 this.ffsFileGuid
= ffsFileGuid
.trim();
496 This function is to get ffsFileType.
498 @return value of ffsFileType
500 public String
getFfsFileType() {
501 return this.ffsFileType
;
507 This function is to set ffsFileType.
511 public void setFfsFileType(String ffsFileType
) {
512 this.ffsFileType
= ffsFileType
.trim();
516 ffsAttribHeaderExtension
518 This function is to get ffsAttribHeaderExtension
520 @return Value of ffsAttribHeaderExtension
522 public boolean isFfsAttribHeaderExtension() {
523 return this.ffsAttribHeaderExtension
;
529 This function is to set headerExtension
530 @param headerExtension Value of headerExension
532 public void setHeaderExtension(boolean headerExtension
) {
533 this.ffsAttribHeaderExtension
= headerExtension
;
534 if (headerExtension
) {
535 attributes
|= FFS_ATTRIB_HEADER_EXTENSION
;
540 isFfsAttribTailPresent
542 This function is to get ffsAttribTailPresent value.
543 @return Value of ffsAttribTailPresent.
545 public boolean isFfsAttribTailPresent() {
546 return this.ffsAttribTailPresent
;
550 setFfsAttribTailPresent
552 This function is to set ffsAttribTailPresent.
553 @param tailPresent Value of ffsAttribTailPresent.
555 public void setFfsAttribTailPresent(boolean tailPresent
) {
556 this.ffsAttribTailPresent
= tailPresent
;
558 attributes
|= FFS_ATTRIB_TAIL_PRESENT
;
566 This function is to convert string to GUID.
567 * @param GuidStr String of GUID.
568 * @param Guid GUID form.
570 private void stringToGuid (String GuidStr
, FfsHeader
.FfsGuid Guid
){
578 byte[] buffer
= new byte[16];
579 if (GuidStr
.length()!=36) {
580 throw new BuildException ("Guid length is not correct!");
584 SplitStr
= GuidStr
.split("-");
585 if (SplitStr
.length
!= 5) {
586 throw new BuildException ("Guid type is not correct!");
591 for (i
= 0; i
< SplitStr
.length
; i
++) {
592 String str
= SplitStr
[i
];
593 charArry
= str
.toCharArray();
595 for (j
=0; j
< (str
.toCharArray().length
)/2; j
++) {
597 buffer
[k
] = hexCharToByte (charArry
[j
*2]);
598 buffer
[k
] = (byte)( buffer
[k
]& 0x0f);
599 buffer
[k
] = (byte)((buffer
[k
]<< 4));
600 buffer
[k
] = (byte)( buffer
[k
]& 0xf0);
601 buffer
[k
] = (byte)( buffer
[k
]|hexCharToByte(charArry
[j
*2+1]));
605 Guid
.bufferToStruct(buffer
);
611 This function is to get suffix of ffs file according to ffsFileType.
613 @param ffsFileType ffsFileType
614 @return The suffix of ffs file
616 private String
TypeToSuffix (String ffsFileType
){
617 if (ffsFileType
.equals("EFI_FV_FILETYPE_ALL")) {
620 if (ffsFileType
.equals("EFI_FV_FILETYPE_RAW")) {
621 return EFI_FV_FFS_FILETYPE_STR
;
623 if (ffsFileType
.equals("EFI_FV_FILETYPE_FREEFORM")) {
624 return EFI_FV_FFS_FILETYPE_STR
;
626 if (ffsFileType
.equals("EFI_FV_FILETYPE_SECURITY_CORE")) {
627 return EFI_FV_SEC_FILETYPE_STR
;
629 if (ffsFileType
.equals("EFI_FV_FILETYPE_PEI_CORE")) {
630 return EFI_FV_PEI_FILETYPE_STR
;
632 if (ffsFileType
.equals("EFI_FV_FILETYPE_DXE_CORE")) {
633 return EFI_FV_DXE_FILETYPE_STR
;
635 if (ffsFileType
.equals("EFI_FV_FILETYPE_PEIM")) {
636 return EFI_FV_PEI_FILETYPE_STR
;
638 if (ffsFileType
.equals("EFI_FV_FILETYPE_DRIVER")) {
639 return EFI_FV_DXE_FILETYPE_STR
;
641 if (ffsFileType
.equals("EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER")) {
642 return EFI_FV_PEI_FILETYPE_STR
;
644 if (ffsFileType
.equals("EFI_FV_FILETYPE_APPLICATION")) {
645 return EFI_FV_APP_FILETYPE_STR
;
647 if (ffsFileType
.equals("EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE")) {
648 return EFI_FV_FVI_FILETYPE_STR
;
650 if (ffsFileType
.equals("EFI_FV_FILETYPE_FFS_PAD")) {
651 return EFI_FV_FFS_FILETYPE_STR
;
660 This function is to get ffsFileType integer value according to ffsFileType.
661 @param ffsFileType String value of ffsFileType
662 @return Integer value of ffsFileType.
664 private byte stringToType (String ffsFileType
){
666 if (ffsFileType
.equals("EFI_FV_FILETYPE_ALL")) {
667 return(byte)EFI_FV_FILETYPE_ALL
;
670 if (ffsFileType
.equals("EFI_FV_FILETYPE_RAW")) {
671 return(byte)EFI_FV_FILETYPE_RAW
;
674 if (ffsFileType
.equals("EFI_FV_FILETYPE_FREEFORM")) {
675 return(byte)EFI_FV_FILETYPE_SECURITY_CORE
;
678 if (ffsFileType
.equals("EFI_FV_FILETYPE_SECURITY_CORE")) {
679 return(byte)EFI_FV_FILETYPE_SECURITY_CORE
;
682 if (ffsFileType
.equals("EFI_FV_FILETYPE_PEI_CORE")) {
683 return(byte) EFI_FV_FILETYPE_PEI_CORE
;
686 if (ffsFileType
.equals("EFI_FV_FILETYPE_DXE_CORE")) {
687 return(byte)EFI_FV_FILETYPE_DXE_CORE
;
690 if (ffsFileType
.equals("EFI_FV_FILETYPE_PEIM")) {
691 return(byte)EFI_FV_FILETYPE_PEIM
;
694 if (ffsFileType
.equals("EFI_FV_FILETYPE_DRIVER")) {
695 return(byte) EFI_FV_FILETYPE_DRIVER
;
698 if (ffsFileType
.equals("EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER")) {
699 return(byte)EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER
;
702 if (ffsFileType
.equals("EFI_FV_FILETYPE_APPLICATION")) {
703 return(byte)EFI_FV_FILETYPE_APPLICATION
;
706 if (ffsFileType
.equals("EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE")) {
707 return(byte)EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
;
709 if (ffsFileType
.equals("EFI_FV_FILETYPE_FFS_PAD")) {
710 return(byte) EFI_FV_FILETYPE_FFS_PAD
;
721 This function is to calculate the value needed for a valid UINT8 checksum
722 @param buffer Byte buffer containing byte data of component.
723 @param size Size of the buffer.
724 @return The 8 bit checksum value needed.
726 private byte calculateChecksum8 (byte[] buffer
, int size
){
727 return(byte) (0x100 - calculateSum8 (buffer
, size
));
734 This function is to calculate the UINT8 sum for the requested region.
735 @param buffer Byte buffer containing byte data of component
736 @param size Size of the buffer.
737 @return The 8 bit checksum value needed.
739 private short calculateSum8 (byte[] buffer
, int size
){
745 // Perform the word sum for buffer
747 for (Index
= 0; Index
< size
; Index
++) {
748 Sum
= (byte) (Sum
+ buffer
[Index
]);
757 This function is to convert hex character to byte
759 @param hexChar hex character
760 @return Byte which corresponding to the character.
762 private byte hexCharToByte (char hexChar
){
813 This function is used to adjusts file size to insure sectioned file is exactly the right length such
814 that it ends on exactly the last byte of the last section. ProcessScript()
815 may have padded beyond the end of the last section out to a 4 byte boundary.
816 This padding is stripped.
818 @param buffer Byte buffer contains a section stream
819 @return Corrected size of file.
821 private int adjustFileSize (byte[] buffer
){
823 int orignalLen
= buffer
.length
;
825 int sectionPoint
= 0;
826 int nextSectionPoint
= 0;
829 int firstSectionHeader
= 0;
832 firstSectionHeader
= buffer
[0]& 0xff;
833 firstSectionHeader
= ((buffer
[1]&0xff)<<8) | firstSectionHeader
;
834 firstSectionHeader
= ((buffer
[2]&0xff)<<16)| firstSectionHeader
;
837 while (sectionPoint
< buffer
.length
) {
838 sectionLen
= buffer
[0 + sectionPoint
]& 0xff;
839 sectionLen
= ((buffer
[1 + sectionPoint
]&0xff)<<8)| sectionLen
;
840 sectionLen
= ((buffer
[2 + sectionPoint
]&0xff)<<16)| sectionLen
;
841 totalLen
= totalLen
+ sectionLen
;
843 if (totalLen
== orignalLen
) {
847 sectionPoint
= sectionPoint
+ sectionLen
;
848 adjustLen
= sectionPoint
;
850 nextSectionPoint
= (sectionPoint
+ 0x03) & (~
0x03);
851 totalLen
= totalLen
+ nextSectionPoint
- sectionLen
;
852 sectionPoint
= nextSectionPoint
;
860 This function is to get output directory.
862 @return Path of output directory.
864 public String
getOutputDir() {
871 This function is to set output directory.
873 @param outputDir The output direcotry.
875 public void setOutputDir(String outputDir
) {
876 this.outputDir
= outputDir
;