# coding=UTF-8 #!/usr/bin/python import json import sys import getopt import os import glob import shutil import distutils.dir_util import subprocess import shlex import math import platform import re sys.path.append(os.path.join(os.path.dirname(__file__), "SSDKDS", "scripts","")) # from Kconfiglib.sdkconfig import SDKconfig global BPT_SZ BPT_SZ=0x1000 global XSPI1_MEM_BASE XSPI1_MEM_BASE = 0x10000000 global SP_EXIT global SX_EXIT global RAM_SIZE global RAM_BASE SP_EXIT = True SX_EXIT = True g_objEncryption=[] DEF_BOOT_SZ=0x400000 PAC_ALIGN=0x20000 def str_trans(input): if input == "true": return "1" else: return "0" def file_align(file_name, align_size): try: file_size = math.ceil(os.path.getsize(file_name) / align_size) * align_size fo = open(file_name, "r+") fo.truncate(file_size) fo.close() print("%s is aligned to 0x%x" %(file_name, align_size)) except Exception as e: raise Exception("getsize %s error:\n %s" %(file_name,e)) def pac_align(mem_offset, align_size): return math.ceil(mem_offset / align_size) * align_size def calc_dlp(mem_offset): return int(mem_offset/512) def try_copy(file, path): try: shutil.copy(file, path) except Exception as e: raise Exception("copy %s error:\n %s" %(file,e)) def is_taishan_l(chip_id): if chip_id == "E3104" or chip_id == "E3106" or chip_id == "E3205" or chip_id == "E3206": return True else: return False def get_default_chip_id_by_board(board_type): dict_tmp = {'d3_display':'D3248', 'd3_gateway':'D3248', 'e3_144_ref':'E3205', 'e3_176_ref':'E3110', 'e3_324_dev_kit':'E3640', 'e3_324_ref_display':'E3340', 'e3_display':'E3340', 'e3_gateway':'E3640'} return dict_tmp.get(board_type) def exe_pac(sf_only_mode, pac_type, BOARD, PROJECT, partition_mode, xip_mode, sec_ver, \ iib_str_list, sfs_name, msfs_name, sfs_list, boot0_addr, boot1_addr, boot2_addr, rfd_name, partition_file, \ fat32_file, key_str, boot_package_num, ctl_str, uuid_str, dloader_entry, other_file_list, ver): global g_objEncryption print("exe_pac_start") downloader_unsigned = ("downloader_%s.bin" % BOARD) downloader_signed = ("downloader_%s_signed.bin" % BOARD) output_pac = os.path.join(PAC_TEMP_PATH, ("%s_%s.pac" % (pac_type, BOARD))) #clean the env if os.path.exists(output_pac): os.remove(output_pac) os.chdir(os.path.join(PWD, "tools", "sdtools")) if DOWNLOADER_TYPE == "dloader": print("\n-----sign dloader key = %s:" % key_str) try: sign_dloader = ATB_SIGNER + " sign --v 2 --sec_ver %s --dgst sha256 %s \n--iib core=0 type=0x0 image=temp/%s to=%s entry=%s %s %s \n--psn 0x01 --of temp/%s" %(sec_ver, key_str, downloader_unsigned, dloader_entry, dloader_entry, ctl_str, uuid_str, downloader_signed) print(sign_dloader) args = shlex.split(sign_dloader) subprocess.run(args, check=True) except Exception as e: raise Exception("sign dloader error:\n %s" %e) else: shutil.copy(os.path.join(os.getcwd(), "temp", downloader_unsigned), os.path.join(os.getcwd(), "temp", downloader_signed)) ssdk_name=["ssdk_signed_normal.bin", "ssdk_signed_backup.bin", "ssdk_signed_third.bin"] boot_package_version = ver num = [0, 1, 2] for i in num: if i >= boot_package_num: break print("\n-----sign boot package %d key = %s:" % (num[i], key_str)) sign_boot_package = ATB_SIGNER + " sign --v 2 --sec_ver %s --dgst sha256 %s \n%s --psn %s --of temp/%s" %(sec_ver, key_str, iib_str_list[i], boot_package_version[i], ssdk_name[i]) print(sign_boot_package) try: args = shlex.split(sign_boot_package) subprocess.run(args, check=True) #Encrypte boot image if len(g_objEncryption) > 0 and \ g_objEncryption["encryption_on"] == "true" and \ i < len(g_objEncryption["rfd"]): strOriginalFile = ssdk_name[i] strEncryFile = ssdk_name[i] + ".sign" strEncrypteCmd = ATB_SIGNER + " xspi_enc " strKs = "" if "ks" in g_objEncryption: strKs = g_objEncryption["ks"] strEncrypteCmd += " ks={0} ".format(strKs) strPvkName = "" pvkName = ["pvk0", "pvk1", "pvk2", "pvk3"] for pvk in pvkName: if pvk in g_objEncryption["rfd"][i]: strPvkName = pvk break strKek = "" if "kek" in g_objEncryption["rfd"][i]: strKek = g_objEncryption["rfd"][i]["kek"] strIek = "" if "iek" in g_objEncryption["rfd"][i]: strIek = g_objEncryption["rfd"][i]["iek"] strIv = g_objEncryption["rfd"][i]["iv"] if strPvkName != "": strPvkVal = g_objEncryption["rfd"][i][strPvkName] strEncrypteCmd = strEncrypteCmd + " {0}={1} iv={2} " \ .format(strPvkName,strPvkVal,strIv) else: strEncrypteCmd = strEncrypteCmd + " iek={0} iv={1} " \ .format(strIek,strIv) pass strEncrypteCmd = strEncrypteCmd + " if=temp/{0} of=temp/{1}" \ .format(strOriginalFile , strEncryFile) print("Encryte Boot Image...") print(strEncrypteCmd) args = shlex.split(strEncrypteCmd) subprocess.run(args, check=True) ssdk_name[i] = strEncryFile file_align( ("temp/%s" %ssdk_name[i]), 4096) except Exception as e: raise Exception("sign boot package error:\n %s" %e) #gen sfs binary if pac_type == "ospi": # single sfs mode if msfs_name == "": print("\n-----gen_sfs_binary:") gen_sfs_binary = PYTHON + " pactool/gen_sfs_binary.py --json sfs/%s \n--out temp/sfs.img \n--normal_img_off %s \n--backup_img_off %s \n--third_img_off %s" %(sfs_name, boot0_addr, boot1_addr, boot2_addr) print(gen_sfs_binary) try: args = shlex.split(gen_sfs_binary) subprocess.run(args, check=True) out_sfs = "sfs.img" except Exception as e: raise Exception("gen_sfs_binary error:\n %s" %e) # multi-sfs mode elif msfs_name != "": print("\n-----gen_msfs_binary: step1") for sfs in sfs_list: print(sfs["name"]) gen_sfs_binary = PYTHON + " pactool/gen_sfs_binary.py --json sfs/%s \n--out temp/%s.img \n--normal_img_off %s \n--backup_img_off %s \n--third_img_off %s" %(sfs["name"], sfs["name"].split(".")[0], boot0_addr, boot1_addr, boot2_addr) print(gen_sfs_binary) try: args = shlex.split(gen_sfs_binary) subprocess.run(args, check=True) except Exception as e: raise Exception("gen_sfs_binary %s error:\n %s" %(sfs["name"], e)) print("\n-----gen_msfs_binary: step2") gen_msfs_binary = PYTHON + " pactool/msfstool.py make_msfs --output temp/%s "%msfs_name last_id = "" for sfs in sfs_list: if last_id == sfs["id"]: raise Exception("the id is same as last_id\n") gen_msfs_binary = gen_msfs_binary + " --image %s@temp/%s.img "%(sfs["id"], sfs["name"].split(".")[0]) print(gen_msfs_binary) try: args = shlex.split(gen_msfs_binary) subprocess.run(args, check=True) except Exception as e: raise Exception("gen_msfs_binary error:\n %s" %e) out_sfs = msfs_name else: raise Exception("gen sfs or msfs binary error\n") #gen pac if partition_mode == "0": print("\n-----generating PAC without parition : %s" % output_pac) if pac_type == "ospi": paccmd = PYTHON + " pactool/pactool make_pac_image_no_gpt \n" + \ ("--output pac/%s/%s/%s_%s.pac \n" % (BOARD, PROJECT, pac_type, BOARD)) + \ ("--allow_empty_partitions \n") + \ ("--preload sfs:temp/%s \n" % out_sfs) + \ ("--preload rfd:%s \n" % rfd_name) + \ ("--preload boot0:temp/%s \n" % ssdk_name[0]) + \ ("--da FDA:temp/%s \n" % downloader_signed) elif pac_type == "emmc": paccmd = PYTHON + " pactool/pactool make_pac_image_no_gpt \n" + \ ("--output pac/%s/%s/%s_%s.pac \n" % (BOARD, PROJECT, pac_type, BOARD)) + \ ("--allow_empty_partitions \n") + \ ("--preload boot0:temp/%s \n" % ssdk_name[0]) + \ ("--da FDA:temp/%s \n" % downloader_signed) if boot_package_num > 1: paccmd = paccmd +("--preload boot1:temp/%s \n" % ssdk_name[1]) if boot_package_num > 2: paccmd = paccmd +("--preload boot2:temp/%s \n" % ssdk_name[2]) if (other_file_list != "none"): for k in other_file_list: paccmd = paccmd +("--image %s:temp/%s \n" % (k, ("other_" + os.path.basename(other_file_list[k])))) try: args = shlex.split(paccmd) print(paccmd) subprocess.run(args, check=True) except Exception as e: raise Exception("generating PAC without parition error:\n %s" %e) else: print("\n-----generating PAC with parition : %s" % output_pac) bptcmd= PYTHON + " pactool/bpttool make_table \n" + \ ("--input bpt/%s --ab_suffixes \"_a,_b\" \n" % partition_file) + \ "--output_json temp/output.bpt \n" + \ "--output_gpt temp/partition.img \n" if pac_type == "ospi": paccmd = PYTHON + " pactool/pactool make_pac_image \n" + \ ("--input temp/output.bpt \n") + \ ("--output pac/%s/%s/%s_%s.pac \n" % (BOARD, PROJECT, pac_type, BOARD)) + \ ("--image boot0:temp/%s \n" % ssdk_name[0]) +\ ("--allow_empty_partitions \n") +\ ("--preload sfs:temp/%s \n" % out_sfs) +\ ("--preload rfd:%s \n" % rfd_name) +\ ("--da FDA:temp/%s \n" % downloader_signed) if boot_package_num > 1: paccmd = paccmd + ("--image boot1:temp/%s \n" % ssdk_name[1]) if boot_package_num > 2: paccmd = paccmd + ("--image boot2:temp/%s \n" % ssdk_name[2]) else: paccmd = PYTHON + " pactool/pactool make_pac_image \n" + \ ("--input temp/output.bpt \n") + \ ("--output pac/%s/%s/%s_%s.pac \n" % (BOARD, PROJECT, pac_type, BOARD)) + \ ("--preload boot0:temp/%s \n" % ssdk_name[0]) + \ ("--allow_empty_partitions \n") + \ ("--da FDA:temp/%s \n" % downloader_signed) if boot_package_num > 1: paccmd = paccmd + ("--preload boot1:temp/%s \n" % ssdk_name[1]) if boot_package_num > 2: paccmd = paccmd + ("--image boot2:temp/%s \n" % ssdk_name[2]) try: b = open(os.path.join(SDTOOLS, "bpt", partition_file)) bptfile = json.load(b) partitions = bptfile["partitions"] for pt_inst in partitions : label = pt_inst["label"] if label == "boot0" or label == "boot1" or label == "boot2": continue elif label == "res": paccmd = paccmd + "--image res:temp/%s \n" %(fat32_file) else: for files in glob.glob(os.path.join(TEMP_PATH, "*")): name_temp = os.path.basename(files) if name_temp == label: paccmd = paccmd + "--image %s:temp/%s \n" % (label,label) elif name_temp == (label +".bin"): paccmd = paccmd + "--image %s:temp/%s.bin \n" % (label,label) elif name_temp == (label +".img"): paccmd = paccmd + "--image %s:temp/%s.img \n" % (label,label) except Exception as e: raise Exception("read temp/output.bpt error: %s", e) try: args = shlex.split(bptcmd) print(bptcmd) subprocess.run(args, check=True) except Exception as e: raise Exception("make parition table error:\n %s" %e) try: args = shlex.split(paccmd) print(paccmd) subprocess.run(args, check=True) except Exception as e: raise Exception("generating PAC with parition error:\n %s" %e) os.chdir(PWD) try_copy(os.path.join(PAC_TEMP_PATH, "%s_%s.pac" % (pac_type, BOARD)), PAC_PTAH) print("exe_pac_end, pac path is %s" %(os.path.join(PAC_PTAH,"%s_%s.pac" % (pac_type, BOARD)))) def gen_pac(board_name, project_name, json_cfg, downloader): global g_objEncryption global RAM_SIZE global SX_EXIT global SP_EXIT global DOWNLOADER_TYPE flash_type = "none" if "pac" in json_cfg: pac = json_cfg.get("pac") for pac_inst in pac : if DOWNLOADER_TYPE == "none": DOWNLOADER_TYPE = pac_inst.get("downloader_type", "dloader") if downloader == "from_prebuild": flash_type = pac_inst.get("flash_type", "hyperflash") if DOWNLOADER_TYPE == "dloader": downloader = os.path.join(DEVICES_PATH, CHIP_ID, DOWNLOADER_TYPE, ("%s_%s.bin" % (board_name, flash_type))) else: downloader = os.path.join(DEVICES_PATH, CHIP_ID, DOWNLOADER_TYPE, ("%s_%s.out" % (DOWNLOADER_TYPE, flash_type))) if QUERY_MODE == 0: # copy downloader binary try_copy(downloader, os.path.join(BIN_PATH, ("downloader_%s.bin" % board_name))) # copy FAT image for fat in glob.glob(fat_file): try_copy(fat, BIN_PATH) # copy other binaries for other in glob.glob(other_file): try_copy(other, BIN_PATH) # copy bin dir to temp dir for files in glob.glob(os.path.join(BIN_PATH, "*")): try_copy(files, TEMP_PATH) try: pac_type = pac_inst["type"] except: raise Exception("can not find [pac]-[type] in [%s] please check json file" %pac_json) if pac_type == "emmc" and DOWNLOADER_TYPE == "flashloader": sys.exit() print("\n****************************************gen pac for %s************************************************\n " % pac_type) try: sfs = pac_inst["sfs"] sfs_name = sfs["name"] boot0_addr = sfs["boot0_addr"] boot1_addr = sfs["boot1_addr"] boot2_addr = sfs["boot2_addr"] msfs_name = "" sfs_list = "" except: if pac_type == "ospi": try: msfs = pac_inst["msfs"] msfs_name = msfs["name"] sfs_list = msfs["sfs_list"] boot0_addr = msfs["boot0_addr"] boot1_addr = msfs["boot1_addr"] boot2_addr = msfs["boot2_addr"] sfs_name = "" except: raise Exception("Error in [%s] 's sfs, please check json file" % pac_json) else: sfs_name = "mt35-1-1-1.json" boot0_addr = "0x7000" boot1_addr = "0x207000" boot2_addr = "0x407000" msfs_name = "" sfs_list = "" boot0_end = 0x0 boot1_end = 0x0 boot2_end = 0x0 if boot1_addr == "": boot0_end = int(boot0_addr,16) + int(DEF_BOOT_SZ,16) else: boot0_end = int(boot1_addr,16) if boot2_addr == "": boot1_end = int(boot1_addr,16) + int(boot1_addr, 16) - int(boot0_addr) else: boot1_end = int(boot2_addr,16) boot2_end = int(boot2_addr, 16) + int(boot2_addr, 16) - int(boot1_addr,16) boot_region = [{"start":int(boot0_addr,16), "end":boot0_end},{"start":int(boot1_addr,16), "end":boot1_end},{"start":int(boot2_addr,16), "end":boot2_end}] #Read Encryption configuration strNewRfd="" if "encryption" in pac_inst: g_objEncryption = pac_inst["encryption"] print("Begin to creating rfd image..."+g_objEncryption["encryption_on"]) if g_objEncryption["encryption_on"] == "true": print("Begin to creating rfd image...") strRfdCmd = "" strSrkKey = "" if "srk" in g_objEncryption: strSrkKey = g_objEncryption["srk"] strKs = "" if "ks" in g_objEncryption: strKs = g_objEncryption["ks"] objRfdArray = g_objEncryption["rfd"] strRfdCmd = " xspi_wrap " if strSrkKey != "": strRfdCmd += " srk=" + strSrkKey if strKs != "": strRfdCmd += " ks=" + strKs print("strRfdCmd:"+strRfdCmd) rfdIdx = 0 for objRfd in objRfdArray: strCurRfdCmd="" strKek = "" if "kek" in objRfd: strKek = objRfd["kek"] strIek = "" if "iek" in objRfd: strIek = objRfd["iek"] strIv = objRfd["iv"] strStart = objRfd["start"] strEnd = objRfd["end"] strPvk = "" pvkName = ["pvk0", "pvk1", "pvk2", "pvk3"] for pvk in pvkName: if pvk in objRfd: strPvk = pvk break if "boot" in objRfd and objRfd["boot"] == "true": if boot_region[rfdIdx]["start"] != int(strStart, 16) or boot_region[rfdIdx]["end"] != int(strEnd, 16): print("rfd:"+str(rfdIdx)+" region addr is not match sfs!") print("rfd start:" + strStart + " rfd end:"+ strEnd) print("boot start:%#x"%boot_region[rfdIdx]["start"] + " boot end:%#x"%boot_region[rfdIdx]["end"]) exit() if strPvk != "": strPvkVal = objRfd[strPvk] strCurRfdCmd = " --rfd {0}={1} iv={2} start={3} end={4} "\ .format(strPvk,strPvkVal,strIv,strStart,strEnd) pass else: strCurRfdCmd = " --rfd kek={0} iek={1} iv={2} start={3} end={4} "\ .format(strKek,strIek,strIv,strStart,strEnd) pass rfdIdx += 1 strRfdCmd = strRfdCmd + strCurRfdCmd strNewRfd="temp/new.rfd" os.chdir(os.path.join(os.getcwd(),"tools", "sdtools")) strRfdCmd = ATB_SIGNER + strRfdCmd + " of=" + strNewRfd print("Generate RFD Command:") print(strRfdCmd) args = shlex.split(strRfdCmd) subprocess.run(args, check=True) os.chdir(PWD) else: print("No Encryption configuration,Skip...") g_objEncryption = [] xip_mode = str_trans(pac_inst.get("xip_mode", "false")) partition_mode = str_trans(pac_inst.get("partition", "false")) sf_only_mode = str_trans(pac_inst.get("sf_only_mode", "false")) partition_file = pac_inst.get("partition_file", "none") sec_ver = pac_inst.get("sec_ver", "0") rfd_name = pac_inst.get("rfd_name", "xspi_wrap_rfd_blk_pvk1_ks.rfd") fat32_file = pac_inst.get("fat32_file", "fat.img") key = pac_inst.get("key", "none") ctl = pac_inst.get("ctl", "none") uuid = pac_inst.get("uuid", "none") dloader_entry = pac_inst.get("dloader_entry", "0x404000") ver0 = pac_inst.get("ver0", "0x100") ver1 = pac_inst.get("ver1", "0x100") ver2 = pac_inst.get("ver2", "0x100") ver = [ver0, ver1, ver2] if strNewRfd == "": rfd_name = "rfd/" + rfd_name else: rfd_name = strNewRfd if key != "none": key_str = "--rcp key=sign_tool/keys/%s" % key else: key_str = " " if ctl != "none": ctl_str = "ctl=%s" % ctl else: ctl_str = " " if uuid != "none": uuid_str = "uuid=%s" % uuid else: uuid_str = " " boot_package_num = int(pac_inst.get("boot_package_num", "3")) if (boot_package_num > 3) or (boot_package_num <= 0): boot_package_num = 3 if boot_package_num == 1: boot1_addr = "0x0" boot2_addr = "0x0" if boot_package_num == 2: boot2_addr = "0x0" if pac_type != "ospi": xip_mode = "0" if sf_only_mode == "1": partition_mode = "1" if partition_file == "none": raise Exception("partition_file is none in [%s] please check json file" %pac_json) try: core = pac_inst["core"] iib_str_list = [] bootloader_mode = str_trans(core.get("bootloader_mode", "false")) if bootloader_mode == "1": try_copy(bootloader, os.path.join(BIN_PATH, "bootloader.bin")) try_copy(bootloader, os.path.join(TEMP_PATH, "bootloader.bin")) if QUERY_MODE == 0: SF_ALIGN = int(core.get("sf_pad_size", "0x1000"),16) SP0_ALIGN = int(core.get("sp0_pad_size", "0x1000"),16) SP1_ALIGN = int(core.get("sp1_pad_size", "0x1000"),16) SX0_ALIGN = int(core.get("sx0_pad_size", "0x1000"),16) SX1_ALIGN = int(core.get("sx1_pad_size", "0x1000"),16) BOOTLOADER_ALIGN = int(core.get("bootloader_pad_size", "0x1000"),16) #pad the bin for files in glob.glob(os.path.join(TEMP_PATH, "*")): if os.path.basename(files) == "sf.bin" and SF_ALIGN!= 0: file_align(files, SF_ALIGN) elif os.path.basename(files) == "sp0.bin" and SP0_ALIGN!= 0: file_align(files, SP0_ALIGN) elif os.path.basename(files) == "sp1.bin" and SP1_ALIGN!= 0: file_align(files, SP1_ALIGN) elif os.path.basename(files) == "sx0.bin" and SX0_ALIGN!= 0: file_align(files, SX0_ALIGN) elif os.path.basename(files) == "sx1.bin" and SX1_ALIGN!= 0: file_align(files, SX1_ALIGN) elif os.path.basename(files) == "bootloader.bin" and BOOTLOADER_ALIGN!= 0: file_align(files, BOOTLOADER_ALIGN) num = [0, 1, 2] membase = 0 memsize = 0 pacoffset = 0 dlp = 0 if pac_type == "ospi": boot_addr_array = [int(boot0_addr,16), int(boot1_addr,16), int(boot2_addr,16)] for i in num: # sf iib str if i >= boot_package_num: break if os.path.exists(os.path.join(TEMP_PATH, "sf.bin")) == False: if QUERY_MODE == 1: sys.exit(1) raise Exception("can not find sf.bin in %s" % os.path.join(TEMP_PATH, "sf.bin")) pacoffset = BPT_SZ if xip_mode == "0": membase = int(core.get("sf_entry", "0x404000"), 16) memsize = os.path.getsize(os.path.join(TEMP_PATH, "sf.bin")) if ((membase > (RAM_SIZE + RAM_BASE)) or ((membase + memsize) > (RAM_SIZE + RAM_BASE))): print("membase 0x%x or memsize 0x%x exceed the limit size 0x%x\n" %(membase, memsize, (RAM_SIZE + RAM_BASE))) sys.exit(1) else: xipbase = XSPI1_MEM_BASE + boot_addr_array[i] membase = xipbase + pacoffset memsize = os.path.getsize(os.path.join(TEMP_PATH, "sf.bin")) dlp = calc_dlp(pacoffset) pacoffset = pac_align((pacoffset + memsize), PAC_ALIGN) iib_str = "--iib core=0 type=0x0 image=temp/sf.bin dlp=0x%x to=0x%x entry=0x%x %s %s \n" % (dlp, membase, membase, ctl_str, uuid_str) if sf_only_mode == "0": core_sx_mode = core.get("sx_mode", "None") core_sp_mode = core.get("sp_mode", "None") if (core_sp_mode == "split" or core_sp_mode == "lockstep") and (SP_EXIT == True): if os.path.exists(os.path.join(TEMP_PATH, "sp0.bin")) == False: if QUERY_MODE == 1: print("can't find sp0.bin\n") sys.exit(1) raise Exception("can not find sp0.bin in %s" % os.path.join(TEMP_PATH, "sp0.bin")) if xip_mode == "0": membase = int(core.get("sp0_entry", "0x600000"), 16) memsize = os.path.getsize(os.path.join(TEMP_PATH, "sp0.bin")) if ((membase > (RAM_SIZE + RAM_BASE)) or ((membase + memsize) > (RAM_SIZE + RAM_BASE))): print("membase 0x%x or memsize 0x%x exceed the limit size 0x%x\n" %(membase, memsize, (RAM_SIZE + RAM_BASE))) sys.exit(1) else: membase = xipbase + pacoffset memsize = os.path.getsize(os.path.join(TEMP_PATH, "sp0.bin")) dlp = calc_dlp(pacoffset) pacoffset = pac_align((pacoffset + memsize), PAC_ALIGN) if core_sp_mode == "lockstep": iib_str += "--iib core=7 type=0x0 image=temp/sp0.bin dlp=0x%x to=0x%x entry=0x%x \n" % (dlp, membase, membase) else: iib_str += "--iib core=2 type=0x0 image=temp/sp0.bin dlp=0x%x to=0x%x entry=0x%x \n" % (dlp, membase, membase) if os.path.exists(os.path.join(TEMP_PATH, "sp1.bin")) == False: if QUERY_MODE == 1: print("can't find sp1.bin\n") sys.exit(1) raise Exception("can not find sp1.bin in %s" % os.path.join(TEMP_PATH, "sp1.bin")) if xip_mode == "0": membase = int(core.get("sp1_entry", "0x680000"), 16) memsize = os.path.getsize(os.path.join(TEMP_PATH, "sp1.bin")) if ((membase > (RAM_SIZE + RAM_BASE)) or ((membase + memsize) > (RAM_SIZE + RAM_BASE))): print("membase 0x%x or memsize 0x%x exceed the limit size 0x%x\n" %(membase, memsize, (RAM_SIZE + RAM_BASE))) sys.exit(1) else: membase = xipbase + pacoffset memsize = os.path.getsize(os.path.join(TEMP_PATH, "sp1.bin")) dlp = calc_dlp(pacoffset) pacoffset = pac_align((pacoffset + memsize), PAC_ALIGN) iib_str += "--iib core=3 type=0x0 image=temp/sp1.bin dlp=0x%x to=0x%x entry=0x%x \n" % (dlp, membase, membase) if (core_sx_mode == "split" or core_sx_mode == "lockstep") and (SX_EXIT == True): if os.path.exists(os.path.join(TEMP_PATH, "sx0.bin")) == False: if QUERY_MODE == 1: print("can't find sx0.bin\n") sys.exit(1) raise Exception("can not find sx0.bin in %s" % os.path.join(TEMP_PATH, "sx0.bin")) if xip_mode == "0": membase = int(core.get("sx0_entry", "0x500000"), 16) memsize = os.path.getsize(os.path.join(TEMP_PATH, "sx0.bin")) if ((membase > (RAM_SIZE + RAM_BASE)) or ((membase + memsize) > (RAM_SIZE + RAM_BASE))): print("membase 0x%x or memsize 0x%x exceed the limit size 0x%x\n" %(membase, memsize, (RAM_SIZE + RAM_BASE))) sys.exit(1) else: membase = xipbase + pacoffset memsize = os.path.getsize(os.path.join(TEMP_PATH, "sx0.bin")) dlp = calc_dlp(pacoffset) pacoffset = pac_align((pacoffset + memsize), PAC_ALIGN) if core_sx_mode == "lockstep": iib_str += "--iib core=6 type=0x0 image=temp/sx0.bin dlp=0x%x to=0x%x entry=0x%x \n" % (dlp, membase, membase) else: iib_str += "--iib core=4 type=0x0 image=temp/sx0.bin dlp=0x%x to=0x%x entry=0x%x \n" % (dlp, membase, membase) if os.path.exists(os.path.join(TEMP_PATH, "sx1.bin")) == False: if QUERY_MODE == 1: print("can't find sx1.bin\n") sys.exit(1) raise Exception("can not find sx1.bin in %s" % os.path.join(TEMP_PATH, "sx1.bin")) if xip_mode == "0": membase = int(core.get("sx1_entry", "0x580000"), 16) memsize = os.path.getsize(os.path.join(TEMP_PATH, "sx1.bin")) if ((membase > (RAM_SIZE + RAM_BASE)) or ((membase + memsize) > (RAM_SIZE + RAM_BASE))): print("membase 0x%x or memsize 0x%x exceed the limit size 0x%x\n" %(membase, memsize, (RAM_SIZE + RAM_BASE))) sys.exit(1) else: membase = xipbase + pacoffset memsize = os.path.getsize(os.path.join(TEMP_PATH, "sx1.bin")) dlp = calc_dlp(pacoffset) pacoffset = pac_align((pacoffset + memsize), PAC_ALIGN) iib_str += "--iib core=5 type=0x0 image=temp/sx1.bin dlp=0x%x to=0x%x entry=0x%x \n" % (dlp, membase, membase) elif QUERY_MODE == 1: try: b = open(os.path.join(SDTOOLS, "bpt", partition_file)) bptfile = json.load(b) partitions = bptfile["partitions"] for pt_inst in partitions : label = pt_inst["label"] if (label == "sp0") and (os.path.exists(os.path.join(TEMP_PATH, "sp0.bin")) == False): print("can't find sp0.bin\n") sys.exit(1) if (label == "sp1") and (os.path.exists(os.path.join(TEMP_PATH, "sp1.bin")) == False): print("can't find sp1.bin\n") sys.exit(1) if (label == "sx0") and (os.path.exists(os.path.join(TEMP_PATH, "sx0.bin")) == False): print("can't find sx0.bin\n") sys.exit(1) if (label == "sx1") and (os.path.exists(os.path.join(TEMP_PATH, "sx1.bin")) == False): print("can't find sx1.bin\n") sys.exit(1) except Exception as e: raise Exception("qurey mode read partition bpt file error: %s", e) if bootloader_mode == "1": if os.path.exists(os.path.join(TEMP_PATH, "bootloader.bin")) == False : if QUERY_MODE == 1: sys.exit(1) raise Exception("can not find bootloader.bin in %s" % os.path.join(TEMP_PATH, "bootloader.bin")) membase = int(core.get("bootloader_entry", "0x404000"), 16) dlp = calc_dlp(pacoffset) iib_str += "--iib core=0 type=0xf image=temp/bootloader.bin dlp=0x%x to=0x%x entry=0x%x \n" % (dlp, membase, membase) iib_str_list.append(iib_str) #print(iib_str_list[i]) except Exception as e: raise Exception("parse project:[%s] 's core setup error:\n %s" % (project_name, e)) other_file_list = pac_inst.get("other_file", "none") if (other_file_list != "none"): print("find other file!\n") for k in other_file_list: if (os.path.basename(other_file_list[k]) != other_file_list[k]): print("copy %s to %s" %(other_file_list[k], os.path.join(TEMP_PATH, "other_" + os.path.basename(other_file_list[k])))) try_copy(other_file_list[k], os.path.join(TEMP_PATH, "other_" + os.path.basename(other_file_list[k]))) try: if QUERY_MODE == 0: exe_pac(sf_only_mode, pac_type , board_name, project_name, partition_mode, xip_mode, sec_ver, iib_str_list, sfs_name, msfs_name, sfs_list, \ boot0_addr, boot1_addr, boot2_addr, rfd_name, partition_file, fat32_file, key_str, boot_package_num, ctl_str, uuid_str, dloader_entry, other_file_list, \ ver) except Exception as e: raise Exception("exe_pac error:\n %s" %e) else: raise Exception("can not find 'pac' in json %s, please check" %json_cfg) def get_part_info(part_info, chip_id_input): print("start to get_part_info") part_num = 0 global RAM_SIZE global SX_EXIT global SP_EXIT for chipid in part_info: if(chipid == "reserve"): print("can't chip id %s in part.json\n", chip_id_input) sys.exit(1) if(chipid != chip_id_input): continue part_num = part_num + 1 core_num = 1 sx_exist = False sp_exist = False chip_info = part_info[chipid] config_sx = chip_info["CONFIG_SX"] config_sp = chip_info["CONFIG_SP"] ram_size_str = chip_info["RAM_SIZE"] size_value = int(re.search("([0-9]+)", ram_size_str).group(1)) size_unit = re.search("([a-zA-Z]+)", ram_size_str).group(1) if size_unit == "KB": RAM_SIZE = size_value * 1024 else: RAM_SIZE = size_value * 1024 * 1024 if config_sx == 1: SX_EXIT = True else: SX_EXIT = False if config_sp == 1: SP_EXIT = True else: SP_EXIT = False print('part_num: %d' %part_num) print('chipid: %s' %chipid) print('ram_size: %#x' %RAM_SIZE) print('sp_exist: %d' %SP_EXIT) print('sx_exist: %d' %SX_EXIT) break class LazyDecoder(json.JSONDecoder): def decode(self, s, **kwargs): regex_replacements = [ (re.compile(r'([^\\])\\([^\\])'), r'\1\\\\\2'), (re.compile(r',(\s*])'), r'\1'), ] for regex, replacement in regex_replacements: s = regex.sub(replacement, s) return super().decode(s, **kwargs) if __name__ == "__main__": QUERY_MODE = 0 CONFIG_NAME = "Debug" CHIP_ID = "none" PAC_ONLY_BY_FILE = False PAC_CONFIG_FILE_NAME = "none" downloader = "from_prebuild" BOARD = "none" PROJECT = "none" TOOLCHAIN = "IAR" PROJECT_PATH = "none" DOWNLOADER_TYPE = "none" try: opts, args = getopt.getopt(sys.argv[1:], '-b:-p:-v:-q-c:-f:-d:',['chipid=']) except Exception as e: print("get opt error:\n %s" % e) sys.exit(-1) for opt_name, opt_value in opts: if opt_name in ('-b', '--board'): BOARD = opt_value os.environ['BOARD'] = opt_value print("BOARD is %s" % BOARD) if opt_name in ('-p', '--project'): PROJECT = opt_value os.environ['PROJECT'] = opt_value print("PROJECT is %s" % PROJECT) if opt_name in ('-v', '--version'): TOOLCHAIN = opt_value if TOOLCHAIN == "GCC": TOOLCHAIN = "Eclipse" print("TOOLCHAIN is %s" % TOOLCHAIN) if opt_name in ('-q', '--query'): QUERY_MODE = 1 print("QUERY_MODE=%d" % QUERY_MODE) if opt_name in ('-c', '--config'): CONFIG_NAME = opt_value print("CONFIG_NAME is %s" % CONFIG_NAME) if opt_name in ('-f', '--file'): PAC_ONLY_BY_FILE = True PAC_CONFIG_FILE_NAME = opt_value print("pacfile is %s" % PAC_CONFIG_FILE_NAME) try: f = open(PAC_CONFIG_FILE_NAME) except: raise("Can not find %s" % PAC_CONFIG_FILE_NAME) json_cfg = json.load(f, cls=LazyDecoder) description = json_cfg.get("description", "e3 pac json file") print("description is " + description) if "board" in json_cfg: BOARD = json_cfg.get("board") print("BOARD is %s" % BOARD) if "project" in json_cfg: PROJECT = json_cfg.get("board") print("PROJECT is %s" % PROJECT) if "sf_path" not in json_cfg: PAC_ONLY_BY_FILE = False if opt_name == ('--chipid'): CHIP_ID = opt_value print("CHIP_ID is %s" % CHIP_ID) part_file = os.path.join(os.getcwd(), "tools", "sdtools", "part", "part.json") try: part_cfg = open(part_file, "r", encoding="utf-8") except Exception as e: print("open part file %s failed:\n %s" %(part_file,e)) sys.exit(-1) try: part_info = json.load(part_cfg) except Exception as e: print("parse part file %s failed:\n %s" %(part_file,e)) sys.exit(-1) get_part_info(part_info, CHIP_ID) if opt_name in ('-d', '--downloader_type'): DOWNLOADER_TYPE = opt_value os.environ['DOWNLOADER_TYPE'] = opt_value print("DOWNLOADER_TYPE is %s" % DOWNLOADER_TYPE) if BOARD == "none" or PROJECT == "none": print("Must specify BOARD or PROJECT") sys.exit(-1) if CHIP_ID == "none": CHIP_ID = get_default_chip_id_by_board(BOARD) taishan_l_flag = is_taishan_l(CHIP_ID) if taishan_l_flag: RAM_BASE = 0x500000 else: RAM_BASE = 0x400000 RAM_SIZE = 0x400000 PWD = os.path.join(os.getcwd()) SDTOOLS = os.path.join(os.getcwd(), "tools", "sdtools") PREBUILD_PATH = os.path.join(os.getcwd(), "prebuilts") BUILD_PATH = os.path.join(os.getcwd(), "boards", BOARD) TEMP_PATH = os.path.join(SDTOOLS, "temp") BIN_PATH = os.path.join(SDTOOLS, "bin") PAC_TEMP_PATH = os.path.join(SDTOOLS, "pac", BOARD, PROJECT) fat_file = os.path.join(PREBUILD_PATH, "fat", "*") other_file = os.path.join(PREBUILD_PATH, "other", "*") DEVICES_PATH = os.path.join(os.getcwd(), "devices") sysstr = platform.system() if sysstr =="Windows": PYTHON = "../../prebuilts/windows/python-3.7.0/python.exe " ATB_SIGNER = "./sign_tool/windows/atb_signer.exe" print ("Call Windows tasks") else: PYTHON = "python3 " ATB_SIGNER = "./sign_tool/linux/atb_signer" print ("Call Linux tasks") shutil.rmtree(TEMP_PATH, ignore_errors=True) shutil.rmtree(BIN_PATH, ignore_errors=True) os.makedirs(PAC_TEMP_PATH, exist_ok=True) os.makedirs(TEMP_PATH, exist_ok=True) os.makedirs(BIN_PATH, exist_ok=True) if(PAC_ONLY_BY_FILE == False): if PAC_CONFIG_FILE_NAME == "none": print ("Must select a pac config file, eg: -f devices\E3640\pac_config_sf.json") sys.exit(-1) pac_json = PAC_CONFIG_FILE_NAME if os.path.exists(pac_json) == False: print ("pac config file %s not exist." % pac_json) sys.exit(-1) for project_path in glob.glob(os.path.join(os.getcwd(), "boards", BOARD, "**", PROJECT), recursive=True): PROJECT_PATH = os.path.abspath(project_path) if PROJECT_PATH == "none": print ("can not find the project path") sys.exit(-1) print("gen pac for board=%s, project=%s toolchain=%s project_path =%s" % (BOARD, PROJECT, TOOLCHAIN, PROJECT_PATH)) # 单核 if os.path.exists(os.path.join(PROJECT_PATH, TOOLCHAIN)) == True: if TOOLCHAIN == "IAR": ssdk_bin_file = os.path.join(PROJECT_PATH, "IAR", CONFIG_NAME, "Exe", "*.bin") elif TOOLCHAIN == "SES": ssdk_bin_file = os.path.join(PROJECT_PATH, "SES", "Output", CONFIG_NAME, "Exe", "*.bin") else: ssdk_bin_file = os.path.join(PROJECT_PATH, "Eclipse", CONFIG_NAME, "*.bin") # 多核 else: if TOOLCHAIN == "IAR": ssdk_bin_file = os.path.join(PROJECT_PATH, "*", "IAR", CONFIG_NAME, "Exe", "*.bin") elif TOOLCHAIN == "SES": ssdk_bin_file = os.path.join(PROJECT_PATH, "*", "SES", "Output", CONFIG_NAME, "Exe", "*.bin") else: ssdk_bin_file = os.path.join(PROJECT_PATH, "*", "Eclipse", CONFIG_NAME, "*.bin") # copy core binaries to bin dir for bin in glob.glob(ssdk_bin_file): try_copy(bin, BIN_PATH) print("\ncopy %s to %s" %(bin, BIN_PATH)) print("Generate PAC according to %s" % pac_json) try: f = open(pac_json) except: raise("Can not find %s" % pac_json) json_cfg = json.load(f) description = json_cfg.get("description", "e3 pac json file") print("description is " + description) PAC_PTAH = os.path.join(PROJECT_PATH) else: print("Generate PAC according to %s" % PAC_CONFIG_FILE_NAME) if "sf_path" in json_cfg: sf_path = json_cfg.get("sf_path") try_copy(sf_path, os.path.join(BIN_PATH, "sf.bin")) print("sf file is %s" % sf_path) else: print("must have a sf file:\n %s") sys.exit(-1) if "sp0_path" in json_cfg: sp0_path = json_cfg.get("sp0_path") try_copy(sp0_path, os.path.join(BIN_PATH, "sp0.bin")) print("sp0 file is %s" % sp0_path) if "sp1_path" in json_cfg: sp1_path = json_cfg.get("sp1_path") try_copy(sp1_path, os.path.join(BIN_PATH, "sp1.bin")) print("sp1 file is %s" % sp1_path) if "sx0_path" in json_cfg: sx0_path = json_cfg.get("sx0_path") try_copy(sx0_path, os.path.join(BIN_PATH, "sx0.bin")) print("sx0 file is %s" % sx0_path) if "sx1_path" in json_cfg: sx1_path = json_cfg.get("sx1_path") try_copy(sx1_path, os.path.join(BIN_PATH, "sx1.bin")) print("sx1 file is %s" % sx1_path) if "bootloader_path" in json_cfg: bootloader_path = json_cfg.get("bootloader_path") try_copy(bootloader_path, os.path.join(BIN_PATH, "bootloader.bin")) print("bootloader file is %s" % bootloader_path) if "downloader_path" in json_cfg: downloader_path = json_cfg.get("downloader_path") try_copy(downloader_path, os.path.join(BIN_PATH, "downloader.bin")) print("downloader file is %s" % downloader_path) downloader = downloader_path #output file path PAC_PTAH = os.path.dirname(os.path.abspath(PAC_CONFIG_FILE_NAME)) try: gen_pac(BOARD, PROJECT, json_cfg, downloader) except Exception as e: print("gen_pac error:\n %s" % e) sys.exit(-1)