bl_iot_sdk/image_conf/flash_build.py
serv-inc a0fbac10ef chore: chmod flash_build.py
- to enable calling like ./flash_build.py
2020-10-30 20:48:36 +01:00

1459 lines
57 KiB
Python
Executable File

#! /usr/bin/env python3
# -*- coding:utf-8 -*-
import os
import sys
import fdt
import struct
import shutil
import binascii
import hashlib
import lzma
import toml
import itertools
import bootheader_cfg_keys as B_CFG_KEYS
import efuse_cfg_keys as E_CFG_KEYS
from configobj import ConfigObj
from Cryptodome.Hash import SHA256
app_path = ""
chip_name = ""
bl_factory_params_file_prefix = 'bl_factory_params_'
bin_build_out_path = "build_out"
default_conf_path = ""
efuse_mask_file = ""
efuse_file = ""
eflash_loader_cfg_org = ""
eflash_loader_cfg = ""
dict_xtal = {"24M": 1, "32M": "2", "38.4M": "3", "40M": "4", "26M": "5", "RC32M": "6"}
def bl_find_file_list(key_val, endswith):
file_path_list = []
conf_path = os.path.join(app_path, "img_conf")
if os.path.exists(conf_path):
files = os.listdir(conf_path)
for f in files:
if key_val in f and f.endswith(endswith):
find_file = os.path.join(conf_path, f)
file_path_list.append(find_file)
# return find_file
if file_path_list != []:
return file_path_list
conf_path = os.path.join(os.path.abspath('..'), "image_conf", default_conf_path)
files = os.listdir(conf_path)
for f in files:
if key_val in f and f.endswith(endswith):
find_file = os.path.join(conf_path, f)
file_path_list.append(find_file)
# return find_file
return file_path_list
def bl_find_file(key_val, endswith):
conf_path = os.path.join(app_path, "img_conf")
if os.path.exists(conf_path):
files = os.listdir(conf_path)
for f in files:
if key_val in f and f.endswith(endswith):
find_file = os.path.join(conf_path, f)
return find_file
conf_path = os.path.join(os.path.abspath('..'), "image_conf", default_conf_path)
files = os.listdir(conf_path)
for f in files:
if key_val in f and f.endswith(endswith):
find_file = os.path.join(conf_path, f)
return find_file
class bl_efuse_boothd_gen():
def __init__(self):
self.utils = bl_utils()
def bootheader_update_flash_pll_crc(self, bootheader_data):
flash_cfg_start = 8
flash_cfg_len = 4 + 84 + 4
# magic+......+CRC32
flash_cfg = bootheader_data[flash_cfg_start + 4:flash_cfg_start + flash_cfg_len - 4]
crcarray = self.utils.get_crc32_bytearray(flash_cfg)
bootheader_data[flash_cfg_start + flash_cfg_len - 4:flash_cfg_start + flash_cfg_len] = crcarray
pll_cfg_start = flash_cfg_start + flash_cfg_len
pll_cfg_len = 4 + 8 + 4
# magic+......+CRC32
pll_cfg = bootheader_data[pll_cfg_start + 4:pll_cfg_start + pll_cfg_len - 4]
crcarray = self.utils.get_crc32_bytearray(pll_cfg)
bootheader_data[pll_cfg_start + pll_cfg_len - 4:pll_cfg_start + pll_cfg_len] = crcarray
return bootheader_data
def get_int_mask(self, pos, length):
ones = "1" * 32
zeros = "0" * 32
mask = ones[0:32 - pos - length] + zeros[0:length] + ones[0:pos]
return int(mask, 2)
def update_data_from_cfg(self, config_keys, config_file, section):
cfg = BFConfigParser()
cfg.read(config_file)
# get finally data len
filelen = 0
for key in config_keys:
offset = int(config_keys.get(key)["offset"], 10)
if offset > filelen:
filelen = offset
filelen += 4
data = bytearray(filelen)
data_mask = bytearray(filelen)
for key in cfg.options(section):
if config_keys.get(key) == None:
print(key + " not exist")
continue
val = cfg.get(section, key)
if val.startswith("0x"):
val = int(val, 16)
else:
val = int(val, 10)
offset = int(config_keys.get(key)["offset"], 10)
pos = int(config_keys.get(key)["pos"], 10)
bitlen = int(config_keys.get(key)["bitlen"], 10)
oldval = self.utils.bytearray_to_int(self.utils.bytearray_reverse(data[offset:offset + 4]))
oldval_mask = self.utils.bytearray_to_int(self.utils.bytearray_reverse(data_mask[offset:offset + 4]))
newval = (oldval & self.get_int_mask(pos, bitlen)) + (val << pos)
if val != 0:
newval_mask = (oldval_mask | (~self.get_int_mask(pos, bitlen)))
else:
newval_mask = oldval_mask
data[offset:offset + 4] = self.utils.int_to_4bytearray_l(newval)
data_mask[offset:offset + 4] = self.utils.int_to_4bytearray_l(newval_mask)
return data, data_mask
def bootheader_create_do(self, chipname, chiptype, config_file, section, output_file=None, if_img=False):
efuse_bootheader_path = os.path.join(app_path, bin_build_out_path)
try:
# sub_module = __import__("bootheader_cfg_keys", fromlist=[chiptype])
bh_data, tmp = self.update_data_from_cfg(B_CFG_KEYS.bootheader_cfg_keys, config_file, section)
# bh_data, tmp = self.update_data_from_cfg(sub_module.bootheader_cfg_keys, config_file, section)
bh_data = self.bootheader_update_flash_pll_crc(bh_data)
if output_file == None:
fp = open(efuse_bootheader_path + "/" + section.lower().replace("_cfg", ".bin"), 'wb+')
else:
fp = open(output_file, 'wb+')
if section == "BOOTHEADER_CFG" and chiptype == "bl60x":
final_data = bytearray(8 * 1024)
# add sp core feature
# halt
bh_data[118] = (bh_data[118] | (1 << 2))
final_data[0:176] = bh_data
final_data[4096 + 0:4096 + 176] = bh_data
# change magic
final_data[4096 + 2] = 65
# change waydis to 0xf
final_data[117] = (final_data[117] | (15 << 4))
# change crc and hash ignore
final_data[4096 + 118] = final_data[4096 + 118] | 0x03
bh_data = final_data
if if_img == True:
# clear flash magic
bh_data[8:12] = bytearray(4)
# clear clock magic
bh_data[100:104] = bytearray(4)
fp.write(bh_data[0:176])
else:
fp.write(bh_data)
fp.close()
fp = open(efuse_bootheader_path + "/flash_para.bin", 'wb+')
fp.write(bh_data[12:12 + 84])
fp.close()
except Exception as err:
print("bootheader_create_do fail!!")
print(err)
traceback.print_exc(limit=5, file=sys.stdout)
def bootheader_create_process(self, chipname, chiptype, config_file, output_file1=None, output_file2=None, if_img=False):
fp = open(config_file, 'r')
data = fp.read()
fp.close()
if "BOOTHEADER_CFG" in data:
self.bootheader_create_do(chipname, chiptype, config_file, "BOOTHEADER_CFG", output_file1, if_img)
if "BOOTHEADER_CPU0_CFG" in data:
self.bootheader_create_do(chipname, chiptype, config_file, "BOOTHEADER_CPU0_CFG", output_file1, if_img)
if "BOOTHEADER_CPU1_CFG" in data:
self.bootheader_create_do(chipname, chiptype, config_file, "BOOTHEADER_CPU1_CFG", output_file2, if_img)
def efuse_create_process(self, chipname, chiptype, config_file, output_file=None):
efuse_file = os.path.join(app_path, bin_build_out_path, "efusedata.bin")
# sub_module = __import__("efuse_cfg_keys.py", fromlist=[chiptype])
efuse_data, mask = self.update_data_from_cfg(E_CFG_KEYS.efuse_cfg_keys, config_file, "EFUSE_CFG")
# efuse_data, mask = self.update_data_from_cfg(sub_module.efuse_cfg_keys, config_file, "EFUSE_CFG")
if output_file == None:
fp = open(efuse_file, 'wb+')
else:
fp = open(output_file, 'wb+')
fp.write(efuse_data)
fp.close()
efuse_mask_file = os.path.join(app_path, bin_build_out_path, "efusedata_mask.bin")
if output_file == None:
fp = open(efuse_mask_file, 'wb+')
else:
fp = open(output_file.replace(".bin", "_mask.bin"), 'wb+')
fp.write(mask)
fp.close()
def efuse_boothd_create_process(self, chipname, chiptype, config_file):
self.bootheader_create_process(chipname, chiptype, config_file)
self.efuse_create_process(chipname, chiptype, config_file)
class bl_utils():
#12345678->0x12,0x34,0x56,0x78
def hexstr_to_bytearray_b(self, hexstring):
return bytearray.fromhex(hexstring)
def hexstr_to_bytearray(self, hexstring):
return bytearray.fromhex(hexstring)
def hexstr_to_bytearray_l(self, hexstring):
b = bytearray.fromhex(hexstring)
b.reverse()
return b
def int_to_2bytearray_l(self, intvalue):
return struct.pack("<H", intvalue)
def int_to_2bytearray_b(self, intvalue):
return struct.pack(">H", intvalue)
def int_to_4bytearray_l(self, intvalue):
src = bytearray(4)
src[3] = ((intvalue >> 24) & 0xFF)
src[2] = ((intvalue >> 16) & 0xFF)
src[1] = ((intvalue >> 8) & 0xFF)
src[0] = ((intvalue >> 0) & 0xFF)
return src
def int_to_4bytearray_b(self, intvalue):
val = int_to_4bytearray_l(intvalue)
val.reverse()
return val
def bytearray_reverse(self, a):
l = len(a)
b = bytearray(l)
i = 0
while i < l:
b[i] = a[l - i - 1]
i = i + 1
return b
def bytearray_to_int(self, b):
return int(binascii.hexlify(b), 16)
def string_to_bytearray(self, string):
return bytes(string, encoding="utf8")
def bytearray_to_str(self, bytesarray):
return str(bytesarray)
def get_random_hexstr(self, n_bytes):
hextring = ""
i = 0
while i < n_bytes:
hextring = hextring + str(binascii.hexlify(random.randint(0, 255)))
i = i + 1
return hextring
def get_crc32_bytearray(self, data):
crc = binascii.crc32(data)
return self.int_to_4bytearray_l(crc)
def copyfile(self, srcfile, dstfile):
if os.path.isfile(srcfile):
fpath, fname = os.path.split(dstfile)
if not os.path.exists(fpath):
os.makedirs(fpath)
shutil.copyfile(srcfile, dstfile)
else:
print("Src file not exists")
sys.exit()
def enable_udp_send_log(self, server,local_echo):
global udp_send_log,udp_socket_server,upd_log_local_echo
udp_send_log=True
upd_log_local_echo=local_echo
udp_socket_server=server
def add_udp_client(self, tid,upd_client):
udp_clinet_dict[tid]=upd_client
def remove_udp_client(self, tid):
del udp_clinet_dict[tid]
def Update_Cfg(self, cfg, section, key, value):
if cfg.has_option(section, key):
cfg.set(section, key, str(value))
else:
#print key," not found,adding it"
cfg.set(section, key, str(value))
def get_byte_array(self, str):
return str.encode("utf-8")
#class BFConfigParser(configparser.ConfigParser):
# def __init__(self, defaults=None):
# configparser.ConfigParser.__init__(self, defaults=defaults)
#
# def optionxform(self, optionstr):
# return optionstr
class BFConfigParser():
cfg_infile = None
cfg_obj = ConfigObj()
def __init__(self, file=None):
self.cfg_infile = file
self.cfg_obj = ConfigObj(self.cfg_infile)
def read(self, file=None):
self.cfg_infile = file
self.cfg_obj = ConfigObj(self.cfg_infile, encoding='UTF8')
return self.cfg_obj
def get(self, section, key):
ret = self.cfg_obj[section][key]
if ret == "\"\"":
return ""
else:
return ret
def set(self, section, key, value):
self.cfg_obj[section][key] = str(value)
def sections(self,):
return self.cfg_obj.keys()
def delete_section(self, section):
del self.cfg_obj[section]
def update_section_name(self, oldsection, newsection):
_sections = self.cfg_obj.keys()
for _section in _sections:
print(_section)
if _section == oldsection:
print(self.cfg_obj[_section])
self.cfg_obj[newsection] = self.cfg_obj[oldsection]
self.delete_section(oldsection)
def options(self, section):
return self.cfg_obj[section]
def has_option(self, section, key):
_sections = self.cfg_obj.keys()
for _section in _sections:
if _section == section:
for _key in self.cfg_obj[_section]:
if _key == key:
return True
else:
continue
else:
continue
return False
def write(self, outfile=None, flag=None):
if outfile == None:
self.cfg_obj.filename = self.cfg_infile
else:
self.cfg_obj.filename = outfile
self.cfg_obj.write()
class PtCreater(bl_utils):
def __init__(self, config_file):
#if not os.path.exists(config_file):
# config_file = os.path.join(default_conf_path, "partition_cfg_2M.toml")
#config_file = bl_find_file("partition_cfg_", ".toml")
self.parsed_toml = toml.load(config_file)
self.entry_max = 16
self.pt_new = False
def __create_pt_table_do(self, lists, file):
entry_table = bytearray(36 * self.entry_max)
entry_cnt = 0
for item in lists:
entry_type = item["type"]
entry_name = item["name"]
entry_device = item["device"]
entry_addr0 = item["address0"]
entry_addr1 = item["address1"]
entry_maxlen0 = item["size0"]
entry_maxlen1 = item["size1"]
entry_len = item["len"]
entry_table[36 * entry_cnt + 0] = self.int_to_2bytearray_l(entry_type)[0]
if len(entry_name) >= 8:
print("Entry name is too long!")
return False
entry_table[36 * entry_cnt + 3:36 * entry_cnt + 3 + len(entry_name)] = bytearray(entry_name, "utf-8") + bytearray(0)
entry_table[36 * entry_cnt + 12:36 * entry_cnt + 16] = self.int_to_4bytearray_l(entry_addr0)
entry_table[36 * entry_cnt + 16:36 * entry_cnt + 20] = self.int_to_4bytearray_l(entry_addr1)
entry_table[36 * entry_cnt + 20:36 * entry_cnt + 24] = self.int_to_4bytearray_l(entry_maxlen0)
entry_table[36 * entry_cnt + 24:36 * entry_cnt + 28] = self.int_to_4bytearray_l(entry_maxlen1)
entry_cnt += 1
#partition table header
#0x54504642
pt_table = bytearray(16)
pt_table[0] = 0x42
pt_table[1] = 0x46
pt_table[2] = 0x50
pt_table[3] = 0x54
pt_table[6:8] = self.int_to_2bytearray_l(int(entry_cnt))
pt_table[12:16] = self.get_crc32_bytearray(pt_table[0:12])
entry_table[36 * entry_cnt:36 * entry_cnt + 4] = self.get_crc32_bytearray(entry_table[0:36 * entry_cnt])
data = pt_table + entry_table[0:36 * entry_cnt + 4]
fp = open(file, 'wb+')
fp.write(data)
fp.close()
return True
def create_pt_table(self, file):
self.pt_new = True
return self.__create_pt_table_do(self.parsed_toml["pt_entry"], file)
def get_pt_table_addr(self):
addr0 = self.parsed_toml["pt_table"]["address0"]
addr1 = self.parsed_toml["pt_table"]["address1"]
return addr0, addr1
def construct_table(self):
parcel = {}
if self.pt_new == True:
parcel['pt_new'] = True
else:
parcel['pt_new'] = False
parcel['pt_addr0'] = self.parsed_toml["pt_table"]["address0"]
parcel['pt_addr1'] = self.parsed_toml["pt_table"]["address1"]
for tbl_item in self.parsed_toml["pt_entry"]:
if tbl_item['name'] == 'factory':
parcel['conf_addr'] = tbl_item['address0']
if tbl_item['name'] == 'FW_CPU0':
parcel['fw_cpu0_addr'] = tbl_item['address0']
if tbl_item['name'] == 'FW':
parcel['fw_addr'] = tbl_item['address0']
if tbl_item['name'] == 'media':
parcel['media_addr'] = tbl_item['address0']
if tbl_item['name'] == 'mfg':
parcel['mfg_addr'] = tbl_item['address0']
return parcel
class bl_img_create_do(bl_utils):
def __init__(self):
cfg = BFConfigParser()
keyslot0 = 28
keyslot1 = keyslot0 + 16
keyslot2 = keyslot1 + 16
keyslot3 = keyslot2 + 16
keyslot4 = keyslot3 + 16
keyslot5 = keyslot4 + 16
keyslot6 = keyslot5 + 16
wr_lock_key_slot_4_l = 13
wr_lock_key_slot_5_l = 14
wr_lock_boot_mode = 15
wr_lock_dbg_pwd = 16
wr_lock_sw_usage_0 = 17
wr_lock_wifi_mac = 18
wr_lock_key_slot_0 = 19
wr_lock_key_slot_1 = 20
wr_lock_key_slot_2 = 21
wr_lock_key_slot_3 = 22
wr_lock_key_slot_4_h = 23
wr_lock_key_slot_5_h = 24
rd_lock_dbg_pwd = 25
rd_lock_key_slot_0 = 26
rd_lock_key_slot_1 = 27
rd_lock_key_slot_2 = 28
rd_lock_key_slot_3 = 29
rd_lock_key_slot_4 = 30
rd_lock_key_slot_5 = 31
#####################update efuse info##########################################
def img_update_efuse(self, sign, pk_hash, flash_encryp_type, flash_key, sec_eng_key_sel, sec_eng_key):
fp = open(cfg.get("Img_Cfg", "efuse_file"), 'rb')
efuse_data = bytearray(fp.read()) + bytearray(0)
fp.close()
fp = open(cfg.get("Img_Cfg", "efuse_mask_file"), 'rb')
efuse_mask_data = bytearray(fp.read()) + bytearray(0)
fp.close()
mask_4bytes = bytearray.fromhex("FFFFFFFF")
efuse_data[0] |= flash_encryp_type
efuse_data[0] |= (sign << 2)
if flash_encryp_type > 0:
efuse_data[0] |= 0x80
efuse_mask_data[0] |= 0xff
rw_lock = 0
if pk_hash != None:
efuse_data[keyslot0:keyslot2] = pk_hash
efuse_mask_data[keyslot0:keyslot2] = mask_4bytes * 8
rw_lock |= (1 << wr_lock_key_slot_0)
rw_lock |= (1 << wr_lock_key_slot_1)
if flash_key != None:
if flash_encryp_type == 1:
# aes 128
efuse_data[keyslot2:keyslot4] = flash_key
efuse_mask_data[keyslot2:keyslot4] = mask_4bytes * 8
elif flash_encryp_type == 2:
# aes 192
efuse_data[keyslot2:keyslot4] = flash_key
efuse_mask_data[keyslot2:keyslot4] = mask_4bytes * 8
elif flash_encryp_type == 3:
# aes 256
efuse_data[keyslot2:keyslot4] = flash_key
efuse_mask_data[keyslot2:keyslot4] = mask_4bytes * 8
rw_lock |= (1 << wr_lock_key_slot_2)
rw_lock |= (1 << wr_lock_key_slot_3)
rw_lock |= (1 << rd_lock_key_slot_2)
rw_lock |= (1 << rd_lock_key_slot_3)
if sec_eng_key != None:
if flash_encryp_type == 0:
if sec_eng_key_sel == 0:
efuse_data[keyslot2:keyslot3] = sec_eng_key[16:32]
efuse_data[keyslot3:keyslot4] = sec_eng_key[0:16]
efuse_mask_data[keyslot2:keyslot4] = mask_4bytes * 8
rw_lock |= (1 << wr_lock_key_slot_2)
rw_lock |= (1 << wr_lock_key_slot_3)
rw_lock |= (1 << rd_lock_key_slot_2)
rw_lock |= (1 << rd_lock_key_slot_3)
if sec_eng_key_sel == 1:
efuse_data[keyslot3:keyslot4] = sec_eng_key[16:32]
efuse_data[keyslot2:keyslot3] = sec_eng_key[0:16]
efuse_mask_data[keyslot2:keyslot4] = mask_4bytes * 8
rw_lock |= (1 << wr_lock_key_slot_2)
rw_lock |= (1 << wr_lock_key_slot_3)
rw_lock |= (1 << rd_lock_key_slot_2)
rw_lock |= (1 << rd_lock_key_slot_3)
if flash_encryp_type == 1:
if sec_eng_key_sel == 0:
efuse_data[keyslot4:keyslot5] = sec_eng_key[0:16]
efuse_mask_data[keyslot4:keyslot5] = mask_4bytes * 4
rw_lock |= (1 << wr_lock_key_slot_4_l)
rw_lock |= (1 << wr_lock_key_slot_4_h)
rw_lock |= (1 << rd_lock_key_slot_4)
if sec_eng_key_sel == 1:
efuse_data[keyslot4:keyslot5] = sec_eng_key[0:16]
efuse_mask_data[keyslot4:keyslot5] = mask_4bytes * 4
rw_lock |= (1 << wr_lock_key_slot_4_l)
rw_lock |= (1 << wr_lock_key_slot_4_h)
rw_lock |= (1 << rd_lock_key_slot_4)
# set read write lock key
efuse_data[124:128] = self.int_to_4bytearray_l(rw_lock)
efuse_mask_data[124:128] = self.int_to_4bytearray_l(rw_lock)
fp = open(cfg.get("Img_Cfg", "efuse_file"), 'wb+')
fp.write(efuse_data)
fp.close()
fp = open(cfg.get("Img_Cfg", "efuse_mask_file"), 'wb+')
fp.write(efuse_mask_data)
fp.close()
####################get sign and encrypt info##########################################
def img_create_get_sign_encrypt_info(self, bootheader_data):
sign = bootheader_data[116] & 0x3
encrypt = ((bootheader_data[116] >> 2) & 0x3)
key_sel = ((bootheader_data[116] >> 4) & 0x3)
return sign, encrypt, key_sel
####################get hash ignore ignore##########################################
def img_create_get_hash_ignore(self, bootheader_data):
return (bootheader_data[118] >> 1) & 0x1
####################get crc ignore ignore##########################################
def img_create_get_crc_ignore(self, bootheader_data):
return bootheader_data[118] & 0x1
#####################update boot header info##########################################
def img_create_update_bootheader(self, bootheader_data, hash, seg_cnt):
# update segment count
bootheader_data[120:124] = self.int_to_4bytearray_l(seg_cnt)
# update hash
sign, encrypt, key_sel = self.img_create_get_sign_encrypt_info(bootheader_data)
if self.img_create_get_hash_ignore(bootheader_data) == 1 and sign == 0:
# do nothing
pass
else:
bootheader_data[132:164] = hash
# update header crc
if self.img_create_get_crc_ignore(bootheader_data) == 1:
# do nothing
pass
else:
hd_crcarray = self.get_crc32_bytearray(bootheader_data[0:176 - 4])
bootheader_data[176 - 4:176] = hd_crcarray
print("Header crc: ", binascii.hexlify(hd_crcarray))
return bootheader_data[0:176]
#####################update segment header according segdata#########################
def img_create_update_segheader(self, segheader, segdatalen, segdatacrc):
segheader[4:8] = segdatalen
segheader[8:12] = segdatacrc
return segheader
#####################do hash of image################################################
def img_create_sha256_data(self, data_bytearray):
hashfun = SHA256.new()
hashfun.update(data_bytearray)
return self.hexstr_to_bytearray(hashfun.hexdigest())
#####################encrypt image, mainly segdata#####################################
def img_create_encrypt_data(self, data_bytearray, key_bytearray, iv_bytearray, flash_img):
if flash_img == 0:
cryptor = AES.new(key_bytearray, AES.MODE_CBC, iv_bytearray)
ciphertext = cryptor.encrypt(data_bytearray)
else:
#iv = Crypto.Util.Counter.new(128, initial_value = long(binascii.hexlify(iv_bytearray),16))
iv = Counter.new(128, initial_value=int(binascii.hexlify(iv_bytearray), 16))
cryptor = AES.new(key_bytearray, AES.MODE_CTR, counter=iv)
ciphertext = cryptor.encrypt(data_bytearray)
return ciphertext
#####################sign image(hash code)#####################################
def img_create_sign_data(self, data_bytearray, privatekey_file_uecc, publickey_file):
sk = ecdsa.SigningKey.from_pem(open(privatekey_file_uecc).read())
vk = ecdsa.VerifyingKey.from_pem(open(publickey_file).read())
pk_data = vk.to_string()
pk_hash = self.img_create_sha256_data(pk_data)
signature = sk.sign(data_bytearray, hashfunc=hashlib.sha256, sigencode=ecdsa.util.sigencode_string)
# return len+signature+crc
len_array = self.int_to_4bytearray_l(len(signature))
sig_field = len_array + signature
crcarray = self.get_crc32_bytearray(sig_field)
return pk_data, pk_hash, sig_field + crcarray
######################## read one file and append crc if needed#####################
def img_create_read_file_append_crc(self, file, crc):
fp = open(file, 'rb')
read_data = bytearray(fp.read())
crcarray = bytearray(0)
if crc:
crcarray = self.get_crc32_bytearray(read_data)
fp.close()
return read_data + crcarray
def img_creat_process(self, flash_img):
encrypt_blk_size = 16
padding = bytearray(encrypt_blk_size)
data_tohash = bytearray(0)
ret = 'OK'
cfg_section = "Img_Cfg"
# get segdata to deal with
segheader_file = []
if flash_img == 0:
for files in cfg.get(cfg_section, "segheader_file").split(" "):
segheader_file.append(str(files))
segdata_file = []
for files in cfg.get(cfg_section, "segdata_file").split(" "):
segdata_file.append(str(files))
if flash_img == 1:
break
# get bootheader
boot_header_file = cfg.get(cfg_section, "boot_header_file")
bootheader_data = self.img_create_read_file_append_crc(boot_header_file, 0)
# decide encrypt and sign
encrypt = 0
sign, encrypt, key_sel = self.img_create_get_sign_encrypt_info(bootheader_data)
aesiv_data = bytearray(0)
pk_data = bytearray(0)
if sign != 0:
publickey_file = cfg.get(cfg_section, "publickey_file")
privatekey_file_uecc = cfg.get(cfg_section, "privatekey_file_uecc")
if encrypt != 0:
encrypt_key_org = self.hexstr_to_bytearray(cfg.get(cfg_section, "aes_key_org"))
global encrypt_key
if encrypt == 1:
encrypt_key = encrypt_key_org[0:16]
elif encrypt == 2:
encrypt_key = encrypt_key_org[0:32]
elif encrypt == 3:
encrypt_key = encrypt_key_org[0:24]
encrypt_iv = self.hexstr_to_bytearray(cfg.get(cfg_section, "aes_iv"))
iv_crcarray = self.get_crc32_bytearray(encrypt_iv)
aesiv_data = encrypt_iv + iv_crcarray
data_tohash = data_tohash + aesiv_data
# decide seg_cnt values
seg_cnt = len(segheader_file)
if flash_img == 0 and seg_cnt != len(segdata_file):
print("Segheader count and segdata count not match")
return "FAIL", data_tohash
data_toencrypt = bytearray(0)
if flash_img == 0:
i = 0
seg_header_list = []
seg_data_list = []
while i < seg_cnt:
# read seg data and calculate crcdata
seg_data = self.img_create_read_file_append_crc(segdata_file[i], 0)
padding_size = 0
if len(seg_data) % encrypt_blk_size != 0:
padding_size = encrypt_blk_size - \
len(seg_data) % encrypt_blk_size
seg_data += padding[0:padding_size]
segdata_crcarray = self.get_crc32_bytearray(seg_data)
seg_data_list.append(seg_data)
# read seg header and replace segdata's CRC
seg_header = self.img_create_read_file_append_crc(segheader_file[i], 0)
seg_header = img_create_update_segheader(seg_header, self.int_to_4bytearray_l(len(seg_data)), segdata_crcarray)
segheader_crcarray = self.get_crc32_bytearray(seg_header)
seg_header = seg_header + segheader_crcarray
seg_header_list.append(seg_header)
i = i + 1
# get all data to encrypt
i = 0
while i < seg_cnt:
# ,now changed to encrypted since download tool's segdata len is from bootrom
data_toencrypt += seg_header_list[i]
data_toencrypt += seg_data_list[i]
i += 1
else:
seg_data = self.img_create_read_file_append_crc(segdata_file[0], 0)
padding_size = 0
if len(seg_data) % encrypt_blk_size != 0:
padding_size = encrypt_blk_size - len(seg_data) % encrypt_blk_size
seg_data += padding[0:padding_size]
data_toencrypt += seg_data
seg_cnt = len(data_toencrypt)
# do encrypt
if encrypt != 0:
data_toencrypt = img_create_encrypt_data(data_toencrypt, encrypt_key, encrypt_iv, flash_img)
# get fw data
fw_data = bytearray(0)
data_tohash += data_toencrypt
fw_data = data_toencrypt
# hash fw img
hash = self.img_create_sha256_data(data_tohash)
# update boot header and recalculate crc
bootheader_data = self.img_create_update_bootheader(bootheader_data, hash, seg_cnt)
# add signautre
signature = bytearray(0)
pk_hash = None
if sign == 1:
pk_data, pk_hash, signature = img_create_sign_data(data_tohash, privatekey_file_uecc, publickey_file)
pk_data = pk_data + self.get_crc32_bytearray(pk_data)
# write whole image
if flash_img == 1:
bootinfo_file_name = cfg.get(cfg_section, "bootinfo_file")
fp = open(bootinfo_file_name, 'wb+')
bootinfo = bootheader_data + pk_data + signature + aesiv_data
fp.write(bootinfo)
fp.close()
fw_file_name = cfg.get(cfg_section, "img_file")
fp = open(fw_file_name, 'wb+')
fp.write(fw_data)
fp.close()
# update efuse
if encrypt != 0:
if encrypt == 1:
# AES 128
img_update_efuse(sign, pk_hash, 1, encrypt_key + bytearray(32 - len(encrypt_key)), key_sel, None)
if encrypt == 2:
# AES 256
img_update_efuse(sign, pk_hash, 3, encrypt_key + bytearray(32 - len(encrypt_key)), key_sel, None)
if encrypt == 3:
# AES 192
img_update_efuse(sign, pk_hash, 2, encrypt_key + bytearray(32 - len(encrypt_key)), key_sel, None)
else:
self.img_update_efuse(sign, pk_hash, encrypt, None, key_sel, None)
else:
whole_img_file_name = cfg.get(cfg_section, "whole_img_file")
fp = open(whole_img_file_name, 'wb+')
img_data = bootheader_data + pk_data + signature + aesiv_data + fw_data
fp.write(img_data)
fp.close()
# update efuse
if encrypt != 0:
if encrypt == 1:
# AES 128
img_update_efuse(sign, pk_hash, 1, None, key_sel, encrypt_key + bytearray(32 - len(encrypt_key)))
if encrypt == 2:
# AES 256
img_update_efuse(sign, pk_hash, 3, None, key_sel, encrypt_key + bytearray(32 - len(encrypt_key)))
if encrypt == 3:
# AES 192
img_update_efuse(sign, pk_hash, 2, None, key_sel, encrypt_key + bytearray(32 - len(encrypt_key)))
else:
img_update_efuse(sign, pk_hash, 0, None, key_sel, bytearray(32))
return "OK", data_tohash
def usage():
print(sys.argv[0], "\n")
print("-i/--img_type= :image type:media or if")
print("-h/--help :helper")
#######################################################################
def img_create_do(self, options, img_dir_path=None, config_file=None):
print("Image create path: ", img_dir_path)
if config_file == None:
config_file = img_dir_path + "/img_create_cfg.ini"
cfg.read(config_file)
print("Config file: ", config_file)
img_type = "media"
signer = "none"
ret = "OK"
data_tohash = bytearray(0)
try:
opts, args = getopt.getopt(options, 'i:s:Hh', ["img_type=", "signer=", "help"])
for option, value in opts:
if option in ["-h", "-H"]:
usage()
if option in ["-i", "--img_type"]:
img_type = value
if option in ["-s", "--signer"]:
signer = value
except getopt.GetoptError as err:
# will something like "option -a not recognized")
print(err)
usage()
if img_type == "media":
flash_img = 1
else:
flash_img = 0
# deal image creation
ret, data_tohash = self.img_creat_process(flash_img)
if ret != "OK":
print("Fail to create images!")
return
def create_sp_media_image(self, config, cpu_type=None):
global cfg
cfg = BFConfigParser()
cfg.read(config)
self.img_creat_process(1)
class bl_img_create(bl_img_create_do):
def img_create(self, options, chipname="bl60x", chiptype="bl60x", img_dir=None, config_file=None):
img_dir_path = os.path.join(app_path, chipname, "img_create")
if img_dir is None:
self.img_create_do(options, img_dir_path, config_file)
else:
self.img_create_do(options, img_dir, config_file)
def create_sp_media_image_file(self, config, chiptype="bl60x", cpu_type=None):
self.create_sp_media_image(config, cpu_type)
class bl_device_tree():
def bl_dts2dtb(self, src_addr="", dest_addr=""):
if "" == src_addr or "" == dest_addr:
print("bl_dts2dtb please check arg.")
return
with open(src_addr, "r") as f:
tmp1_dts = f.read()
tmp2_dtb = fdt.parse_dts(tmp1_dts)
dest_addr = os.path.join(app_path, bin_build_out_path, dest_addr)
with open(dest_addr, "wb") as f:
f.write(tmp2_dtb.to_dtb(version=17))
def bl_ro_params_device_tree(self, in_dts_config, out_bin_file):
dts_config = in_dts_config
bin_file = out_bin_file
self.bl_dts2dtb(dts_config, bin_file)
class bl_whole_img_generate():
def bl_create_flash_default_data(self, length):
datas = bytearray(length)
for i in range(length):
datas[i] = 0xff
return datas
def bl_get_largest_addr(self, addrs, files):
maxlen = 0
datalen = 0
for i in range(len(addrs)):
if int(addrs[i], 16) > maxlen:
maxlen = int(addrs[i], 16)
datalen = os.path.getsize(files[i])
return maxlen + datalen
def bl_get_file_data(self, files):
datas = []
for file in files:
with open(file, 'rb') as fp:
data = fp.read()
datas.append(data)
return datas
def bl_write_flash_img(self, d_addrs, d_files, flash_size):
whole_img_len = self.bl_get_largest_addr(d_addrs, d_files)
whole_img_data = self.bl_create_flash_default_data(whole_img_len)
filedatas = self.bl_get_file_data(d_files)
for i in range(len(d_addrs)):
start_addr = int(d_addrs[i], 16)
whole_img_data[start_addr:start_addr + len(filedatas[i])] = filedatas[i]
# dst_file = os.path.join(app_path, bin_build_out_path, "whole_flash_data.bin")
dst_file = os.path.join(app_path, bin_build_out_path, "whole_{}.bin".format(file_finally_name))
fp = open(dst_file, 'wb+')
fp.write(whole_img_data)
print("Generating BIN File to %s" %(dst_file))
fp.close()
def bl_image_gen_cfg(self, raw_bin_name, bintype, key=None, iv=None, cfg_ini=None, cpu_type=None):
cfg = BFConfigParser()
if cfg_ini in [None, '']:
f_org = bl_find_file("img_create_cfg", ".conf")
f = os.path.join(app_path, bin_build_out_path, "img_create_cfg.ini")
#if os.path.isfile(f) == False:
shutil.copy(f_org, f)
else:
f = cfg_ini
cfg.read(f)
if bintype == "fw":
if cpu_type == None:
bootinfo_file = os.path.join(app_path, bin_build_out_path, "bootinfo.bin")
img_file = os.path.join(app_path, bin_build_out_path, "img.bin")
else:
bootinfo_file = os.path.join(app_path, bin_build_out_path, "bootinfo_{0}.bin".format(cpu_type.lower()))
img_file = os.path.join(app_path, bin_build_out_path, "img_{0}.bin".format(cpu_type.lower()))
else:
bootinfo_file = os.path.join(app_path, bin_build_out_path, "bootinfo_{0}.bin".format(bintype))
img_file = os.path.join(app_path, bin_build_out_path, "img_{0}.bin".format(bintype))
if cpu_type != None:
img_section_name = "Img_" + cpu_type + "_Cfg"
else:
if "Img_CPU0_Cfg" in cfg.sections():
img_section_name = "Img_CPU0_Cfg"
else:
img_section_name = "Img_Cfg"
bh_file = os.path.join(app_path, bin_build_out_path, "bootheader.bin")
efuse_file = os.path.join(app_path, bin_build_out_path, "efusedata.bin")
efuse_mask_file = os.path.join(app_path, bin_build_out_path, "efusedata_mask.bin")
cfg.set(img_section_name, 'boot_header_file', bh_file)
cfg.set(img_section_name, 'efuse_file', efuse_file)
cfg.set(img_section_name, 'efuse_mask_file', efuse_mask_file)
cfg.set(img_section_name, 'segdata_file', raw_bin_name)
cfg.set(img_section_name, 'bootinfo_file', bootinfo_file)
cfg.set(img_section_name, 'img_file', img_file)
if key:
cfg.set(img_section_name, 'aes_key_org', key)
if iv:
cfg.set(img_section_name, 'aes_iv', iv)
cfg.write(f, 'w')
return f
def bl_image_gen(self, bintype, raw_bin_name, key=None, iv=None, cfg_ini=None):
# python bflb_img_create.py -c np -i media -s none
f = self.bl_image_gen_cfg(raw_bin_name, bintype)
#exe_genitor(['bflb_img_create.exe', '-c', 'np', '-i', 'media', '-s', 'none'])
img_create = bl_img_create()
img_create.create_sp_media_image_file(f)
def bl_fw_boot_head_gen(self, boot2, xtal, config, encrypt=False, chipname="bl60x", chiptype="bl60x", cpu_type=None):
cfg = BFConfigParser()
cfg.read(config)
if cpu_type != None:
bootheader_section_name = "BOOTHEADER_" + cpu_type + "_CFG"
else:
if "BOOTHEADER_CPU0_CFG" in cfg.sections():
bootheader_section_name = "BOOTHEADER_CPU0_CFG"
else:
bootheader_section_name = "BOOTHEADER_CFG"
if boot2 == True:
cfg.set(bootheader_section_name, 'img_start', '0x2000')
cfg.set(bootheader_section_name, 'cache_enable', '1')
cfg.set(bootheader_section_name, 'crc_ignore', '1')
cfg.set(bootheader_section_name, 'hash_ignore', '1')
#cfg.set(bootheader_section_name,'sfctrl_clk_delay', '0')
if cpu_type != None:
cfg.set(bootheader_section_name, 'halt_cpu1', '1')
cfg.set(bootheader_section_name, 'key_sel', '0')
if encrypt:
cfg.set(bootheader_section_name, 'encrypt_type', '1')
else:
cfg.set(bootheader_section_name, 'encrypt_type', '0')
cfg.set(bootheader_section_name, 'xtal_type', dict_xtal[xtal])
cfg.write(config)
create = bl_efuse_boothd_gen()
create.efuse_boothd_create_process(chipname, chiptype, config)
def bl_whole_flash_bin_create(self, bin_file, boot2, ro_params, pt_parcel, media, mfg, flash_opt="1M"):
d_files = []
d_addrs = []
if pt_parcel == None:
return False
if boot2 == True:
d_files.append(os.path.join(app_path, bin_build_out_path, "bootinfo_boot2.bin"))
d_addrs.append("00000000")
d_files.append(os.path.join(app_path, bin_build_out_path, "img_boot2.bin"))
d_addrs.append("00002000")
if pt_parcel != None and len(pt_parcel) > 0 and pt_parcel['pt_new'] == True:
d_files.append(os.path.join(app_path, bin_build_out_path, "partition.bin"))
d_addrs.append(hex(pt_parcel['pt_addr0'])[2:])
d_files.append(os.path.join(app_path, bin_build_out_path, "partition.bin"))
d_addrs.append(hex(pt_parcel['pt_addr1'])[2:])
if bin_file == True and 'fw_addr' in pt_parcel:
d_files.append(os.path.join(app_path, bin_build_out_path, "bootinfo.bin"))
d_addrs.append(hex(pt_parcel['fw_addr'])[2:])
d_files.append(os.path.join(app_path, bin_build_out_path, "img.bin"))
d_addrs.append(hex(pt_parcel['fw_addr'] + 0x1000)[2:])
if ro_params != None and len(ro_params) > 0 and pt_parcel['conf_addr'] != None:
bl_ro_device_tree = bl_device_tree()
dtb_file = os.path.join(app_path, bin_build_out_path, "ro_params.dtb")
bl_ro_device_tree.bl_ro_params_device_tree(ro_params, dtb_file)
d_files.append(os.path.join(app_path, bin_build_out_path, "ro_params.dtb"))
d_addrs.append(hex(pt_parcel['conf_addr'])[2:])
if media == True and pt_parcel['media_addr'] != None:
d_files.append(os.path.join(app_path, bin_build_out_path, "media.bin"))
d_addrs.append(hex(pt_parcel['media_addr'])[2:])
if mfg == True:
d_files.append(os.path.join(app_path, bin_build_out_path, "bootinfo_mfg.bin"))
d_addrs.append(hex(pt_parcel['mfg_addr'])[2:])
d_files.append(os.path.join(app_path, bin_build_out_path, "img_mfg.bin"))
d_addrs.append(hex(pt_parcel['mfg_addr'] + 0x1000)[2:])
if len(d_files) > 0 and len(d_addrs) > 0:
cfg = BFConfigParser()
cfg.read(eflash_loader_cfg)
self.bl_write_flash_img(d_addrs, d_files, flash_opt)
files_str = " ".join(d_files)
addrs_str = " ".join(d_addrs)
cfg.set('FLASH_CFG', 'file', files_str)
cfg.set('FLASH_CFG', 'address', addrs_str)
cfg.write(eflash_loader_cfg, 'w')
return True
else:
return False
class bl_img_ota():
def bl_mfg_ota_header(self, file_bytearray, use_xz):
ota_conf = bl_find_file("ota", ".toml")
parsed_toml = toml.load(ota_conf)
header_len = 512
header = bytearray()
file_len = len(file_bytearray)
m = hashlib.sha256()
# 16 Bytes header
data = b'BL60X_OTA_Ver1.0'
for b in data:
header.append(b)
# 4 Byte ota file type
if use_xz:
data = b'XZ '
else:
data = b'RAW '
for b in data:
header.append(b)
# 4 Bytes file length
file_len_bytes = file_len.to_bytes(4, byteorder='little')
for b in file_len_bytes:
header.append(b)
# 8 Bytes pad
header.append(0x01)
header.append(0x02)
header.append(0x03)
header.append(0x04)
header.append(0x05)
header.append(0x06)
header.append(0x07)
header.append(0x08)
# 16 Bytes Hardware version
data = bytearray(parsed_toml["ota"]["version_hardware"].encode())
data_len = 16 - len(data)
for b in data:
header.append(b)
while data_len > 0:
header.append(0x00)
data_len = data_len - 1
# 16 Bytes firmware version
data = bytearray(parsed_toml["ota"]["version_software"].encode())
data_len = 16 - len(data)
for b in data:
header.append(b)
while data_len > 0:
header.append(0x00)
data_len = data_len - 1
# 32 Bytes SHA256
m.update(file_bytearray)
hash_bytes = m.digest()
for b in hash_bytes:
header.append(b)
header_len = header_len - len(header)
while header_len > 0:
header.append(0xFF)
header_len = header_len - 1
return header
def bl_mfg_ota_xz_gen(self, chipname="bl60x", chiptype="bl60x", cpu_type=None):
bl60x_xz_filters = [
{
"id": lzma.FILTER_LZMA2,
"dict_size": 32768
},
]
fw_ota_bin = bytearray()
fw_ota_bin_xz = bytearray()
if cpu_type == None:
FW_OTA_path = os.path.join(app_path, bin_build_out_path, "ota/{}/FW_OTA.bin".format(file_finally_name))
else:
FW_OTA_path = os.path.join(app_path, bin_build_out_path, "ota/{}/".format(file_finally_name) + cpu_type + "_OTA.bin")
with open(FW_OTA_path, mode="rb") as bin_f:
file_bytes = bin_f.read()
for b in file_bytes:
fw_ota_bin.append(b)
if cpu_type == None:
FW_OTA_path = os.path.join(app_path, bin_build_out_path, "ota/{}/FW_OTA.bin.xz".format(file_finally_name))
else:
FW_OTA_path = os.path.join(app_path, bin_build_out_path, "ota/{}/".format(file_finally_name) + cpu_type + "_OTA.bin.xz")
with lzma.open(FW_OTA_path, mode="wb", check=lzma.CHECK_CRC32, filters=bl60x_xz_filters) as xz_f:
xz_f.write(fw_ota_bin)
print("Generating BIN File to %s" %(FW_OTA_path))
with open(FW_OTA_path, mode="rb") as f:
file_bytes = f.read()
for b in file_bytes:
fw_ota_bin_xz.append(b)
fw_ota_bin_xz_ota = self.bl_mfg_ota_header(fw_ota_bin_xz, use_xz=1)
for b in fw_ota_bin_xz:
fw_ota_bin_xz_ota.append(b)
if cpu_type == None:
FW_OTA_path = os.path.join(app_path, bin_build_out_path, "ota/{}/FW_OTA.bin.xz.ota".format(file_finally_name))
else:
FW_OTA_path = os.path.join(app_path, bin_build_out_path, "ota/{}/".format(file_finally_name) + cpu_type + "_OTA.bin.xz.ota")
with open(FW_OTA_path, mode="wb") as f:
f.write(fw_ota_bin_xz_ota)
print("Generating BIN File to %s" %(FW_OTA_path))
def bl_mfg_ota_bin_gen(self, chipname="bl60x", chiptype="bl60x", cpu_type=None):
fw_header_len = 4096
fw_ota_bin = bytearray()
ota_path = os.path.join(app_path, bin_build_out_path)
if os.path.isdir(ota_path)==False:
os.mkdir(ota_path)
if cpu_type == None:
bootinfo_fw_path = os.path.join(app_path, bin_build_out_path, "bootinfo.bin")
else:
bootinfo_fw_path = os.path.join(app_path, bin_build_out_path, "bootinfo_" + cpu_type.lower() + ".bin")
with open(bootinfo_fw_path, mode="rb") as f:
file_bytes = f.read(4096)
for b in file_bytes:
fw_ota_bin.append(b)
i = fw_header_len - len(fw_ota_bin)
while i > 0:
fw_ota_bin.append(0xFF)
i = i - 1
if cpu_type == None:
img_fw_path = os.path.join(app_path, bin_build_out_path, "img.bin")
else:
img_fw_path = os.path.join(app_path, bin_build_out_path, "img_" + cpu_type.lower() + ".bin")
with open(img_fw_path, mode="rb") as f:
file_bytes = f.read()
for b in file_bytes:
fw_ota_bin.append(b)
fw_ota_bin_header = self.bl_mfg_ota_header(fw_ota_bin, use_xz=0)
FW_OTA_path = os.path.join(app_path, bin_build_out_path, "ota")
if not os.path.exists(FW_OTA_path):
os.makedirs(FW_OTA_path)
FW_OTA_path = os.path.join(FW_OTA_path, file_finally_name)
if not os.path.exists(FW_OTA_path):
os.makedirs(FW_OTA_path)
if cpu_type == None:
FW_OTA_path = os.path.join(FW_OTA_path, "FW_OTA.bin")
else:
FW_OTA_path = os.path.join(FW_OTA_path, cpu_type + "_OTA.bin")
with open(FW_OTA_path, mode="wb") as f:
f.write(fw_ota_bin)
print("Generating BIN File to %s" %(FW_OTA_path))
for b in fw_ota_bin:
fw_ota_bin_header.append(b)
if cpu_type == None:
FW_OTA_path = os.path.join(app_path, bin_build_out_path, "ota/{}/FW_OTA.bin.ota".format(file_finally_name))
else:
FW_OTA_path = os.path.join(app_path, bin_build_out_path, "ota/{}/".format(file_finally_name) + cpu_type + "_OTA.bin.ota")
with open(FW_OTA_path, mode="wb") as f:
f.write(fw_ota_bin_header)
print("Generating BIN File to %s" %(FW_OTA_path))
self.bl_mfg_ota_xz_gen(chipname, chiptype, cpu_type)
class bl_flash_select():
def get_suitable_file_name(self, cfg_dir, flash_id):
conf_files = []
for home, dirs, files in os.walk(cfg_dir):
for filename in files:
if filename.split('_')[-1] == flash_id + '.conf':
conf_files.append(filename)
if len(conf_files) > 1:
for i in range(len(conf_files)):
tmp = conf_files[i].split('.')[0]
print("%d:%s" % (i + 1, tmp))
return conf_files[i]
elif len(conf_files) == 1:
return conf_files[0]
else:
return ""
def update_flash_cfg_do(self, chipname, chiptype, flash_id, file=None, create=False, section=None):
cfg_dir = os.path.join(os.getcwd(), chiptype, "flash_select")
conf_name = self.get_suitable_file_name(cfg_dir, flash_id)
print(os.path.join(cfg_dir, conf_name))
value_key = []
if os.path.isfile(os.path.join(cfg_dir, conf_name)) == False:
return False
fp = open(os.path.join(cfg_dir, conf_name), 'r')
for line in fp.readlines():
value = line.split("=")[0].strip()
if value == "[FLASH_CFG]":
continue
value_key.append(value)
cfg1 = BFConfigParser()
cfg1.read(os.path.join(cfg_dir, conf_name))
cfg2 = BFConfigParser()
cfg2.read(file)
for i in range(len(value_key)):
if cfg1.has_option("FLASH_CFG", value_key[i]) and cfg2.has_option(section, value_key[i]) :
tmp_value = cfg1.get("FLASH_CFG", value_key[i])
bflb_utils = bl_utils()
bflb_utils.Update_Cfg(cfg2, section, value_key[i], tmp_value)
cfg2.write(file, "w+")
def bl_flash_loader_list(self, chipname, chiptype, bh_cfg_file):
eflash_loader_cfg = os.path.join(app_path, bin_build_out_path, "eflash_loader_cfg.ini")
cfg = BFConfigParser()
cfg.read(eflash_loader_cfg)
if cfg.has_option("FLASH_CFG", "flash_id"):
flash_id_str = cfg.get("FLASH_CFG", "flash_id")
if type(flash_id_str) is str:
flash_id_list = flash_id_str.split(',')
return flash_id_list
elif type(flash_id_str) is list:
return flash_id_str
# for flash_id in flash_id_list:
# print("========= chip flash id: %s =========" % flash_id)
# if chiptype == "bl602":
# if self.update_flash_cfg_do(chipname, chiptype, flash_id, bh_cfg_file, False, "BOOTHEADER_CFG") == False:
# error = "flash_id:" + flash_id + " do not support"
# return error
# elif chiptype == "bl60x":
# if self.update_flash_cfg_do(chipname, chiptype, flash_id, bh_cfg_file, False, "BOOTHEADER_CPU0_CFG") == False:
# error = "flash_id:" + flash_id + " do not support"
# return error
else:
error = "Do not find flash_id in eflash_loader_cfg.ini"
return error
def bl_flash_update(self, chipname, chiptype, bh_cfg_file, flash_id):
print("========= chip flash id: %s =========" % flash_id)
if chiptype == "bl602":
if self.update_flash_cfg_do(chipname, chiptype, flash_id, bh_cfg_file, False, "BOOTHEADER_CFG") == False:
error = "flash_id:" + flash_id + " do not support"
return error
elif chiptype == "bl60x":
if self.update_flash_cfg_do(chipname, chiptype, flash_id, bh_cfg_file, False,
"BOOTHEADER_CPU0_CFG") == False:
error = "flash_id:" + flash_id + " do not support"
return error
def bl_flash_loader(self, chipname, chiptype, bh_cfg_file):
eflash_loader_cfg = os.path.join(app_path, bin_build_out_path, "eflash_loader_cfg.ini")
cfg = BFConfigParser()
cfg.read(eflash_loader_cfg)
if cfg.has_option("FLASH_CFG", "flash_id"):
flash_id_str = cfg.get("FLASH_CFG", "flash_id")
flash_id_list = flash_id_str.split(',')
print('++++++++')
print(flash_id_list, type(flash_id_list))
for flash_id in flash_id_list:
print(flash_id)
print("========= chip flash id: %s =========" % flash_id)
if chiptype == "bl602":
if self.update_flash_cfg_do(chipname, chiptype, flash_id, bh_cfg_file, False, "BOOTHEADER_CFG") == False:
error = "flash_id:" + flash_id + " do not support"
return error
elif chiptype == "bl60x":
if self.update_flash_cfg_do(chipname, chiptype, flash_id, bh_cfg_file, False, "BOOTHEADER_CPU0_CFG") == False:
error = "flash_id:" + flash_id + " do not support"
return error
else:
error = "Do not find flash_id in eflash_loader_cfg.ini"
return error
if __name__ == '__main__':
abs_path = os.path.abspath('..')
app_path = os.path.join(abs_path, "customer_app", sys.argv[1])
demo_name = sys.argv[1]
chip_name = sys.argv[2].lower()
default_conf_path = chip_name
eflash_loader_cfg_org = bl_find_file("eflash_loader_cfg", ".conf")
eflash_loader_cfg = os.path.join(app_path, bin_build_out_path, "eflash_loader_cfg.ini")
shutil.copy(eflash_loader_cfg_org, eflash_loader_cfg)
# 找到efuse_bootheader_cfg
f_org = bl_find_file("efuse_bootheader_cfg", ".conf")
f = os.path.join(app_path, bin_build_out_path, "efuse_bootheader_cfg.ini")
# if os.path.isfile(f) == False:
shutil.copy(f_org, f)
# 选择flash型号
flash_sele = bl_flash_select()
flashid_list = flash_sele.bl_flash_loader_list(chip_name, chip_name, f)
pt_file_list = bl_find_file_list("partition_cfg_", ".toml")
ro_list = bl_find_file_list(bl_factory_params_file_prefix, ".dts")
img_boot2_file_list = bl_find_file_list("blsp_boot2_", ".bin")
arrange_group_list = list(itertools.product(pt_file_list, ro_list, img_boot2_file_list, flashid_list))
for group in arrange_group_list:
# 找到partition
# pt_file = bl_find_file("partition_cfg_", ".toml")
pt_file = group[0]
pt_name = pt_file.split("partition_cfg_")
pt_name = pt_name[1].split('.toml')
pt_name = 'pt{}'.format(pt_name[0])
pt_helper = PtCreater(pt_file)
pt_helper.create_pt_table(os.path.join(app_path, bin_build_out_path, "partition.bin"))
pt_parcel = pt_helper.construct_table()
# flashid
flash_sele.bl_flash_update(chip_name, chip_name, f, group[3])
flash_id_name = group[3]
#找到device_tree
# ro = bl_find_file(bl_factory_params_file_prefix, ".dts")
ro = group[1]
xtal = ro.split("IoTKitA_")
xtal = xtal[1].split(".dts")
xtal = xtal[0]
dts_name = 'dts{}'.format(xtal)
img_gen = bl_whole_img_generate()
img_gen.bl_fw_boot_head_gen(True, xtal, f, False, chip_name, chip_name)
#找到boot2
# img_boot2_file = bl_find_file("blsp_boot2_", ".bin")
img_boot2_file = group[2]
boot2_name = img_boot2_file.split("blsp_boot2_")
boot2_name = boot2_name[1].split('.bin')
boot2_name = 'boot2{}'.format(boot2_name[0])
file_finally_name = '{}_{}_{}_{}'.format(dts_name, pt_name, boot2_name, flash_id_name)
img_gen.bl_image_gen("boot2", img_boot2_file)
img_gen.bl_fw_boot_head_gen(False, xtal, f, False, chip_name, chip_name)
img_gen.bl_image_gen("fw", os.path.join(app_path, "build_out", demo_name + ".bin"))
img_ota = bl_img_ota()
img_ota.bl_mfg_ota_bin_gen(chip_name, chip_name, None)
img_gen.bl_whole_flash_bin_create(True, True, ro, pt_parcel, None, None, "2M")