]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/GenFfsFileTask.java
cbe20f02960aa12b715422bc26ba9c33e0be7a04
[mirror_edk2.git] / Tools / Source / FrameworkTasks / org / tianocore / framework / tasks / GenFfsFileTask.java
1 /** @file
2 GenFfsFileTask class.
3
4 GenFfsFileTaks is to generate ffs file.
5
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
11
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.
14
15 **/
16 package org.tianocore.framework.tasks;
17
18 import java.io.DataInputStream;
19 import java.io.DataOutputStream;
20 import java.io.File;
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;
26
27 import org.apache.tools.ant.BuildException;
28 import org.apache.tools.ant.Project;
29 import org.apache.tools.ant.Task;
30 import org.tianocore.common.logger.EdkLog;
31
32 /**
33 GenFfsFileTask
34
35 GenFfsFileTaks is to generate ffs file.
36
37 **/
38 public class GenFfsFileTask extends Task implements EfiDefine, FfsTypes {
39 /**
40 * GenFfsFile Task Class
41 * class member
42 * -baseName : module baseName
43 * -ffsFileGuid : module Guid.
44 * -ffsFileType : Ffs file type.
45 * -ffsAttributeRecovery : The file is required for recovery.
46 * -ffsAligment : The file data alignment (0 if none required). See FFS
47 * specification for supported alignments (0-7 are only possible
48 * values). *
49 * -ffsAttributeCheckSum : The file data is checksummed. If this is FALSE a
50 * value of 0x5A will be inserted in the file
51 * checksum field of the file header. *
52 * -sectFileDir : specifies the full path to the component build directory.
53 * Required.
54 * -ffsAttrib : Data recorde attribute added result.
55 * -sectionList : List recorded all section elemet in task.
56 */
57 ///
58 /// module baseName
59 ///
60 String baseName = "";
61 ///
62 ///
63 ///
64 String moduleType;
65 ///
66 /// module Guid
67 ///
68 String ffsFileGuid = "";
69 ///
70 /// Ffs file type
71 ///
72 String ffsFileType = "";
73 ///
74 /// ffsAttribHeaderExtension value is used to set the corresponding bit in
75 /// the output FFS file header
76 ///
77 boolean ffsAttribHeaderExtension = false;
78 ///
79 /// ffsAttribTailPresent value is used to set the corresponding bit in the
80 /// output FFS file header
81 ///
82 boolean ffsAttribTailPresent = false;
83 ///
84 /// ffsAttribRecovery value is used to set the corresponding bit in the
85 /// output FFS file header
86 ///
87 boolean ffsAttribRecovery = false;
88 ///
89 /// ffsAttribDataAlignment value is used to set the corresponding bit in the output
90 /// FFS file header.The specified FFS alignment must be a value between 0
91 /// and 7 inclusive
92 ///
93 int ffsAttribDataAlignment = 0;
94 ///
95 /// ffsAttribChecksum value is used to set the corresponding bit in the
96 /// output FFS file header
97 ///
98 boolean FfsAttribChecksum = false;
99 ///
100 /// Attribute is used to record the sum of all bit in the output FFS file.
101 ///
102 byte attributes = 0;
103 ///
104 /// The output directory of ffs file.
105 ///
106 String outputDir = "";
107 ///
108 /// List of section.
109 ///
110 List<Object> sectionList = new ArrayList<Object>();
111
112 ///
113 /// The path of Framewor_Tools_Paht.
114 ///
115 static String path = "";
116
117 ///
118 /// Gensection
119 ///
120 List<GenSectionTask> genSectList = new ArrayList<GenSectionTask>();
121
122 /**
123 execute
124
125 GenFfsFileTask execute is to generate ffs file according to input section
126 dscriptive information.
127 **/
128 public void execute() throws BuildException {
129
130 String ffsSuffix = "";
131 String outputPath = "";
132
133 //
134 // Get Fraemwork_Tools_Path
135 //
136 Project pj = this.getOwningTarget().getProject();
137 path = pj.getProperty("env.FRAMEWORK_TOOLS_PATH");
138
139 //
140 // Check does the BaseName, Guid, FileType set value.
141 //
142 if (this.baseName.equals("")) {
143 throw new BuildException ("Must set OutputFileBasename!\n");
144 }
145
146 if (this.ffsFileGuid.equals("")) {
147 throw new BuildException ("Must set ffsFileGuid!\n");
148 }
149
150 if (this.ffsFileType.equals("")) {
151 throw new BuildException ("Must set ffsFileType!\n");
152 }
153
154 //
155 // Create ffs file. File name = FfsFileGuid + BaseName + ffsSuffix.
156 // If outputDir's value was set, file will output to the outputDir.
157 //
158 ffsSuffix = TypeToSuffix (this.moduleType);
159 if (!this.outputDir.equals("")) {
160 String temp;
161 outputPath = this.outputDir;
162 temp = outputPath.replace('\\', File.separatorChar);
163 outputPath = temp.replace('/', File.separatorChar);
164 if (outputPath.charAt(outputPath.length()-1) != File.separatorChar) {
165 outputPath = outputPath + File.separator;
166 }
167
168 }
169
170 String ffsFilePath = outputPath + this.ffsFileGuid + '-' + this.baseName + ffsSuffix;
171 File ffsFile = new File (ffsFilePath);
172 genFfs(ffsFile);
173 }
174
175 /**
176 addCompress
177
178 This function is to add compress section to section list.
179 @param compress Section of compress
180 **/
181 public void addCompress(CompressSection compress) {
182 this.sectionList.add(compress);
183 }
184
185 /**
186 addTool
187
188 This function is to add tool section to section list.
189 @param tool Section of tool
190 **/
191 public void addTool(Tool tool) {
192 this.sectionList.add(tool);
193 }
194
195 /**
196 addSectionFile
197
198 This function is to add sectFile section to section list.
199 @param sectFile Section of sectFile.
200 **/
201 public void addSectFile (SectFile sectFile) {
202 this.sectionList.add(sectFile);
203 }
204
205 /**
206 getBaseName
207
208 This function is to get basename
209
210 @return String of base name
211 **/
212 public String getBaseName() {
213 return this.baseName;
214 }
215
216 /**
217 setBaseName
218
219 This function is to set base name.
220 @param baseName
221 **/
222 public void setBaseName(String baseName) {
223 this.baseName = baseName.trim();
224 }
225
226 /**
227 getFfsAligment
228
229 This function is to get the ffsAligment
230 @return The value of ffsAligment.
231 **/
232 public int getFfsAttribDataAlignment() {
233 return this.ffsAttribDataAlignment;
234 }
235
236 /**
237 setFfsAligment
238
239 This function is to set ffsAligment
240 @param ffsAligment The value of ffsAligment.
241 **/
242 public void setFfsAttribDataAlignment(String ffsAligment) {
243 this.ffsAttribDataAlignment = stringToInt(ffsAligment.replaceAll(" ", "").toLowerCase());
244 if (this.ffsAttribDataAlignment < 0 || this.ffsAttribDataAlignment > 7) {
245 throw new BuildException ("FFS_ATTRIB_DATA_ALIGMENT must be an integer value from 0 through 7, inclusive");
246 } else {
247 attributes |= (((byte)this.ffsAttribDataAlignment) << 3);
248 }
249 }
250
251 /**
252 getFfsAttribCheckSum
253
254 This function is to get ffsAttribCheckSum
255
256 @return Value of ffsAttribChecksum
257 **/
258 public boolean getFfsAttribChecksum() {
259 return this.FfsAttribChecksum;
260 }
261
262 /**
263 setFfsAttribChecksum
264
265 This function is to set ffsAttribChecksum
266 @param ffsAttributeCheckSum Value of ffsAttribCheckSum
267 **/
268 public void setFfsAttribChecksum(boolean ffsAttributeCheckSum) {
269 this.FfsAttribChecksum = ffsAttributeCheckSum;
270 if (ffsAttributeCheckSum) {
271 attributes |= FFS_ATTRIB_CHECKSUM;
272 }
273 }
274
275 /**
276 getFfsAttribRecovery
277
278 This function is to get ffsAttribRecovery
279 @return Value of ffsAttribRecovery
280 **/
281 public boolean getFfsAttribRecovery() {
282 return this.ffsAttribRecovery;
283 }
284
285 /**
286 setRecovery
287
288 This function is to set ffsAttributeRecovery
289
290 @param ffsAttributeRecovery Value of ffsAttributeRecovery
291 **/
292 public void setRecovery(boolean ffsAttributeRecovery) {
293 this.ffsAttribRecovery = ffsAttributeRecovery;
294 if (ffsAttributeRecovery) {
295 attributes |= FFS_ATTRIB_RECOVERY;
296 }
297 }
298
299 /**
300 getFileGuid
301
302 This function is to get fileGuid
303 @return Guid
304 **/
305 public String getFileGuid() {
306 return this.ffsFileGuid;
307 }
308
309 /**
310 setFileGuid
311
312 This function is to set fileGuid
313 @param ffsFileGuid String of GUID
314 **/
315 public void setFileGuid(String ffsFileGuid) {
316 this.ffsFileGuid = ffsFileGuid.trim();
317 }
318
319 /**
320 getFfsFileType
321
322 This function is to get ffsFileType.
323
324 @return value of ffsFileType
325 **/
326 public String getFfsFileType() {
327 return this.ffsFileType;
328 }
329
330 /**
331 setFfsFileType
332
333 This function is to set ffsFileType.
334
335 @param ffsFileType
336 **/
337 public void setFfsFileType(String ffsFileType) {
338 this.ffsFileType = ffsFileType.trim();
339 }
340
341 /**
342 ffsAttribHeaderExtension
343
344 This function is to get ffsAttribHeaderExtension
345
346 @return Value of ffsAttribHeaderExtension
347 **/
348 public boolean isFfsAttribHeaderExtension() {
349 return this.ffsAttribHeaderExtension;
350 }
351
352 /**
353 setHeaderExension
354
355 This function is to set headerExtension
356 @param headerExtension Value of headerExension
357 **/
358 public void setHeaderExtension(boolean headerExtension) {
359 this.ffsAttribHeaderExtension = headerExtension;
360 if (headerExtension) {
361 attributes |= FFS_ATTRIB_HEADER_EXTENSION;
362 }
363 }
364
365 /**
366 isFfsAttribTailPresent
367
368 This function is to get ffsAttribTailPresent value.
369 @return Value of ffsAttribTailPresent.
370 **/
371 public boolean isFfsAttribTailPresent() {
372 return this.ffsAttribTailPresent;
373 }
374
375 /**
376 setFfsAttribTailPresent
377
378 This function is to set ffsAttribTailPresent.
379 @param tailPresent Value of ffsAttribTailPresent.
380 **/
381 public void setFfsAttribTailPresent(boolean tailPresent) {
382 this.ffsAttribTailPresent = tailPresent;
383 if (tailPresent) {
384 attributes |= FFS_ATTRIB_TAIL_PRESENT;
385 }
386 }
387
388
389 /**
390 stringToGuid
391
392 This function is to convert string to GUID.
393 * @param GuidStr String of GUID.
394 * @param Guid GUID form.
395 */
396 private void stringToGuid (String GuidStr, FfsHeader.FfsGuid Guid){
397
398 int i = 0;
399 int j = 0;
400 int k = 0;
401 char [] charArry;
402 String [] SplitStr;
403
404 byte[] buffer = new byte[16];
405 if (GuidStr.length()!=36) {
406 throw new BuildException ("The GUID length [" + GuidStr.length() + "] is not correct!");
407 }
408
409
410 SplitStr = GuidStr.split("-");
411 if (SplitStr.length != 5) {
412 throw new BuildException ("The GUID format is not correct!");
413 }
414
415
416
417 for (i= 0; i < SplitStr.length; i++) {
418 String str = SplitStr[i];
419 charArry = str.toCharArray();
420
421 for (j =0; j < (str.toCharArray().length)/2; j++) {
422
423 buffer[k] = hexCharToByte (charArry[j*2]);
424 buffer[k] = (byte)( buffer[k]& 0x0f);
425 buffer[k] = (byte)((buffer[k]<< 4));
426 buffer[k] = (byte)( buffer[k]& 0xf0);
427 buffer[k] = (byte)( buffer[k]|hexCharToByte(charArry[j*2+1]));
428 k++;
429 }
430 }
431 Guid.bufferToStruct(buffer);
432 }
433
434 /**
435 typeToSuffix
436
437 This function is to get suffix of ffs file according to ffsFileType.
438
439 @param ffsFileType ffsFileType
440 @return The suffix of ffs file
441 **/
442 private String TypeToSuffix (String ffsFileType){
443 String[][] suffix = { { "BASE", ".FFS"},
444 { "SEC", ".SEC" }, { "PEI_CORE", ".PEI" },
445 { "PEIM", ".PEI" }, { "DXE_CORE", ".DXE" },
446 { "DXE_DRIVER", ".DXE" }, { "DXE_RUNTIME_DRIVER", ".DXE" },
447 { "DXE_SAL_DRIVER", ".DXE" }, { "DXE_SMM_DRIVER", ".DXE" },
448 { "TOOL", ".FFS" }, { "UEFI_DRIVER", ".DXE" },
449 { "UEFI_APPLICATION", ".APP" }, { "USER_DEFINED", ".FFS" } };
450
451 for (int i = 0; i < suffix.length; i++) {
452 if (suffix[i][0].equalsIgnoreCase(moduleType)) {
453 return suffix[i][1];
454 }
455 }
456
457 return ".FFS";
458 }
459
460
461 /**
462 stringToType
463
464 This function is to get ffsFileType integer value according to ffsFileType.
465 @param ffsFileType String value of ffsFileType
466 @return Integer value of ffsFileType.
467 **/
468 private byte stringToType (String ffsFileType){
469
470 if (ffsFileType.equals("EFI_FV_FILETYPE_ALL")) {
471 return(byte)EFI_FV_FILETYPE_ALL;
472 }
473
474 if (ffsFileType.equals("EFI_FV_FILETYPE_RAW")) {
475 return(byte)EFI_FV_FILETYPE_RAW;
476 }
477
478 if (ffsFileType.equals("EFI_FV_FILETYPE_FREEFORM")) {
479 return(byte)EFI_FV_FILETYPE_FREEFORM;
480 }
481
482 if (ffsFileType.equals("EFI_FV_FILETYPE_SECURITY_CORE")) {
483 return(byte)EFI_FV_FILETYPE_SECURITY_CORE;
484 }
485
486 if (ffsFileType.equals("EFI_FV_FILETYPE_PEI_CORE")) {
487 return(byte) EFI_FV_FILETYPE_PEI_CORE;
488 }
489
490 if (ffsFileType.equals("EFI_FV_FILETYPE_DXE_CORE")) {
491 return(byte)EFI_FV_FILETYPE_DXE_CORE;
492 }
493
494 if (ffsFileType.equals("EFI_FV_FILETYPE_PEIM")) {
495 return(byte)EFI_FV_FILETYPE_PEIM;
496 }
497
498 if (ffsFileType.equals("EFI_FV_FILETYPE_DRIVER")) {
499 return(byte) EFI_FV_FILETYPE_DRIVER;
500 }
501
502 if (ffsFileType.equals("EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER")) {
503 return(byte)EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER;
504 }
505
506 if (ffsFileType.equals("EFI_FV_FILETYPE_APPLICATION")) {
507 return(byte)EFI_FV_FILETYPE_APPLICATION;
508 }
509
510 if (ffsFileType.equals("EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE")) {
511 return(byte)EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE;
512 }
513 if (ffsFileType.equals("EFI_FV_FILETYPE_FFS_PAD")) {
514 return(byte) EFI_FV_FILETYPE_FFS_PAD;
515 }
516
517 return -1;
518 }
519
520
521
522 /**
523 calculateCheckSum8
524
525 This function is to calculate the value needed for a valid UINT8 checksum
526 @param buffer Byte buffer containing byte data of component.
527 @param size Size of the buffer.
528 @return The 8 bit checksum value needed.
529 **/
530 private byte calculateChecksum8 (byte[] buffer, int size){
531 return(byte) (0x100 - calculateSum8 (buffer, size));
532 }
533
534
535 /**
536 calculateSum8
537
538 This function is to calculate the UINT8 sum for the requested region.
539 @param buffer Byte buffer containing byte data of component
540 @param size Size of the buffer.
541 @return The 8 bit checksum value needed.
542 **/
543 private short calculateSum8 (byte[] buffer, int size){
544 int Index;
545 byte Sum;
546 Sum = 0;
547
548 //
549 // Perform the word sum for buffer
550 //
551 for (Index = 0; Index < size; Index++) {
552 Sum = (byte) (Sum + buffer[Index]);
553 }
554
555 return(byte) Sum;
556 }
557
558 /**
559 hexCharToByte
560
561 This function is to convert hex character to byte
562
563 @param hexChar hex character
564 @return Byte which corresponding to the character.
565 **/
566 private byte hexCharToByte (char hexChar){
567 switch (hexChar) {
568 case '0':
569 return(byte)0x00;
570 case '1':
571 return(byte)0x01;
572 case '2':
573 return(byte)0x02;
574 case '3':
575 return(byte)0x03;
576 case '4':
577 return(byte)0x04;
578 case '5':
579 return(byte)0x05;
580 case '6':
581 return(byte)0x06;
582 case '7':
583 return(byte)0x07;
584 case '8':
585 return(byte)0x08;
586 case '9':
587 return(byte)0x09;
588 case 'a':
589 case 'A':
590 return(byte)0x0a;
591 case 'b':
592 case 'B':
593 return(byte)0x0b;
594 case 'c':
595 case 'C':
596 return(byte)0x0c;
597
598 case 'd':
599 case 'D':
600 return(byte)0x0d;
601
602 case 'e':
603 case 'E':
604 return(byte)0x0e;
605 case 'f':
606 case 'F':
607 return(byte)0x0f;
608
609 default:
610 return(byte)0xff;
611 }
612 }
613
614 /**
615 adjustFileSize
616
617 This function is used to adjusts file size to insure sectioned file is exactly the right length such
618 that it ends on exactly the last byte of the last section. ProcessScript()
619 may have padded beyond the end of the last section out to a 4 byte boundary.
620 This padding is stripped.
621
622 @param buffer Byte buffer contains a section stream
623 @return Corrected size of file.
624 **/
625 private int adjustFileSize (byte[] buffer){
626
627 int orignalLen = buffer.length;
628 int adjustLen = 0;
629 int sectionPoint = 0;
630 int nextSectionPoint = 0;
631 int sectionLen = 0;
632 int totalLen = 0;
633 int firstSectionHeader = 0;
634
635
636 firstSectionHeader = buffer[0]& 0xff;
637 firstSectionHeader = ((buffer[1]&0xff)<<8) | firstSectionHeader;
638 firstSectionHeader = ((buffer[2]&0xff)<<16)| firstSectionHeader;
639
640
641 while (sectionPoint < buffer.length) {
642 sectionLen = buffer[0 + sectionPoint]& 0xff;
643 sectionLen = ((buffer[1 + sectionPoint]&0xff)<<8)| sectionLen;
644 sectionLen = ((buffer[2 + sectionPoint]&0xff)<<16)| sectionLen;
645 totalLen = totalLen + sectionLen;
646
647 if (totalLen == orignalLen) {
648 return totalLen;
649 }
650
651 sectionPoint = sectionPoint + sectionLen;
652 adjustLen = sectionPoint;
653
654 nextSectionPoint = (sectionPoint + 0x03) & (~0x03);
655 totalLen = totalLen + nextSectionPoint - sectionLen;
656 sectionPoint = nextSectionPoint;
657 }
658 return adjustLen;
659 }
660
661 /**
662 getOutputDir
663
664 This function is to get output directory.
665
666 @return Path of output directory.
667 **/
668 public String getOutputDir() {
669 return outputDir;
670 }
671
672 /**
673 setOutputDir
674
675 This function is to set output directory.
676
677 @param outputDir The output direcotry.
678 **/
679 public void setOutputDir(String outputDir) {
680 this.outputDir = outputDir;
681 }
682
683 /**
684 getModuleTyp
685
686 This function is to get string of module type.
687
688 @return moduleType The string of module type.
689 **/
690 public String getModuleType() {
691 return this.moduleType;
692 }
693
694 /**
695 setModuleType
696
697 This function is to set moduleType.
698
699 @param moduleType The string of module type.
700 **/
701 public void setModuleType(String moduleType) {
702 this.moduleType = moduleType;
703 }
704
705 /**
706 Convert a string to a integer.
707
708 @param intString The string representing a integer
709
710 @retval int The value of integer represented by the
711 given string; -1 is returned if the format
712 of the string is wrong.
713 **/
714 private int stringToInt(String intString) {
715 int value;
716 int hexPrefixPos = intString.indexOf("0x");
717 int radix = 10;
718 String intStringNoPrefix;
719
720 if (hexPrefixPos >= 0) {
721 radix = 16;
722 intStringNoPrefix = intString.substring(hexPrefixPos + 2, intString.length());
723 } else {
724 intStringNoPrefix = intString;
725 }
726
727 try {
728 value = Integer.parseInt(intStringNoPrefix, radix);
729 } catch (NumberFormatException e) {
730 log("Incorrect format of int [" + intString + "]. -1 is assumed");
731 return -1;
732 }
733
734 return value;
735 }
736
737 /**
738 genFfs
739
740 This function is to generate FFS file.
741
742 @param ffsFile Name of FFS file.
743 @param isOrg Flag to indicate generate ORG ffs file or not.
744 **/
745 private void genFfs(File ffsFile) {
746 Section sect;
747 int fileSize;
748 int fileDataSize;
749 FfsHeader ffsHeader = new FfsHeader();
750 FfsHeader orgFfsHeader = new FfsHeader();
751
752 EdkLog.log(this, EdkLog.EDK_INFO, ffsFile.getName());
753
754 try {
755 //
756 // Create file output stream -- dataBuffer.
757 //
758 FileOutputStream dataFs = new FileOutputStream (ffsFile.getAbsolutePath());
759 DataOutputStream dataBuffer = new DataOutputStream (dataFs);
760
761 //
762 // Search SectionList find earch section and call it's
763 // ToBuffer function.
764 //
765 Iterator sectionIter = this.sectionList.iterator();
766 while (sectionIter.hasNext()) {
767 sect = (Section)sectionIter.next();
768
769 try {
770 //
771 // The last section don't need 4 byte ffsAligment.
772 //
773 sect.toBuffer((DataOutputStream)dataBuffer);
774 } catch (Exception e) {
775 throw new BuildException (e.getMessage());
776 }
777 }
778 dataBuffer.close();
779 } catch (Exception e) {
780 throw new BuildException (e.getMessage());
781 }
782
783 //
784 // Creat Ffs file header
785 //
786 try {
787
788 //
789 // create input stream to read file data
790 //
791 byte[] fileBuffer = new byte[(int)ffsFile.length()];
792 FileInputStream fi = new FileInputStream (ffsFile.getAbsolutePath());
793 DataInputStream di = new DataInputStream (fi);
794 di.read(fileBuffer);
795 di.close();
796
797 //
798 // Add GUID to header struct
799 //
800 if (this.ffsFileGuid != null) {
801 stringToGuid (this.ffsFileGuid, ffsHeader.name);
802 }
803
804 ffsHeader.ffsAttributes = this.attributes;
805 if ((ffsHeader.fileType = stringToType(this.ffsFileType))== -1) {
806 throw new BuildException ("FFS_FILE_TYPE unknow!\n");
807 }
808
809 //
810 // Copy ffsHeader.ffsAttribute and fileType to orgFfsHeader.ffsAttribute
811 // and fileType
812 //
813 orgFfsHeader.ffsAttributes = ffsHeader.ffsAttributes;
814 orgFfsHeader.fileType = ffsHeader.fileType;
815
816 //
817 // Adjust file size. The function is used to tripe the last
818 // section padding of 4 binary boundary.
819 //
820 //
821 if (ffsHeader.fileType != EFI_FV_FILETYPE_RAW) {
822
823 fileDataSize = adjustFileSize (fileBuffer);
824 } else {
825 fileDataSize = fileBuffer.length;
826 }
827
828 //
829 // 1. add header size to file size
830 //
831 fileSize = fileDataSize + ffsHeader.getSize();
832
833 if ((ffsHeader.ffsAttributes & FFS_ATTRIB_TAIL_PRESENT) != 0) {
834 if (ffsHeader.fileType == EFI_FV_FILETYPE_FFS_PAD) {
835
836 throw new BuildException (
837 "FFS_ATTRIB_TAIL_PRESENT=TRUE is " +
838 "invalid for PAD files"
839 );
840 }
841 if (fileSize == ffsHeader.getSize()) {
842 throw new BuildException (
843 "FFS_ATTRIB_TAIL_PRESENT=TRUE is " +
844 "invalid for 0-length files"
845 );
846 }
847 fileSize = fileSize + 2;
848 }
849
850 //
851 // 2. set file size to header struct
852 //
853 ffsHeader.ffsFileSize[0] = (byte)(fileSize & 0x00FF);
854 ffsHeader.ffsFileSize[1] = (byte)((fileSize & 0x00FF00)>>8);
855 ffsHeader.ffsFileSize[2] = (byte)(((int)fileSize & 0xFF0000)>>16);
856
857 //
858 // Fill in checksums and state, these must be zero for checksumming
859 //
860 ffsHeader.integrityCheck.header = calculateChecksum8 (
861 ffsHeader.structToBuffer(),
862 ffsHeader.getSize()
863 );
864
865 if ((this.attributes & FFS_ATTRIB_CHECKSUM) != 0) {
866 if ((this.attributes & FFS_ATTRIB_TAIL_PRESENT) != 0) {
867 ffsHeader.integrityCheck.file = calculateChecksum8 (
868 fileBuffer,
869 fileDataSize
870 );
871 } else {
872 ffsHeader.integrityCheck.file = calculateChecksum8 (
873 fileBuffer,
874 fileDataSize
875 );
876 }
877 } else {
878 ffsHeader.integrityCheck.file = FFS_FIXED_CHECKSUM;
879 orgFfsHeader.integrityCheck.file = FFS_FIXED_CHECKSUM;
880 }
881
882 //
883 // Set the state now. Spec says the checksum assumes the state is 0.
884 //
885 ffsHeader.ffsState = EFI_FILE_HEADER_CONSTRUCTION |
886 EFI_FILE_HEADER_VALID |
887 EFI_FILE_DATA_VALID;
888
889 //
890 // create output stream to first write header data in file, then write sect data in file.
891 //
892 FileOutputStream headerFfs = new FileOutputStream (ffsFile.getAbsolutePath());
893 DataOutputStream ffsBuffer = new DataOutputStream (headerFfs);
894
895 //
896 // Add header struct and file data to FFS file
897 //
898 ffsBuffer.write(ffsHeader.structToBuffer());
899 ffsBuffer.write(fileBuffer, 0, fileDataSize);
900
901
902
903 //
904 // If there is a tail, then set it
905 //
906 if ((this.attributes & FFS_ATTRIB_TAIL_PRESENT) != 0) {
907 short tailValue ;
908 byte [] tailByte = new byte[2];
909
910 //
911 // reverse tailvalue , integritycheck.file as hight byte, and
912 // integritycheck.header as low byte.
913 //
914 tailValue = (short)(ffsHeader.integrityCheck.header & 0xff);
915 tailValue = (short)((tailValue) | ((ffsHeader.integrityCheck.file << 8) & 0xff00));
916 tailValue = (short)~tailValue;
917
918 //
919 // Change short to byte[2]
920 //
921 tailByte[0] = (byte)(tailValue & 0xff);
922 tailByte[1] = (byte)((tailValue & 0xff00)>>8);
923 ffsBuffer.write(tailByte[0]);
924 ffsBuffer.write(tailByte[1]);
925
926 }
927
928 //
929 // close output stream. Note if don't close output stream
930 // the buffer can't be rewritten to file.
931 //
932 ffsBuffer.close();
933 } catch (Exception e) {
934 log("genffsfile failed!");
935 throw new BuildException (e.getMessage());
936 }
937
938 }
939
940 /**
941 addGenSection
942
943 This function is to add gensection instance to list
944
945 @param task Instance of GenSectionTask
946 **/
947 public void addGenSection (GenSectionTask task){
948 this.sectionList.add(task);
949 }
950 }