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