PlatformPayloadFeaturePkg.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. ## @file
  2. # This file contains the script to build UniversalPayload with platform payload
  3. #
  4. # Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
  5. # SPDX-License-Identifier: BSD-2-Clause-Patent
  6. ##
  7. import argparse
  8. import subprocess
  9. import os
  10. import shutil
  11. import sys
  12. from ctypes import *
  13. sys.dont_write_bytecode = True
  14. def RunCommand(cmd):
  15. print(cmd)
  16. p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,cwd=os.environ['WORKSPACE'])
  17. while True:
  18. line = p.stdout.readline()
  19. if not line:
  20. break
  21. print(line.strip().decode(errors='ignore'))
  22. p.communicate()
  23. if p.returncode != 0:
  24. print("- Failed - error happened when run command: %s"%cmd)
  25. raise Exception("ERROR: when run command: %s"%cmd)
  26. def BuildUniversalPayload(Args, MacroList):
  27. BuildTarget = Args.Target
  28. ToolChain = Args.ToolChain
  29. ElfToolChain = 'CLANGDWARF'
  30. ObjCopyFlag = "elf64-x86-64" if Args.Arch == 'X64' else "elf32-i386"
  31. #
  32. # Find universal UEFI payload build build script
  33. #
  34. Edk2PayloadBuildScript = os.path.normpath("UefiPayloadPkg/UniversalPayloadBuild.py")
  35. for package_path in os.environ['PACKAGES_PATH'].split(os.pathsep):
  36. if os.path.exists (os.path.join (package_path, Edk2PayloadBuildScript)):
  37. Edk2PayloadBuildScript = os.path.join (package_path, Edk2PayloadBuildScript)
  38. break
  39. if not os.path.exists (Edk2PayloadBuildScript):
  40. raise Exception("Could not find universal UEFI payload build script UniversalPayloadBuild.py")
  41. PlatformFvDscPath = os.path.normpath("PlatformPayloadFeaturePkg/PlatformPayloadFeaturePkg.dsc")
  42. BuildDir = os.path.join(os.environ['WORKSPACE'], os.path.normpath("Build/UefiPayloadPkgX64"))
  43. PlatformFvReportPath = os.path.join(BuildDir, "PlatformPayloadReport.txt")
  44. UniversalUefiPld = os.path.join(BuildDir, 'UniversalPayload.elf')
  45. PlatformFv = os.path.join(os.environ['WORKSPACE'], os.path.normpath("Build/PlatformPayloadFeaturePkg"), f"{BuildTarget}_{ToolChain}", os.path.normpath("FV/PLATFORMPAYLOAD.Fv"))
  46. if "CLANG_BIN" in os.environ:
  47. LlvmObjcopyPath = os.path.join(os.environ["CLANG_BIN"], "llvm-objcopy")
  48. else:
  49. LlvmObjcopyPath = "llvm-objcopy"
  50. try:
  51. RunCommand('"%s" --version'%LlvmObjcopyPath)
  52. except:
  53. print("- Failed - Please check if LLVM is installed or if CLANG_BIN is set correctly")
  54. sys.exit(1)
  55. Defines = ""
  56. for key in MacroList:
  57. Defines +=" -D {0}={1}".format(key, MacroList[key])
  58. #
  59. # Building Universal Payload entry.
  60. #
  61. if not Args.Skip:
  62. BuildPayload = f"python {Edk2PayloadBuildScript} -b {BuildTarget} -t {ToolChain} -a {Args.Arch} {Defines}"
  63. RunCommand(BuildPayload)
  64. #
  65. # Building Platform Payload.
  66. #
  67. BuildPayload = f"build -p {PlatformFvDscPath} -b {BuildTarget} -a X64 -t {ToolChain} -y {PlatformFvReportPath}"
  68. BuildPayload += Defines
  69. RunCommand(BuildPayload)
  70. #
  71. # Copy the Platform Payload as a section in elf format Universal Payload.
  72. #
  73. remove_section = f'"{LlvmObjcopyPath}" -I {ObjCopyFlag} -O {ObjCopyFlag} --remove-section .upld.platform_fv {UniversalUefiPld}'
  74. add_section = f'"{LlvmObjcopyPath}" -I {ObjCopyFlag} -O {ObjCopyFlag} --add-section .upld.platform_fv={PlatformFv} {UniversalUefiPld}'
  75. set_section = f'"{LlvmObjcopyPath}" -I {ObjCopyFlag} -O {ObjCopyFlag} --set-section-alignment .upld.platform_fv=16 {UniversalUefiPld}'
  76. RunCommand(remove_section)
  77. RunCommand(add_section)
  78. RunCommand(set_section)
  79. def main():
  80. parser = argparse.ArgumentParser(description='Build Platform Payload FV and add it to Universal UEFI Payload')
  81. parser.add_argument('-t', '--ToolChain')
  82. parser.add_argument('-b', '--Target', default='DEBUG')
  83. parser.add_argument('-a', '--Arch', choices=['IA32', 'X64'], help='Specify the ARCH for payload entry module. Default build X64 image.', default ='X64')
  84. parser.add_argument("-D", "--Macro", action="append")
  85. parser.add_argument('-s', '--Skip', action='store_true', help='Skip Universal UEFI payload build (just build platform FV and add to Universal UEFI payload.')
  86. MacroList = {}
  87. args = parser.parse_args()
  88. if args.Macro is not None:
  89. for Argument in args.Macro:
  90. if Argument.count('=') != 1:
  91. print("Unknown variable passed in: %s"%Argument)
  92. raise Exception("ERROR: Unknown variable passed in: %s"%Argument)
  93. tokens = Argument.strip().split('=')
  94. MacroList[tokens[0].upper()] = tokens[1]
  95. BuildUniversalPayload(args, MacroList)
  96. print ("Successfully build Universal Payload with platform FV")
  97. if __name__ == '__main__':
  98. main()