Skip to content

Commit a4f7f3f

Browse files
scripts: add build_bootloaders
1 parent 8d231ce commit a4f7f3f

File tree

1 file changed

+118
-0
lines changed

1 file changed

+118
-0
lines changed

scripts/build_bootloaders.py

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
#!/usr/bin/env python
2+
3+
"""
4+
script to build all of our bootloaders using AP_Bootloader and put the resulting binaries in Tools/bootloaders
5+
"""
6+
7+
import os
8+
import shutil
9+
import subprocess
10+
import sys
11+
import fnmatch
12+
import re
13+
14+
# get command line arguments
15+
from argparse import ArgumentParser
16+
parser = ArgumentParser(description='make_secure_bl')
17+
parser.add_argument("--signing-key", type=str, default=None, help="signing key for secure bootloader")
18+
parser.add_argument("--debug", action='store_true', default=False, help="build with debug symbols")
19+
parser.add_argument("--periph-only", action='store_true', default=False, help="only build AP_Periph boards")
20+
parser.add_argument("pattern", type=str, default='*', help="board wildcard pattern")
21+
args = parser.parse_args()
22+
23+
if args.signing_key is not None and os.path.basename(args.signing_key).lower().find("private") != -1:
24+
# prevent the easy mistake of using private key
25+
print("You must use the public key in the bootloader")
26+
sys.exit(1)
27+
28+
os.environ['PYTHONUNBUFFERED'] = '1'
29+
30+
failed_boards = set()
31+
32+
def read_hwdef(filepath):
33+
'''read a hwdef file recursively'''
34+
fh = open(filepath)
35+
ret = []
36+
text = fh.readlines()
37+
for line in text:
38+
m = re.match(r"^\s*include\s+(.+)\s*$", line)
39+
if m is not None:
40+
ret += read_hwdef(os.path.join(os.path.dirname(filepath), m.group(1)))
41+
else:
42+
ret += [line]
43+
return ret
44+
45+
def is_ap_periph(hwdef):
46+
'''return True if a hwdef is for a AP_Periph board'''
47+
lines = read_hwdef(hwdef)
48+
for line in lines:
49+
if line.find('AP_PERIPH') != -1:
50+
return True
51+
return False
52+
53+
def get_board_list():
54+
'''add boards based on existance of hwdef-bl.dat in subdirectories for ChibiOS'''
55+
board_list = []
56+
dirname, dirlist, filenames = next(os.walk('.'))
57+
for d in dirlist:
58+
hwdef = os.path.join(dirname, d, 'hwdef-bl.dat')
59+
if os.path.exists(hwdef):
60+
if args.periph_only and not is_ap_periph(hwdef):
61+
continue
62+
board_list.append(d)
63+
return board_list
64+
65+
def run_program(cmd_list):
66+
print("Running (%s)" % " ".join(cmd_list))
67+
retcode = subprocess.call(cmd_list)
68+
if retcode != 0:
69+
print("Build failed: %s" % ' '.join(cmd_list))
70+
return False
71+
return True
72+
73+
def build_board(board):
74+
configure_args = "--board %s --bootloader --no-submodule-update --Werror" % board
75+
configure_args = configure_args.split()
76+
if args.signing_key is not None:
77+
print("Building secure bootloader")
78+
configure_args.append("--signed-fw")
79+
if args.debug:
80+
print("Building with debug symbols")
81+
configure_args.append("--debug")
82+
if not run_program(["./waf", "configure"] + configure_args):
83+
return False
84+
if not run_program(["./waf", "clean"]):
85+
return False
86+
if not run_program(["./waf", "bootloader"]):
87+
return False
88+
return True
89+
90+
for board in get_board_list():
91+
if not fnmatch.fnmatch(board, args.pattern):
92+
continue
93+
print("Building for %s" % board)
94+
if not build_board(board):
95+
failed_boards.add(board)
96+
continue
97+
bl_file = 'bootloaders/%s_bl.bin' % board
98+
hex_file = 'bootloaders/%s_bl.hex' % board
99+
elf_file = 'bootloaders/%s_bl.elf' % board
100+
shutil.copy('build/%s/bin/AP_Bootloader.bin' % board, bl_file)
101+
print("Created %s" % bl_file)
102+
shutil.copy('build/%s/bootloader/AP_Bootloader' % board, elf_file)
103+
print("Created %s" % elf_file)
104+
if args.signing_key is not None:
105+
print("Signing bootloader with %s" % args.signing_key)
106+
if not run_program(["./ardupilot/Tools/scripts/signing/make_secure_bl.py", bl_file, args.signing_key]):
107+
print("Failed to sign bootloader for %s" % board)
108+
sys.exit(1)
109+
if not run_program(["./ardupilot/Tools/scripts/signing/make_secure_bl.py", elf_file, args.signing_key]):
110+
print("Failed to sign ELF bootloader for %s" % board)
111+
sys.exit(1)
112+
if not run_program([sys.executable, "ardupilot/Tools/scripts/bin2hex.py", "--offset", "0x08000000", bl_file, hex_file]):
113+
failed_boards.add(board)
114+
continue
115+
print("Created %s" % hex_file)
116+
117+
if len(failed_boards):
118+
print("Failed boards: %s" % list(failed_boards))

0 commit comments

Comments
 (0)