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