]>
Commit | Line | Data |
---|---|---|
f4e72cf9 TD |
1 | ## @file\r |
2 | # This file contains the script to build UniversalPayload\r | |
3 | #\r | |
4 | # Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>\r | |
5 | # SPDX-License-Identifier: BSD-2-Clause-Patent\r | |
6 | ##\r | |
7 | \r | |
8 | import argparse\r | |
9 | import subprocess\r | |
10 | import os\r | |
11 | import shutil\r | |
12 | import sys\r | |
4a1899dd GD |
13 | from ctypes import *\r |
14 | \r | |
15 | sys.dont_write_bytecode = True\r | |
16 | \r | |
17 | class UPLD_INFO_HEADER(LittleEndianStructure):\r | |
18 | _pack_ = 1\r | |
19 | _fields_ = [\r | |
20 | ('Identifier', ARRAY(c_char, 4)),\r | |
21 | ('HeaderLength', c_uint32),\r | |
22 | ('SpecRevision', c_uint16),\r | |
23 | ('Reserved', c_uint16),\r | |
24 | ('Revision', c_uint32),\r | |
25 | ('Attribute', c_uint32),\r | |
26 | ('Capability', c_uint32),\r | |
27 | ('ProducerId', ARRAY(c_char, 16)),\r | |
28 | ('ImageId', ARRAY(c_char, 16)),\r | |
29 | ]\r | |
30 | \r | |
31 | def __init__(self):\r | |
32 | self.Identifier = b'UPLD'\r | |
33 | self.HeaderLength = sizeof(UPLD_INFO_HEADER)\r | |
34 | self.HeaderRevision = 0x0075\r | |
35 | self.Revision = 0x0000010105\r | |
36 | self.ImageId = b'UEFI'\r | |
37 | self.ProducerId = b'INTEL'\r | |
f4e72cf9 TD |
38 | \r |
39 | def RunCommand(cmd):\r | |
40 | print(cmd)\r | |
41 | p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,cwd=os.environ['WORKSPACE'])\r | |
42 | while True:\r | |
43 | line = p.stdout.readline()\r | |
44 | if not line:\r | |
45 | break\r | |
46 | print(line.strip().decode(errors='ignore'))\r | |
47 | \r | |
48 | p.communicate()\r | |
49 | if p.returncode != 0:\r | |
50 | print("- Failed - error happened when run command: %s"%cmd)\r | |
51 | raise Exception("ERROR: when run command: %s"%cmd)\r | |
52 | \r | |
53 | def BuildUniversalPayload(Args, MacroList):\r | |
54 | BuildTarget = Args.Target\r | |
55 | ToolChain = Args.ToolChain\r | |
4cfb28f1 | 56 | Quiet = "--quiet" if Args.Quiet else ""\r |
67608430 | 57 | BuildArch = "X64" if Args.Arch == 'X64' else "IA32 -a X64"\r |
f4e72cf9 TD |
58 | ElfToolChain = 'CLANGDWARF'\r |
59 | \r | |
60 | EntryModuleInf = os.path.normpath("UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf")\r | |
61 | DscPath = os.path.normpath("UefiPayloadPkg/UefiPayloadPkg.dsc")\r | |
62 | BuildDir = os.path.join(os.environ['WORKSPACE'], os.path.normpath("Build/UefiPayloadPkgX64"))\r | |
63 | FvOutputDir = os.path.join(BuildDir, f"{BuildTarget}_{ToolChain}", os.path.normpath("FV/DXEFV.Fv"))\r | |
64 | EntryOutputDir = os.path.join(BuildDir, f"{BuildTarget}_{ElfToolChain}", os.path.normpath("X64/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry/DEBUG/UniversalPayloadEntry.dll"))\r | |
65 | PayloadReportPath = os.path.join(BuildDir, "UefiUniversalPayload.txt")\r | |
66 | ModuleReportPath = os.path.join(BuildDir, "UefiUniversalPayloadEntry.txt")\r | |
4a1899dd | 67 | UpldInfoFile = os.path.join(BuildDir, "UniversalPayloadInfo.bin")\r |
f4e72cf9 TD |
68 | \r |
69 | if "CLANG_BIN" in os.environ:\r | |
70 | LlvmObjcopyPath = os.path.join(os.environ["CLANG_BIN"], "llvm-objcopy")\r | |
71 | else:\r | |
72 | LlvmObjcopyPath = "llvm-objcopy"\r | |
73 | try:\r | |
74 | RunCommand('"%s" --version'%LlvmObjcopyPath)\r | |
75 | except:\r | |
76 | print("- Failed - Please check if LLVM is installed or if CLANG_BIN is set correctly")\r | |
77 | sys.exit(1)\r | |
78 | \r | |
79 | Defines = ""\r | |
80 | for key in MacroList:\r | |
81 | Defines +=" -D {0}={1}".format(key, MacroList[key])\r | |
82 | \r | |
83 | #\r | |
84 | # Building DXE core and DXE drivers as DXEFV.\r | |
85 | #\r | |
dab96cf0 | 86 | BuildPayload = f"build -p {DscPath} -b {BuildTarget} -a X64 -t {ToolChain} -y {PayloadReportPath} {Quiet}"\r |
f4e72cf9 TD |
87 | BuildPayload += Defines\r |
88 | RunCommand(BuildPayload)\r | |
89 | #\r | |
90 | # Building Universal Payload entry.\r | |
91 | #\r | |
dab96cf0 | 92 | BuildModule = f"build -p {DscPath} -b {BuildTarget} -a {BuildArch} -m {EntryModuleInf} -t {ElfToolChain} -y {ModuleReportPath} {Quiet}"\r |
f4e72cf9 TD |
93 | BuildModule += Defines\r |
94 | RunCommand(BuildModule)\r | |
95 | \r | |
4a1899dd GD |
96 | #\r |
97 | # Buid Universal Payload Information Section ".upld_info"\r | |
98 | #\r | |
99 | upld_info_hdr = UPLD_INFO_HEADER()\r | |
100 | upld_info_hdr.ImageId = Args.ImageId.encode()[:16]\r | |
101 | fp = open(UpldInfoFile, 'wb')\r | |
102 | fp.write(bytearray(upld_info_hdr))\r | |
103 | fp.close()\r | |
104 | \r | |
f4e72cf9 TD |
105 | #\r |
106 | # Copy the DXEFV as a section in elf format Universal Payload entry.\r | |
107 | #\r | |
4a1899dd GD |
108 | remove_section = '"%s" -I elf64-x86-64 -O elf64-x86-64 --remove-section .upld_info --remove-section .upld.uefi_fv %s'%(LlvmObjcopyPath, EntryOutputDir)\r |
109 | add_section = '"%s" -I elf64-x86-64 -O elf64-x86-64 --add-section .upld_info=%s --add-section .upld.uefi_fv=%s %s'%(LlvmObjcopyPath, UpldInfoFile, FvOutputDir, EntryOutputDir)\r | |
110 | set_section = '"%s" -I elf64-x86-64 -O elf64-x86-64 --set-section-alignment .upld.upld_info=16 --set-section-alignment .upld.uefi_fv=16 %s'%(LlvmObjcopyPath, EntryOutputDir)\r | |
f4e72cf9 TD |
111 | RunCommand(remove_section)\r |
112 | RunCommand(add_section)\r | |
113 | RunCommand(set_section)\r | |
114 | \r | |
115 | shutil.copy (EntryOutputDir, os.path.join(BuildDir, 'UniversalPayload.elf'))\r | |
116 | \r | |
117 | def main():\r | |
118 | parser = argparse.ArgumentParser(description='For building Universal Payload')\r | |
119 | parser.add_argument('-t', '--ToolChain')\r | |
120 | parser.add_argument('-b', '--Target', default='DEBUG')\r | |
67608430 | 121 | parser.add_argument('-a', '--Arch', choices=['IA32', 'X64'], help='Specify the ARCH for payload entry module. Default build X64 image.', default ='X64')\r |
f4e72cf9 | 122 | parser.add_argument("-D", "--Macro", action="append", default=["UNIVERSAL_PAYLOAD=TRUE"])\r |
4a1899dd | 123 | parser.add_argument('-i', '--ImageId', type=str, help='Specify payload ID (16 bytes maximal).', default ='UEFI')\r |
4cfb28f1 | 124 | parser.add_argument('-q', '--Quiet', action='store_true', help='Disable all build messages except FATAL ERRORS.')\r |
f4e72cf9 TD |
125 | MacroList = {}\r |
126 | args = parser.parse_args()\r | |
127 | if args.Macro is not None:\r | |
128 | for Argument in args.Macro:\r | |
129 | if Argument.count('=') != 1:\r | |
130 | print("Unknown variable passed in: %s"%Argument)\r | |
131 | raise Exception("ERROR: Unknown variable passed in: %s"%Argument)\r | |
132 | tokens = Argument.strip().split('=')\r | |
133 | MacroList[tokens[0].upper()] = tokens[1]\r | |
134 | BuildUniversalPayload(args, MacroList)\r | |
135 | print ("Successfully build Universal Payload")\r | |
136 | \r | |
137 | if __name__ == '__main__':\r | |
138 | main()\r |