Skip to content

Commit dfe5351

Browse files
committed
Trusted Firmware (TF-M) build script
Create a script (tools/psa/build_tfm.py) to build Trusted Firmware M (TF-M) image. Current version of the script only clones the TF-M git repo and its dependencies and computes the version information of TF-M repo and write it to 'features/FEATURE_PSA/FEATURE_TFM/VERSION.txt' Signed-off-by: Devaraj Ranganna <[email protected]>
1 parent cdcef4b commit dfe5351

File tree

1 file changed

+181
-0
lines changed

1 file changed

+181
-0
lines changed

tools/psa/build_tfm.py

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
#!/usr/bin/env python
2+
"""
3+
Copyright (c) 2019 ARM Limited. All rights reserved.
4+
5+
SPDX-License-Identifier: Apache-2.0
6+
7+
Licensed under the Apache License, Version 2.0 (the "License");
8+
you may not use this file except in compliance with the License.
9+
You may obtain a copy of the License at
10+
11+
http://www.apache.org/licenses/LICENSE-2.0
12+
13+
Unless required by applicable law or agreed to in writing, software
14+
distributed under the License is distributed on an "AS IS" BASIS,
15+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
See the License for the specific language governing permissions and
17+
limitations under the License.
18+
"""
19+
20+
import os
21+
from os.path import join, abspath, dirname, isdir
22+
import sys
23+
import shutil
24+
import subprocess
25+
import logging
26+
27+
logger = logging.getLogger('TF-M-Builder')
28+
logging.basicConfig(level=logging.INFO,
29+
format='[%(name)s] %(asctime)s: %(message)s.',
30+
datefmt='%H:%M:%S')
31+
32+
ROOT = abspath(join(dirname(__file__), os.pardir, os.pardir))
33+
sys.path.insert(0, ROOT)
34+
35+
TF_M_BUILD_DIR = join(ROOT, os.pardir, 'tfm_build_dir')
36+
VERSION_FILE_PATH = join(ROOT, 'features/FEATURE_PSA/FEATURE_TFM')
37+
38+
dependencies = {
39+
"trusted-firmware-m":
40+
['https://git.trustedfirmware.org/trusted-firmware-m.git',
41+
'feature-twincpu'],
42+
"mbedtls": ['https://github.com/ARMmbed/mbedtls.git',
43+
'mbedtls-2.7.9'],
44+
"mbed-crypto": ['https://github.com/ARMmbed/mbed-crypto.git',
45+
'mbedcrypto-1.1.0'],
46+
"CMSIS_5": ['https://github.com/ARM-software/CMSIS_5.git', '5.5.0'],
47+
}
48+
49+
def is_git_installed():
50+
"""
51+
Check if git is installed
52+
"""
53+
command = ['git', '--version']
54+
try:
55+
with open(os.devnull, 'w') as fnull:
56+
return subprocess.call(command, stdout=fnull, stderr=fnull)
57+
except OSError as e:
58+
return e.errno
59+
60+
def is_git_lfs_installed():
61+
"""
62+
Check if git-lfs is installed
63+
"""
64+
command = ['git-lfs', '--version']
65+
try:
66+
with open(os.devnull, 'w') as fnull:
67+
return subprocess.call(command, stdout=fnull, stderr=fnull)
68+
except OSError as e:
69+
return e.errno
70+
71+
def run_cmd_and_return_output(command):
72+
"""
73+
Run the command in the sytem and return output.
74+
Commands are passed as a list of tokens.
75+
E.g. The command 'git remote -v' would be passed in as:
76+
['git', 'remote', '-v']
77+
78+
:param command: System command as a list of tokens
79+
"""
80+
output = ''
81+
logger.debug('[Exec] %s', ' '.join(command))
82+
try:
83+
with open(os.devnull, 'w') as fnull:
84+
output = subprocess.check_output(command, stderr=fnull)
85+
except subprocess.CalledProcessError as e:
86+
logger.error("The command %s failed with return code: %s",
87+
(' '.join(command)), e.returncode)
88+
clean_up_cloned_repos()
89+
return output.decode("utf-8")
90+
91+
def detect_and_write_tfm_version(tfm_dir):
92+
"""
93+
Identify the version of TF-M and write it to VERSION.txt
94+
:param tfm_dir: The filesystem path where TF-M repo is cloned
95+
"""
96+
cmd = ['git', '-C', tfm_dir, 'describe', '--tags',
97+
'--abbrev=12', '--dirty', '--always']
98+
tfm_version = run_cmd_and_return_output(cmd)
99+
logger.info('TF-M version: %s', tfm_version.strip('\n'))
100+
if not isdir(VERSION_FILE_PATH):
101+
os.makedirs(VERSION_FILE_PATH)
102+
with open(join(VERSION_FILE_PATH, 'VERSION.txt'), 'w') as f:
103+
f.write(tfm_version)
104+
105+
def check_repo_version(name, deps):
106+
"""
107+
Compare the version of cloned and expected and exit if they dont match
108+
:param name: Name of the git repository
109+
:param deps: Dictionary containing dependency details
110+
"""
111+
basedir = TF_M_BUILD_DIR
112+
if name == 'trusted-firmware-m':
113+
cmd = ['git', '-C', join(basedir, name),
114+
'rev-parse', '--abbrev-ref', 'HEAD']
115+
else:
116+
cmd = ['git', '-C', join(basedir, name),
117+
'describe', '--tags']
118+
_out = run_cmd_and_return_output(cmd)
119+
if _out.strip('\n') != deps.get(name)[1]:
120+
logger.error('Conflict: cloned "%s" and expected "%s"',
121+
_out.strip('\n'), deps.get(name)[1])
122+
logger.error('check and remove folder %s',
123+
join(basedir, name))
124+
sys.exit(1)
125+
else:
126+
logger.info('%s: version check OK', name)
127+
128+
def check_and_clone_repo(name, deps):
129+
"""
130+
Test if the repositories are already cloned. If not clone them
131+
:param name: Name of the git repository
132+
:param deps: Dictionary containing dependency details
133+
"""
134+
basedir = TF_M_BUILD_DIR
135+
if not isdir(join(basedir, name)):
136+
logger.info('Cloning %s repo', name)
137+
cmd = ['git', '-C', basedir, 'clone', '-b',
138+
deps.get(name)[1], deps.get(name)[0]]
139+
_out = run_cmd_and_return_output(cmd)
140+
logger.info('Cloned %s repo successfully', name)
141+
else:
142+
logger.info('%s repo exists, checking git version...', name)
143+
check_repo_version(name, deps)
144+
145+
def clone_tfm_repo():
146+
"""
147+
Clone TF-M git repos and it's dependencies
148+
"""
149+
check_and_clone_repo('trusted-firmware-m', dependencies)
150+
check_and_clone_repo('mbedtls', dependencies)
151+
check_and_clone_repo('mbed-crypto', dependencies)
152+
check_and_clone_repo('CMSIS_5', dependencies)
153+
detect_and_write_tfm_version(join(TF_M_BUILD_DIR, 'trusted-firmware-m'))
154+
155+
def clean_up_cloned_repos():
156+
"""
157+
Clean up cloned repos in case of any errors
158+
"""
159+
try:
160+
shutil.rmtree(TF_M_BUILD_DIR)
161+
except OSError as e:
162+
logger.error('Unable to cleanup cloned repos')
163+
logger.error('"%s" occured', e.strerror)
164+
165+
def main():
166+
"""
167+
Build Trusted Firmware M (TF-M) image for mbed-os supported TF-M targets.
168+
Current version of the script only clones TF-M git repo and dependencies
169+
and creates a VERSION.txt file under 'features/FEATURE_PSA/FEATURE_TFM'
170+
"""
171+
if not isdir(TF_M_BUILD_DIR):
172+
os.mkdir(TF_M_BUILD_DIR)
173+
clone_tfm_repo()
174+
175+
if __name__ == '__main__':
176+
if is_git_installed() != 0:
177+
logger.error('"git" is not installed. Exiting...')
178+
elif is_git_lfs_installed() != 0:
179+
logger.error('"git-lfs" is not installed. Exiting...')
180+
else:
181+
main()

0 commit comments

Comments
 (0)