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