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