- Fixed EDKT240. Now the Blank.pad file for alignment purpose will no longer be needed.
[mirror_edk2.git] / Tools / Java / Source / FrameworkTasks / org / tianocore / framework / tasks / GenFfsFileTask.java
index 3fdeb8d..ebc26b9 100644 (file)
@@ -741,15 +741,53 @@ public class GenFfsFileTask extends Task implements EfiDefine, FfsTypes {
 \r
        return value;\r
    }\r
-    \r
-    /**\r
-      genFfs\r
-      \r
-      This function is to generate FFS file.\r
-      \r
-       @param ffsFile          Name of FFS file.\r
-       @param isOrg            Flag to indicate generate ORG ffs file or not.\r
-    **/\r
+\r
+   private void alignSection(DataOutputStream dataBuffer, int dataSize, int alignment) throws BuildException {\r
+       if (alignment == 0) {\r
+           return;\r
+       }\r
+       dataSize += 4; // take the section header into account\r
+       int[] alignedBytes = {0, 16, 128, 512, 1024, 4096, 32768, 65536};\r
+       int padSize = (alignedBytes[alignment] - dataSize) & (alignedBytes[alignment] - 1);\r
+       if (padSize == 0) {\r
+           //\r
+           // already aligned\r
+           // \r
+           return;\r
+       }\r
+       //\r
+       // if the pad size is not times of 4, there must be something wrong in previous sections\r
+       // \r
+       if (((4 - padSize) & (4 - 1)) != 0) {\r
+           EdkLog.log(this, EdkLog.EDK_ERROR, "PAD section size must be 4-byte aligned (" + padSize + ")!");\r
+           throw new BuildException ("Alignment can't be satisfied!");\r
+       }\r
+       byte[] pad = new byte[padSize];\r
+       //\r
+       // first three byte stores the section size\r
+       // \r
+       pad[0] = (byte)(padSize & 0xff);\r
+       pad[1] = (byte)((padSize >> 8) & 0xff);\r
+       pad[2] = (byte)((padSize >> 16) & 0xff);\r
+       //\r
+       // the fourth byte are section type. use raw type (0x19)\r
+       // \r
+       pad[3] = 0x19;\r
+       try {\r
+           dataBuffer.write(pad);\r
+       } catch (Exception e) {\r
+           throw new BuildException(e.getMessage());\r
+       }\r
+   }\r
+\r
+   /**\r
+     genFfs\r
+     \r
+     This function is to generate FFS file.\r
+     \r
+      @param ffsFile          Name of FFS file.\r
+      @param isOrg            Flag to indicate generate ORG ffs file or not.\r
+   **/\r
     private void genFfs(File ffsFile) throws BuildException {\r
         Section           sect;\r
         int               fileSize;\r
@@ -775,6 +813,11 @@ public class GenFfsFileTask extends Task implements EfiDefine, FfsTypes {
                 sect = (Section)sectionIter.next(); \r
 \r
                 try {\r
+                    int alignment = sect.getAlignment();\r
+                    if (this.ffsAttribDataAlignment < alignment) {\r
+                        this.ffsAttribDataAlignment = alignment;\r
+                    }\r
+                    alignSection(dataBuffer, dataBuffer.size(), alignment);\r
                     //\r
                     //  The last section don't need 4 byte ffsAligment.\r
                     //\r
@@ -812,6 +855,12 @@ public class GenFfsFileTask extends Task implements EfiDefine, FfsTypes {
                 stringToGuid (this.ffsFileGuid, ffsHeader.name);\r
             }\r
 \r
+            //\r
+            // because we may have changed the ffsAttribDataAlignment, we need to refresh attributes\r
+            // \r
+            this.attributes &= ~(((byte)7) << 3);\r
+            this.attributes |= (((byte)this.ffsAttribDataAlignment) << 3);\r
+\r
             ffsHeader.ffsAttributes = this.attributes;\r
             if ((ffsHeader.fileType = stringToType(this.ffsFileType))== -1) {\r
                 throw new BuildException ("FFS_FILE_TYPE unknow!\n");\r