251 lines
9.5 KiB
Python
Executable File
251 lines
9.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
import logging
|
|
import getpass
|
|
import shutil
|
|
|
|
from argparse import _MutuallyExclusiveGroup
|
|
from genericpath import exists
|
|
import click
|
|
from click_option_group import optgroup,RequiredMutuallyExclusiveOptionGroup
|
|
|
|
armino_path = os.getenv("ARMINO_PATH")
|
|
project_dir = os.getenv("PROJECT_DIR")
|
|
project_name = os.getenv("PROJECT")
|
|
armino_soc = os.getenv("ARMINO_SOC")
|
|
build_path=os.path.realpath('.')
|
|
header_path = "{}/tools/env_tools/rtt_ota/ota-rbl/".format(armino_path)
|
|
is_secure_boot = False
|
|
|
|
cpu1_bin = f'{armino_path}/{project_dir}/{armino_soc}_cpu1.bin'
|
|
bootloader_bin = f'{armino_path}/properties/modules/bootloader/aboot/arm_bootloader/output/bootloader.bin'
|
|
|
|
nosecurity_pack = "%s/middleware/boards/%s/%s_nosecurity.wrapper"%(armino_path, armino_soc, armino_soc)
|
|
nosecurity_cpu1_bin = '%s/%s/app1.bin'%(armino_path, project_dir)
|
|
pack_boot_tools = '%s/tools/env_tools/beken_packager'%(armino_path)
|
|
|
|
project_full_path = f'{armino_path}/{project_dir}/config/{armino_soc}'
|
|
secure_config_path = os.path.join(project_full_path,'config')
|
|
|
|
if os.path.exists(secure_config_path):
|
|
with open(secure_config_path, 'r') as config_file:
|
|
config_string = config_file.read()
|
|
|
|
config_lines = config_string.strip().split('\n')
|
|
|
|
config_dict = {}
|
|
|
|
for line in config_lines:
|
|
if '=' not in line:
|
|
continue
|
|
key, value = line.split('=')
|
|
config_dict[key.strip()] = value.strip()
|
|
|
|
if config_dict.get('CONFIG_SECURITY_FIRMWARE') == 'y':
|
|
is_secure_boot = True
|
|
|
|
|
|
def run_cmd(cmd):
|
|
p = subprocess.Popen(cmd, shell=True)
|
|
ret = p.wait()
|
|
if (ret):
|
|
logging.error(f'failed to run "{cmd}"')
|
|
exit(1)
|
|
|
|
def run_cmd_with_ret(cmd):
|
|
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding='utf-8')
|
|
out, err = p.communicate()
|
|
print(out)
|
|
if (p.returncode):
|
|
print(err)
|
|
exit(1)
|
|
|
|
def copy_files(postfix, src_dir, dst_dir):
|
|
logging.debug(f'copy *{postfix} from {src_dir}')
|
|
logging.debug(f'to {dst_dir}')
|
|
for f in os.listdir(src_dir):
|
|
if f.endswith(postfix):
|
|
shutil.copy(f'{src_dir}/{f}', f'{dst_dir}/{f}')
|
|
|
|
def install_configs(cfg_dir, install_dir):
|
|
logging.debug(f'install configs from: {cfg_dir}')
|
|
logging.debug(f'to: {install_dir}')
|
|
if os.path.exists(f'{cfg_dir}') == False:
|
|
return
|
|
|
|
copy_files('.bin', cfg_dir, install_dir)
|
|
copy_files('.json', cfg_dir, install_dir)
|
|
copy_files('.pem', cfg_dir, install_dir)
|
|
copy_files('.csv', cfg_dir, install_dir)
|
|
|
|
if os.path.exists(f'{cfg_dir}/key') == True:
|
|
copy_files('.pem', f'{cfg_dir}/key', install_dir)
|
|
if os.path.exists(f'{cfg_dir}/csv') == True:
|
|
copy_files('.csv', f'{cfg_dir}/csv', install_dir)
|
|
if os.path.exists(f'{cfg_dir}/regs') == True:
|
|
copy_files('.csv', f'{cfg_dir}/regs', install_dir)
|
|
|
|
def move_file(bin_name, src_dir, dst_dir):
|
|
logging.debug(f'move {bin_name} from {src_dir}')
|
|
logging.debug(f'to {dst_dir}')
|
|
if os.path.exists(f'{src_dir}/{bin_name}') == True:
|
|
if os.path.exists(dst_dir):
|
|
shutil.copy2(f'{src_dir}/{bin_name}', f'{dst_dir}')
|
|
else:
|
|
shutil.move(f'{src_dir}/{bin_name}', f'{dst_dir}')
|
|
|
|
def copy_file(src, dst):
|
|
logging.debug(f'copy {src} to {dst}')
|
|
logging.debug(f'to {dst}')
|
|
if os.path.exists(f'{src}') == True:
|
|
shutil.copy(f'{src}', f'{dst}')
|
|
|
|
def pack(prebuild):
|
|
|
|
soc = armino_soc
|
|
tools_dir = f'{armino_path}/tools/env_tools'
|
|
bin_dir = build_path
|
|
cpu0_armino_soc = armino_soc.replace('_cp1', '')
|
|
base_cfg_dir = f'{armino_path}/middleware/boards/{cpu0_armino_soc}' #CPU1 share the same config with CPU0
|
|
prefered_cfg_dir = f'{armino_path}/{project_dir}/config'
|
|
gen_dir = f'{build_path}/generated'
|
|
debug = True
|
|
|
|
if (debug):
|
|
logging.basicConfig()
|
|
logging.getLogger().setLevel(logging.DEBUG)
|
|
|
|
logging.debug(f'tools_dir={tools_dir}')
|
|
logging.debug(f'base_cfg_dir={base_cfg_dir}')
|
|
logging.debug(f'prefered_cfg_dir={prefered_cfg_dir}')
|
|
logging.debug(f'soc={soc}')
|
|
logging.debug(f'pack={pack}')
|
|
|
|
SH_SEC_TOOL = f'{tools_dir}/sh_sec_tools/secure_boot_tool'
|
|
BK_UTILS_TOOL = f'{tools_dir}/beken_utils/main.py'
|
|
MCUBOOT_IMG_TOOL = f'{tools_dir}/mcuboot_tools'
|
|
|
|
CMAKE_BIN_DIR = bin_dir
|
|
CMAKE_INSTALL_DIR = f'{CMAKE_BIN_DIR}/install'
|
|
BASE_CFG_DIR = base_cfg_dir
|
|
_BUILD_DIR = f'{bin_dir}/_build'
|
|
|
|
logging.debug(f'Create temporary _build')
|
|
os.makedirs(f'{_BUILD_DIR}', exist_ok=True)
|
|
|
|
saved_cur_dir = os.getcwd()
|
|
os.chdir(_BUILD_DIR)
|
|
logging.debug(f'cd {_BUILD_DIR}')
|
|
|
|
install_configs(BASE_CFG_DIR, _BUILD_DIR)
|
|
install_configs(prefered_cfg_dir, _BUILD_DIR)
|
|
install_configs(f'{prefered_cfg_dir}/common', _BUILD_DIR)
|
|
install_configs(f'{prefered_cfg_dir}/{cpu0_armino_soc}', _BUILD_DIR)
|
|
|
|
debug_option = ''
|
|
if (debug):
|
|
debug_option = f'--debug'
|
|
logging.debug(f'partition pre-processing')
|
|
|
|
if prebuild:
|
|
if (gen_dir == None):
|
|
logging.error(f'Generated dir should NOT be empty')
|
|
exit(1)
|
|
run_cmd(f'{BK_UTILS_TOOL} gen all --debug')
|
|
cwd = os.getcwd()
|
|
copy_file(f'{cwd}/partitions_partition.h', f'{cwd}/partitions_gen.h')
|
|
return
|
|
|
|
logging.debug(f'Copy Armino bin to {_BUILD_DIR}')
|
|
|
|
if (os.path.exists(f'{CMAKE_BIN_DIR}/app.bin') == True):
|
|
copy_file(f'{CMAKE_BIN_DIR}/app.bin', f'{_BUILD_DIR}/cpu0_app.bin')
|
|
TFM_BIN_DIR = f'{CMAKE_BIN_DIR}/tfm_install/outputs'
|
|
if (os.path.exists(TFM_BIN_DIR) == True):
|
|
logging.debug(f'Copy TFM bin to {_BUILD_DIR}')
|
|
copy_files('.bin', TFM_BIN_DIR, _BUILD_DIR)
|
|
|
|
if (os.path.exists(cpu1_bin) == True):
|
|
copy_file(cpu1_bin, f'{_BUILD_DIR}/cpu1_app.bin')
|
|
else:
|
|
logging.info(f'{cpu1_bin} not exist, could compile: make {soc} PROJECT=cpu1')
|
|
|
|
dest_boot_dir = f'{armino_path}/components/bk_libs/{armino_soc}/bootloader/normal_bootloader'
|
|
os.makedirs(dest_boot_dir, exist_ok=True)
|
|
if is_secure_boot == False:
|
|
if (os.path.exists(bootloader_bin) == True):
|
|
copy_file(bootloader_bin, f'{dest_boot_dir}/bootloader.bin')
|
|
run_cmd('%s/cmake_Gen_image genfile -injsonfile %s/config.json -infile %s/bootloader.bin -outfile %s/bootloader.bin -genjson %s/partition_bootloader.json'%(pack_boot_tools, pack_boot_tools, dest_boot_dir,_BUILD_DIR, pack_boot_tools))
|
|
elif (os.path.exists(f'{dest_boot_dir}/bootloader.bin') == True):
|
|
logging.info(f'{bootloader_bin} not exist, could compile:')
|
|
run_cmd('%s/cmake_Gen_image genfile -injsonfile %s/config.json -infile %s/bootloader.bin -outfile %s/bootloader.bin -genjson %s/partition_bootloader.json'%(pack_boot_tools, pack_boot_tools, dest_boot_dir,_BUILD_DIR, pack_boot_tools))
|
|
else:
|
|
pass
|
|
|
|
run_cmd(f'{BK_UTILS_TOOL} pack all --debug')
|
|
|
|
logging.debug(f'copy binaries')
|
|
os.makedirs(f'{CMAKE_INSTALL_DIR}', exist_ok=True)
|
|
copy_file(f'{_BUILD_DIR}/ota.bin', f'{CMAKE_INSTALL_DIR}/ota.bin')
|
|
copy_file(f'{_BUILD_DIR}/all-app.bin', f'{CMAKE_INSTALL_DIR}/all-app.bin')
|
|
copy_file(f'{_BUILD_DIR}/bootloader.bin', f'{CMAKE_INSTALL_DIR}/bootloader.bin')
|
|
copy_file(f'{_BUILD_DIR}/provision_pack.bin', f'{CMAKE_INSTALL_DIR}/provision_pack.bin')
|
|
copy_file(f'{CMAKE_BIN_DIR}/app.elf', f'{CMAKE_INSTALL_DIR}/app.elf')
|
|
copy_file(f'{CMAKE_BIN_DIR}/tfm_install/outputs/tfm_s.elf', f'{CMAKE_INSTALL_DIR}/tfm_s.elf')
|
|
copy_file(f'{CMAKE_BIN_DIR}/tfm_install/outputs/bl2.elf', f'{CMAKE_INSTALL_DIR}/bl2.elf')
|
|
copy_file(f'{_BUILD_DIR}/otp_efuse_config.json', f'{CMAKE_INSTALL_DIR}/otp_efuse_config.json')
|
|
copy_file(f'{CMAKE_BIN_DIR}/armino/partitions/_build/partitions_layout.txt', f'{CMAKE_INSTALL_DIR}/partitions_layout.txt')
|
|
copy_file(f'{bin_dir}/sdkconfig', f'{CMAKE_INSTALL_DIR}/sdkconfig')
|
|
|
|
if is_secure_boot == True:
|
|
pack_dir = f'{CMAKE_INSTALL_DIR}/pack'
|
|
os.makedirs(f'{pack_dir}', exist_ok=True)
|
|
copy_file(f'{_BUILD_DIR}/cpu0_app.bin', f'{pack_dir}/cpu0_app.bin')
|
|
copy_file(f'{_BUILD_DIR}/bl2.bin', f'{pack_dir}/bl2.bin')
|
|
copy_file(f'{_BUILD_DIR}/tfm_s.bin', f'{pack_dir}/tfm_s.bin')
|
|
copy_file(f'{_BUILD_DIR}/partitions.csv', f'{pack_dir}/partitions.csv')
|
|
copy_file(f'{_BUILD_DIR}/ota.csv', f'{pack_dir}/ota.csv')
|
|
copy_file(f'{_BUILD_DIR}/security.csv', f'{pack_dir}/security.csv')
|
|
copy_file(f'{_BUILD_DIR}/pack.json', f'{pack_dir}/pack.json')
|
|
copy_file(f'{CMAKE_INSTALL_DIR}/../armino/partitions/_build/ppc_config.bin', f'{pack_dir}/ppc_config.bin')
|
|
copy_files('.pem', _BUILD_DIR, pack_dir)
|
|
|
|
move_file('all-app.bin', _BUILD_DIR, CMAKE_BIN_DIR)
|
|
|
|
os.chdir(saved_cur_dir)
|
|
logging.debug(f'cd {saved_cur_dir}')
|
|
|
|
if is_secure_boot == False:
|
|
run_cmd_with_ret("python3 {}/tools/env_tools/rtt_ota/ota-rbl/ota_packager_python.py -i {} -o {} -g {} -ap {} -pjd {} packager".format(armino_path, f'{CMAKE_INSTALL_DIR}/app.bin', f'{bin_dir}/app_pack.rbl', header_path, armino_path, os.getenv("PROJECT_DIR")))
|
|
|
|
@click.group()
|
|
@click.version_option(version='1.0.0.0')
|
|
def wrapper():
|
|
"""Post-build scripts to pack the binaries."""
|
|
|
|
if armino_soc.endswith('_cp1') == False:
|
|
cpu1_armino_soc = armino_soc + '_cp1'
|
|
cpu1_build_path = build_path.replace(armino_soc, cpu1_armino_soc)
|
|
if os.path.exists(f'{cpu1_build_path}/app.bin'):
|
|
if is_secure_boot == True:
|
|
os.system(f'cp {cpu1_build_path}/app.bin {cpu1_bin}')
|
|
else:
|
|
os.system(f'cp {cpu1_build_path}/app.bin {nosecurity_cpu1_bin}')
|
|
|
|
@wrapper.command("pack")
|
|
@click.option("--prebuild/--no-prebuild", default=False, help="Whether it's post-build or pre-build")
|
|
def pack_bin(prebuild):
|
|
"""Pack armino binaries."""
|
|
if is_secure_boot == True or prebuild == True:
|
|
pack(prebuild)
|
|
else:
|
|
run_cmd("python3 %s -n all-app.bin -f app.bin -c %s"%(nosecurity_pack, armino_soc))
|
|
|
|
if __name__ == '__main__':
|
|
logging.basicConfig()
|
|
logging.getLogger().setLevel(logging.INFO)
|
|
wrapper()
|