From 9cd262ed579cdf8396af7decc5d4efe36a079439 Mon Sep 17 00:00:00 2001 From: Emil Lerch Date: Thu, 20 Apr 2023 14:04:18 -0700 Subject: [PATCH] code starts up --- .gitignore | 1 + config.py | 219 ++ libs/__init__.py | 82 +- libs/base.py | 7 - libs/base/bflb_base_eflash_loader.py | 2205 +++++++++++ libs/base/bflb_efuse_boothd_create.py | 241 ++ libs/base/bflb_flash_select.py | 170 + libs/base/bflb_img_create.py | 179 + libs/base/bflb_img_loader.py | 787 ++++ libs/base/bflb_serial.py | 714 ++++ libs/base/bl602/bootheader_cfg_keys.py | 331 ++ libs/base/bl602/cklink_load_cfg.py | 12 + libs/base/bl602/flash_select_do.py | 64 + libs/base/bl602/img_create_do.py | 524 +++ libs/base/bl602/jlink_load_cfg.py | 12 + libs/base/bl602/openocd_load_cfg.py | 12 + libs/base/bl616/bootheader_cfg_keys.py | 482 +++ libs/base/bl616/chiptype_patch.py | 10 + libs/base/bl616/cklink_load_cfg.py | 12 + libs/base/bl616/flash_select_do.py | 147 + libs/base/bl616/img_create_do.py | 753 ++++ libs/base/bl616/jlink_load_cfg.py | 12 + libs/base/bl616/openocd_load_cfg.py | 12 + libs/base/bl702/bootheader_cfg_keys.py | 343 ++ libs/base/bl702/chiptype_patch.py | 62 + libs/base/bl702/cklink_load_cfg.py | 12 + libs/base/bl702/flash_select_do.py | 64 + libs/base/bl702/img_create_do.py | 428 +++ libs/base/bl702/jlink_load_cfg.py | 12 + libs/base/bl702/openocd_load_cfg.py | 12 + libs/base/bl702l/bootheader_cfg_keys.py | 391 ++ libs/base/bl702l/chiptype_patch.py | 62 + libs/base/bl702l/cklink_load_cfg.py | 12 + libs/base/bl702l/flash_select_do.py | 151 + libs/base/bl702l/img_create_do.py | 438 +++ libs/base/bl702l/jlink_load_cfg.py | 12 + libs/base/bl702l/openocd_load_cfg.py | 12 + libs/base/bl808/bootheader_cfg_keys.py | 614 +++ libs/base/bl808/chiptype_patch.py | 10 + libs/base/bl808/cklink_load_cfg.py | 12 + libs/base/bl808/flash_select_do.py | 153 + libs/base/bl808/img_create_do.py | 950 +++++ libs/base/bl808/jlink_load_cfg.py | 12 + libs/base/bl808/openocd_load_cfg.py | 12 + libs/base/wb03/bootheader_cfg_keys.py | 645 ++++ libs/base/wb03/chiptype_patch.py | 10 + libs/base/wb03/cklink_load_cfg.py | 12 + libs/base/wb03/flash_select_do.py | 147 + libs/base/wb03/img_create_do.py | 766 ++++ libs/base/wb03/jlink_load_cfg.py | 12 + libs/base/wb03/openocd_load_cfg.py | 12 + pylink/__init__.py | 21 - pylink/binpacker.py | 57 - pylink/decorators.py | 52 - pylink/enums.py | 528 --- pylink/errors.py | 44 - pylink/jlink.py | 4629 ----------------------- pylink/jlock.py | 114 - pylink/library.py | 346 -- pylink/registers.py | 206 - pylink/structs.py | 907 ----- pylink/threads.py | 45 - pylink/util.py | 157 - requirements.txt | 7 + 64 files changed, 12325 insertions(+), 7154 deletions(-) create mode 100644 config.py delete mode 100644 libs/base.py create mode 100644 libs/base/bflb_base_eflash_loader.py create mode 100644 libs/base/bflb_efuse_boothd_create.py create mode 100644 libs/base/bflb_flash_select.py create mode 100644 libs/base/bflb_img_create.py create mode 100644 libs/base/bflb_img_loader.py create mode 100644 libs/base/bflb_serial.py create mode 100644 libs/base/bl602/bootheader_cfg_keys.py create mode 100644 libs/base/bl602/cklink_load_cfg.py create mode 100644 libs/base/bl602/flash_select_do.py create mode 100644 libs/base/bl602/img_create_do.py create mode 100644 libs/base/bl602/jlink_load_cfg.py create mode 100644 libs/base/bl602/openocd_load_cfg.py create mode 100644 libs/base/bl616/bootheader_cfg_keys.py create mode 100644 libs/base/bl616/chiptype_patch.py create mode 100644 libs/base/bl616/cklink_load_cfg.py create mode 100644 libs/base/bl616/flash_select_do.py create mode 100644 libs/base/bl616/img_create_do.py create mode 100644 libs/base/bl616/jlink_load_cfg.py create mode 100644 libs/base/bl616/openocd_load_cfg.py create mode 100644 libs/base/bl702/bootheader_cfg_keys.py create mode 100644 libs/base/bl702/chiptype_patch.py create mode 100644 libs/base/bl702/cklink_load_cfg.py create mode 100644 libs/base/bl702/flash_select_do.py create mode 100644 libs/base/bl702/img_create_do.py create mode 100644 libs/base/bl702/jlink_load_cfg.py create mode 100644 libs/base/bl702/openocd_load_cfg.py create mode 100644 libs/base/bl702l/bootheader_cfg_keys.py create mode 100644 libs/base/bl702l/chiptype_patch.py create mode 100644 libs/base/bl702l/cklink_load_cfg.py create mode 100644 libs/base/bl702l/flash_select_do.py create mode 100644 libs/base/bl702l/img_create_do.py create mode 100644 libs/base/bl702l/jlink_load_cfg.py create mode 100644 libs/base/bl702l/openocd_load_cfg.py create mode 100644 libs/base/bl808/bootheader_cfg_keys.py create mode 100644 libs/base/bl808/chiptype_patch.py create mode 100644 libs/base/bl808/cklink_load_cfg.py create mode 100644 libs/base/bl808/flash_select_do.py create mode 100644 libs/base/bl808/img_create_do.py create mode 100644 libs/base/bl808/jlink_load_cfg.py create mode 100644 libs/base/bl808/openocd_load_cfg.py create mode 100644 libs/base/wb03/bootheader_cfg_keys.py create mode 100644 libs/base/wb03/chiptype_patch.py create mode 100644 libs/base/wb03/cklink_load_cfg.py create mode 100644 libs/base/wb03/flash_select_do.py create mode 100644 libs/base/wb03/img_create_do.py create mode 100644 libs/base/wb03/jlink_load_cfg.py create mode 100644 libs/base/wb03/openocd_load_cfg.py delete mode 100644 pylink/__init__.py delete mode 100644 pylink/binpacker.py delete mode 100644 pylink/decorators.py delete mode 100644 pylink/enums.py delete mode 100644 pylink/errors.py delete mode 100644 pylink/jlink.py delete mode 100644 pylink/jlock.py delete mode 100644 pylink/library.py delete mode 100644 pylink/registers.py delete mode 100644 pylink/structs.py delete mode 100644 pylink/threads.py delete mode 100644 pylink/util.py diff --git a/.gitignore b/.gitignore index 4b04439..fad5296 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ bin/ lib/ lib64 pyvenv.cfg +log/ diff --git a/config.py b/config.py new file mode 100644 index 0000000..5d25352 --- /dev/null +++ b/config.py @@ -0,0 +1,219 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: config.py +import os, sys +try: + from version import * +except ImportError: + version = '1.0.4' + +chip_name = 'tg7100c' +if getattr(sys, 'frozen', False): + app_path = os.path.dirname(sys.executable) +else: + app_path = os.path.dirname(__file__) +try: + import changeconf as cgc + conf_sign = True +except ImportError: + cgc = None + conf_sign = False + +obj_cklink = None +if not conf_sign: + back_color = '#B3DCFB' + list_chip = ['BL602/604','BL702/704/706','BL702L','BL808','BL606P','BL616/618'] + type_chip = ('bl602', 'bl602') + dict_chip = { + 'BL561/563': ('bl56x', 'bl60x'), + 'BL606/608': ('bl60x', 'bl60x'), + 'BL562/564': ('bl562', 'bl602'), + 'BL602/604': ('bl602', 'bl602'), + 'BL702/704/706': ('bl702', 'bl702'), + 'BL702L': ('bl702l', 'bl702l'), + 'BL808': ('bl808', 'bl808'), + 'BL606P': ('bl606p', 'bl808'), + 'BL616/618': ('bl616', 'bl616'), + 'WB03': ('wb03', 'wb03')} + dict_chip_cmd = { + 'bl56x': 'bl60x', + 'bl60x': 'bl60x', + 'bl562': 'bl602', + 'bl602': 'bl602', + 'bl702': 'bl702', + 'bl702l': 'bl702l', + 'bl808': 'bl808', + 'bl606p': 'bl808', + 'bl616': 'bl616', + 'wb03': 'wb03'} + flash_dict = { + 'bl56x': 'bl60x', + 'bl60x': 'bl60x', + 'bl562': 'bl602', + 'bl602': 'bl602', + 'bl702': 'bl702', + 'bl702l': 'bl702l', + 'bl808': 'bl808', + 'bl606p': 'bl808', + 'bl616': 'bl616', + 'wb03': 'wb03'} + bl_factory_params_file_prefix = 'bl_factory_params_' +else: + dict_chip = cgc.dict_chip + dict_chip_cmd = cgc.dict_chip_cmd + list_chip = cgc.list_chip + type_chip = cgc.type_chip + back_color = cgc.back_color + bl_factory_params_file_prefix = cgc.show_text_first_value + +def read_version_file(file_path): + version_dict = {} + with open(file_path, 'r', encoding='utf-8') as fp: + for line in fp.readlines(): + line_list = line.strip().split('=') + version_dict[line_list[0].strip()] = line_list[1].strip() + + return version_dict + + +xtal_type = {} +xtal_type_ = {} +pll_clk = {} +encrypt_type = {} +key_sel = {} +sign_type = {} +cache_way_disable = {} +flash_clk_type = {} +crc_ignore = {} +hash_ignore = {} +img_type = {} +boot_src = {} +cpu_type = {} +xtal_type['bl60x'] = [ + 'None','32M','38.4M','40M','26M','52M'] +xtal_type_['bl60x'] = ['XTAL_' + item for item in xtal_type['bl60x']] +pll_clk['bl60x'] = ['160M', 'Manual'] +encrypt_type['bl60x'] = ['None', 'AES128', 'AES256', 'AES192'] +key_sel['bl60x'] = ['0', '1', '2', '3'] +sign_type['bl60x'] = ['None', 'ECC'] +cache_way_disable['bl60x'] = ['None','OneWay','TwoWay','ThreeWay','FourWay'] +flash_clk_type['bl60x'] = ['XTAL', 'Manual'] +crc_ignore['bl60x'] = ['False', 'True'] +hash_ignore['bl60x'] = ['False', 'True'] +img_type['bl60x'] = ['CPU0','CPU1','SingleCPU','BLSP_Boot2','RAW'] +boot_src['bl60x'] = ['Flash', 'UART/SDIO'] +cpu_type['bl60x'] = ['CPU0', 'CPU1'] +xtal_type['bl602'] = [ + 'None','24M','32M','38.4M','40M','26M','RC32M'] +xtal_type_['bl602'] = ['XTAL_' + item for item in xtal_type['bl602']] +pll_clk['bl602'] = ['160M', 'Manual'] +encrypt_type['bl602'] = ['None', 'AES128', 'AES256', 'AES192'] +key_sel['bl602'] = [ + '0'] +sign_type['bl602'] = ['None', 'ECC'] +cache_way_disable['bl602'] = ['None','OneWay','TwoWay','ThreeWay','FourWay'] +flash_clk_type['bl602'] = ['XTAL', 'Manual'] +crc_ignore['bl602'] = ['False', 'True'] +hash_ignore['bl602'] = ['False', 'True'] +img_type['bl602'] = ['SingleCPU', 'RAW'] +boot_src['bl602'] = ['Flash', 'UART/SDIO'] +xtal_type['bl702'] = [ + 'None', '32M', 'RC32M'] +xtal_type_['bl702'] = ['XTAL_' + item for item in xtal_type['bl702']] +pll_clk['bl702'] = ['144M', 'Manual'] +encrypt_type['bl702'] = ['None', 'AES128', 'AES256', 'AES192'] +key_sel['bl702'] = [ + '1'] +sign_type['bl702'] = ['None', 'ECC'] +cache_way_disable['bl702'] = ['None','OneWay','TwoWay','ThreeWay','FourWay'] +flash_clk_type['bl702'] = ['XCLK', 'Manual'] +crc_ignore['bl702'] = ['False', 'True'] +hash_ignore['bl702'] = ['False', 'True'] +img_type['bl702'] = ['SingleCPU', 'RAW'] +boot_src['bl702'] = ['Flash', 'UART/USB'] +xtal_type['bl702l'] = [ + 'None', '32M', 'RC32M'] +xtal_type_['bl702l'] = ['XTAL_' + item for item in xtal_type['bl702l']] +pll_clk['bl702l'] = ['128M', 'Manual'] +encrypt_type['bl702l'] = ['None', 'AES128', 'AES256', 'AES192'] +key_sel['bl702l'] = [ + '1'] +sign_type['bl702l'] = ['None', 'ECC'] +cache_way_disable['bl702l'] = ['None','OneWay','TwoWay','ThreeWay','FourWay'] +flash_clk_type['bl702l'] = ['XCLK', 'Manual'] +crc_ignore['bl702l'] = ['False', 'True'] +hash_ignore['bl702l'] = ['False', 'True'] +img_type['bl702l'] = ['SingleCPU', 'RAW'] +boot_src['bl702l'] = ['Flash', 'UART/USB'] +xtal_type['bl808'] = [ + 'None','24M','32M','38.4M','40M','26M','RC32M','Auto'] +xtal_type_['bl808'] = ['XTAL_' + item for item in xtal_type['bl808']] +pll_clk['bl808'] = ['WIFIPLL 320M', 'Manual'] +encrypt_type['bl808'] = ['None','AES CTR128','AES CTR256','AES CTR192','AES XTS128','AES XTS256','AES XTS192'] +key_sel['bl808'] = ['0', '1', '2', '3'] +sign_type['bl808'] = ['None', 'ECC'] +cache_way_disable['bl808'] = ['None','OneWay','TwoWay','ThreeWay','FourWay'] +flash_clk_type['bl808'] = ['XTAL', 'Manual'] +crc_ignore['bl808'] = ['False', 'True'] +hash_ignore['bl808'] = ['False', 'True'] +img_type['bl808'] = ['SingleCPU', 'RAW'] +boot_src['bl808'] = ['Flash', 'UART/USB'] +cpu_type['bl808'] = ['Group0', 'Group1'] +xtal_type['bl606p'] = [ + 'None','24M','32M','38.4M','40M','26M','RC32M','Auto'] +xtal_type_['bl606p'] = ['XTAL_' + item for item in xtal_type['bl808']] +pll_clk['bl606p'] = ['WIFIPLL 320M', 'Manual'] +encrypt_type['bl606p'] = ['None','AES CTR128','AES CTR256','AES CTR192','AES XTS128','AES XTS256','AES XTS192'] +key_sel['bl606p'] = ['0', '1', '2', '3'] +sign_type['bl606p'] = ['None', 'ECC'] +cache_way_disable['bl606p'] = ['None','OneWay','TwoWay','ThreeWay','FourWay'] +flash_clk_type['bl606p'] = ['XTAL', 'Manual'] +crc_ignore['bl606p'] = ['False', 'True'] +hash_ignore['bl606p'] = ['False', 'True'] +img_type['bl606p'] = ['SingleCPU', 'RAW'] +boot_src['bl606p'] = ['Flash', 'UART/USB'] +cpu_type['bl606p'] = ['Group0', 'Group1'] +xtal_type['bl616'] = [ + 'None','24M','32M','38.4M','40M','26M','RC32M','Auto'] +xtal_type_['bl616'] = ['XTAL_' + item for item in xtal_type['bl616']] +pll_clk['bl616'] = ['WIFIPLL 320M', 'Manual'] +encrypt_type['bl616'] = ['None','AES CTR128','AES CTR256','AES CTR192','AES XTS128','AES XTS256','AES XTS192'] +key_sel['bl616'] = ['0', '1', '2', '3'] +sign_type['bl616'] = ['None', 'ECC'] +cache_way_disable['bl616'] = ['None','OneWay','TwoWay','ThreeWay','FourWay'] +flash_clk_type['bl616'] = ['XTAL', 'Manual'] +crc_ignore['bl616'] = ['False', 'True'] +hash_ignore['bl616'] = ['False', 'True'] +img_type['bl616'] = ['SingleCPU', 'RAW'] +boot_src['bl616'] = ['Flash', 'UART/USB'] +xtal_type['wb03'] = [ + 'None','24M','32M','38.4M','40M','26M','RC32M','Auto'] +xtal_type_['wb03'] = ['XTAL_' + item for item in xtal_type['wb03']] +pll_clk['wb03'] = ['WIFIPLL 320M', 'Manual'] +encrypt_type['wb03'] = ['None','AES CTR128','AES CTR256','AES CTR192','AES XTS128','AES XTS256','AES XTS192'] +key_sel['wb03'] = ['0', '1', '2', '3'] +sign_type['wb03'] = ['None', 'ECC'] +cache_way_disable['wb03'] = ['None','OneWay','TwoWay','ThreeWay','FourWay'] +flash_clk_type['wb03'] = ['XTAL', 'Manual'] +crc_ignore['wb03'] = ['False', 'True'] +hash_ignore['wb03'] = ['False', 'True'] +img_type['wb03'] = ['SingleCPU', 'RAW'] +boot_src['wb03'] = ['Flash', 'UART/USB'] +try: + logo1 = 'iVBORw0KGgoAAAANSUhEUgAAANoAAADaCAYAAADAHVzbAAAACXBIWXMAAAsTAAALEwEAmpwYAAABNmlD\n Q1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjarY6xSsNQFEDPi6LiUCsEcXB4kygotupgxqQtRRCs1SHJ\n 1qShSmkSXl7VfoSjWwcXd7/AyVFwUPwC/0Bx6uAQIYODCJ7p3MPlcsGo2HWnYZRhEGvVbjrS9Xw5+8QM\n UwDQCbPUbrUOAOIkjvjB5ysC4HnTrjsN/sZ8mCoNTIDtbpSFICpA/0KnGsQYMIN+qkHcAaY6addAPACl\n Xu4vQCnI/Q0oKdfzQXwAZs/1fDDmADPIfQUwdXSpAWpJOlJnvVMtq5ZlSbubBJE8HmU6GmRyPw4TlSaq\n o6MukP8HwGK+2G46cq1qWXvr/DOu58vc3o8QgFh6LFpBOFTn3yqMnd/n4sZ4GQ5vYXpStN0ruNmAheui\n rVahvAX34y/Axk/96FpPYgAAAARnQU1BAACxnmFMQfcAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOgAAFII\n AAEVWAAAOpcAABdv11ofkAAAI1JJREFUeNrsnXe0JFd95z+3uvvleRPf5KgJkpAGSTMgCQ1JIBEt2QKZ\n 9a5NMGBg8bEJ3uNdMBtsI3vxsjbLWbMLxoAXg1ii1oDBCAkBQgihHBnFmZEmaeLL/bq76u4f99vzalrV\n L4d+b37fc+r0zOuuqlv3/r6/dH/3lvPeYzAYpheRdYHBYEQzGIxoBoPBiGYwGNEMBiOawWAwohkMRjSD\n wWBEMxiMaAaDEc1gMBjRDAYjmsFgRDMYDEY0g8GIZjAYjGgGgxHNYDCiGQwGI5rBYEQzGAxGNIPBiGYw\n GNEMBoMRzWAwohkMRjSDwWBEMxiMaAaDwYhmMBjRDAYjmsFgMKIZDEY0g8FgRDMYjGgGgxHNYDAY0QwG\n I5rBYEQzGAxGNIPBiGYwGIxoBoMRzWAwohkMBiOawTBHkN953Y+sF2YXDsgBzcACoA3IA0uBdfr7SmB1\n zTlFYA/QB3Tr30WgDPTrKAEx4K2bZ5lo1gWzQqw80CoyrQQ2AucDFwDPE8EmMjZ9wJPAE8Bd+jwEHACO\n inwVkc9gRJuX5CoA7cBaYDtwIXAp8EKgZYru0wE8X8c1+lsM3AvcBuwGHgMeB44AgyKewYg252PgBbJQ\n O4CLgReLCG6G2pADdupAbuZtsnh3Aw/L6vWZpTvziBYprvBzuF+XyR18CXClLFcj9PdC4LU6isDtwI+A\n O1KkK8/hvm9I2Wk0ohWADTpOys3pmUODXADWAJcBlwOvB1Y1cHtbgJfrOAn8APgecJ/iu945RDineHeL\n FMijst5GtAwhvQJ4l9ysg8DXgS8okG90gq0EXgZcDfyG/jaXsAh4k45fAP8MfB94RG6lb3CS7QTeIQXX\n B3wT+LzkyIiWwhrggyIbwHq5W0uBvwJONKiLuELu4a8DVynhMddxiY6raqxcb4O2dwfwMeAVqb9dKJJ9\n oRGURCMRbSmwOMPf/gBhPuhjwECDtDUnC3YJ8EbgVYrJ5hteoONq4LvA/wMekMVopDbWkqyKLYR5yKIR\n bRgDKRclnZFrBv4AOA783SyTLaeYayfwm3IV1zL/cb6OK0S2bxOmCgYb0JJV4WWBGyKT2khEOwrsIzvt\n vRj4EJAAnyNMvM4kIhHshbJgLyZMMp9p2AlcJMJ9k5CtfGyWCLcD+Ms6JKvK08OEDOrsu0CrXvHWRhnE\n ogj1clmxWnTITSirA4szSLBXAL+vRM3LlDg4U+EIWeFdhEqWVhGth5mZ/HZy2f9CLns9fEfJkD4j2nNN\n /RFgK6EMKQvt6uQWQvr55DRa+tUi2HuBd0sBLMaQduk3EqYyLiTUaMYS7NI03bMDeA3wp4TsYj0cAj5O\n mBvEiPZc9Mjk7wKWjDDAl0qr9gDPAkNTdP924Gzg1cB7gHcawUZFC7BJY7aTkIWtFj0PMjUZvxywjZC+\n /5AsaT1UFMt/YQrlYt4RDeBpxWAXS4PVc+nOlXVbLHeyTx3rJyAoK3W/N8hF/G2ReZHxaFwWbp0s3CVS\n WJ3yDgZl5SYyNtsIVSwfAH6X0bO73wb+XFatcfztHR+9uVEH7feAj0hDjoQYeEiB+X2Egtk9KRemmsX0\n Ke24QAO2WcdFOjYq5jBMDY4oWXKb4uqnNDYnM5IUXgq0Q2O+UWR9pSzl0jHc71bgfYQazoZCo9Y6DgGf\n 0b8/zMhlTDmGK9aPyyLuJiwN6SZkKquZzEREWi/Xcz3QZeSaNnTpuJRQcHBAxNsrt9/XEK2ZULhwlsZn\n JdA0hvvEhEn1v2hEkjUy0ZA1+oxI98eEycfRsERH1Ycvc/q8nBcxc8aBGUUki7SUsESIOhYtz/hX/fcC\n 3yBUDz3SqB3Q6MtkSoR5s0PAHwIvHaOGq6JgMt6wmIqxeQb4e+Cz+jdGtIkjVoD7JPB24Lc4fVm/4cxD\n rLjvM8C3mPkChnlJtCoeImST7gfeJr+/xWTujMMeQhnYPwD3zJVGz7UV1ifVwXcRag2vSfn8hvmNY8CP\n gS8DNzF9xQpGtBQeJKSKfyLCXUaoJrEkx/zDUcKeJ98grJHbNxcfYi7vGdIvzXYfw5XllxJKuNabfE4d\n 0pOQM4REocIDhPnRnxBK7ubsnibzYXOeo8AtwC9FsO2EKo8NhEqFzUzdWrFuwvxPL2FeqEcujSeU/pxk\n eEI8T5gXWkFYSrO5EQmk/tvn4RCek0DF4wcJ1RztDloqHiLnWiLHEkJN4woPC8AvcbhTXsQkyDikdlS3\n ytut8XyIUGKXzHUhnU+7YPUT5lEeISxS7BTZtknQlxBKqjr1uYQwZ5Ok5M6JTMdFnB6GNyI9Tqh06NFv\n jurfJyVjiQSmum9jnjAVsUKE30aYC7yUUIQ7ewRzHMtH3HxioPLwycHyEx63J+/cwXxEt4e4ELlyzrkY\n yJdiXxiKE/I511xJ/GI87cAq5+hc0ta0LBf5lsi5ZXgKuZzryDkWxp5YCqeLUOmR6P9VQlU3ej2mvjwo\n Qj2mkKCfBlneYkQbnXT9GsA7NMjVTUs7UmTLIlovwyVC/RKOWL+r7vo7HuV9UDFGRNiB6lxZ3FcTKtFn\n Es84577pE//j/T3FO3esX3zwBRsWlXuLMZGDyAUbl3MQydxVPFRiTy7nSBJ/wOvJI4f7yp0HchUfu5xz\n OTy5SuJbFrcVFjTnowSIfPAk2hguGiiLaEPqz2o/V/T/ebuj8pmwr2Oioyx36PgUXbdJxG0SeXMpQXEp\n i9ireydyN2/T8U+ETXzeKfJNJ8rA9cA/OrjdQ+/B7hILWwtcvm0ZR/tKeE+HlE+zP929jBLvByPnqjtK\n 9QIk3vumvKskgUPlHNBdrPRff8f+Y+sXt1S11x6LcM8cok0HWglzea9NWcraleGeUNh8WAJXjT3uFwmf\n BD5J2FfxvcC/YXo2Vb0L+BRh0v+Ic3Civ8wrzl7KFecuLRzqKV49UEpe7xyLCcuEaitvIrwfwLlqbeI+\n oNt7f+S81Qt6gR4P/XnckaE4eTTnXOmf7j/IwpaCbfhvRJsSa/Zywi5RoyGWC9qrOOQBwnzQ9+RW3iYS\n /pRQZva8KWpjH2GF8d/rnglAsZywc8NCXrd9Be1N+bh/KPYeXoIfpZbUn6JNdcnLULGclKpuYClMHv/Z\n jg0LHyrkHF+/+wAL2wqp085sNOJ6tLli0a4GzhvDbyNC9rGTsAphO2F7up2ydntFivtk3RaIbJN5pdat\n hELsz+v6p8S9HHuet2oB29csoGcw9s7xtAuu78WMrf6wQKjIadczLSEUCzcDt3h4amVnC0s7mrhrbw+t\n BXszGNj70SYb+020z5cS5v1epGQBcifvBN5PWIv38ASu/TjwR8DvEGoAT1YDxjjxDJZjBssxQ+WE2HuU\n ++gj7K9x3yT7YxGwxnuIvef5azq5dscqTgyWq/cx19EwK6gu2akVw2eBLxLmBq8B3kxYAFlvzdygCHY9\n 8FVgP9q4KPGeUiWhHHs2d7Wza8ti+ooVuhY0Uyydtqvf44SNUnMi/HhT663gjzvnjqW10AXrOokix9fu\n OsCi1vwZHbMZ0WaXaPVS2hXCfNLfijzbgFd7zwqRbkhx3QHgFufYDRzznsFSHAxtHHtWL27mled0MViK\n aS5EdLbk6WgOQ/5sXzEdfvUAfwN8OtW28cABiUu9J8ETpgtWLWzmyuct4+ZHjrKg5cwlmxGtsTFUipNn\n CrnoGQd3lOIkj6dZclyS5el3DhI8i1qbuHb7KkqVBO+hkHe0N+doa8rhvacc+9NYfmrZuccTJo67p1qX\n OGBbVwfOO364+widzWcm2YxoDYhK4vHeU4o91160iht/dYS+Ytz3hotWkc+5THPi8eSco60pR2shJzH3\n VGJf1wRVZSBy7FRipzr/N14UCPOTt5GxKY7Hs21lOzi46ZEjZ6RlM6I1GPqHYl7//OUsbW8iTjztTTmu\n fv4KEg/tzbkRJ9q8kh7jxOWEHX+3TaLZjjAv+K5sooV4cduKdvCem3YfPeXCGtEMM45iOeZ125ezdnEr\n +ODPeQ+tTblqLNXkQ91mJ5Nb9FpW4uNlhMqUrUx+svwAoRY0Wwl4kW1lBx740e5jtDfnjGiG2cmOtOSj\n kI73pwlpB2Hf/xcR5uDWEOom/QRvE8NwydUUND1R8ubQqNmfxHPOqg7A8eNHj55SIkY0w8zCgdMhrJXV\n eRehSDfH1M1/VjOfk2qx9xwjVJ8MjOWGkXMUcu6MitOMaA2EnHP09pdpwlGOPQs7CuQit5qwzOYWQilX\n 3FhqgZxzPO09N471pFIlYf2SVt790g08fLCXWx87Pu8tmxGtQTBUSXjJ5iUsaW+iooRGd1+Zpnx0r3O8\n p7UlX2mkCgsHHO8p0VSIXEdrftwvZ3cupDujM6RsxIjWKNYscqfWgKXGpjBUTmLn8EPlUsOpfO/JDw4l\n cXGoVF66sGki5+O0Ds4zPUsXjGiGUyhWEl66eTFdw9as1TmuIKxTG7e1mCFEzuFzET8HfnairzShNq5s\n b2bn+oXc+0wPucjN27pII1rjWIc0NhKWzOxyLpQ3NaIRJpSBTaoYuRwnbF0WFmHfu7+XCHDMP8IZ0RoT\n mxm5kLhR8AzhpRKTsrjFSsLWrna8dzx8uJeWfI6hSkIlSeZNDGdEa0x0MjfeG7AFeBXOfY1JbqYzWPFs\n XNrGWV1tNOci7tvfw57jA8RJqHaZ63wzojVMwHNaMuCQgydw5BneEKjR4Ai7XL0Zx93AryZ7MY8nTmAg\n jjlnRQc71i3k7me62X24H+89Tj3koTZxZEQzjEHIHPQNxSxtk+b23INz17nwfrBG3h2qCYhd2F5uSgPJ\n OPH0DJa5cPUCypWEZ04WKaig2jnHQCkm8dM/Ls6INn/Qkov4xd5umvMRyzuaSRJ/ohjH3yvFyZxYAl9N\n 5AzFUz+XfqgHlnc0saqz6dR9CjnHw4f6GSgn0+ZSOqAUJ5QqU+O2GtEaQVCB5nxEXzHGMURSdZMiOl0o\n Ho5p4N16ffDkksi5Xia2zGZEiU+8J0lxuJJ4tna1TWvcVsg5njxW5Kljg6csqRFtHrmQNVm2XS5sQwdh\n F61GdSFbXFg0ej1hK+9pR2Wa/cYwDFN3DyNaIyVEqhO2/pQy3wNsAnY1tIIIH2XCRj/3TLlVmwWFN1hO\n GChNnWtqu2A10OB2F8tUEh8ykGGAHwHeQ9gA9ZkGF+ACYRnPhrk+FoXIcainxIHuIQpTlN40i9ZAg/v4\n kUEWtubpbM6nV0o/CHyE8OqiKwhbDnRNUWjoCXN2K6foMV4o6/vEXFd6hVxELpq6pTxGtIZKiDhODlRo\n zefIudMihBPA/yW8D24V4Q01k0VM2ODnbOBaYEPNOriJPYZnqZ+VV6pNzRjkI0exktBTrEzpXJ0RrYGQ\n jxxPHB1kaVue9uYc8XPzjEd1PDCFt/0ZcJNzrI69d3Hsk1TcNd4wJAYOtjRFc/K9MM45huKEx48OcqS3\n REs+Mos2n63akf4ybU05nGOm9q7fW4jc3oFiTG8xntRErXOQ+Pyc3HM/HzkO9g5xuKdEWyGaUl1hRGvA\n wd53ooj3sHFJy6nt5crx9EhudUqhWEkYKicdwLrU3N24LgXkE0/Pyf7yPhxDc0rJeShEEZWKp2katlkw\n ojWkVYt4+mSRyEEhH+ETz5pFLVNe3+d9qJwvxzHFckI59udGjj8irB4ojzPOcoT5tHtd5K6bawkR56CU\n JPSX42mZCDeiNSgC2YJRSLwn9lNbSOs9wT0FBssxOeeIHJ3ARUx+j8eOudbfUeQYKsd0Fys05SIj2pmE\n 4dKf4E5OJSpJwooFTSzvaCI/zODFTH4NXKOuCB85CVJJ6BuKKUTTM7VsRJtzpJuqWDBHsZwwUIppzedI\n vF/rw6t+103y0kXCtMHcsWbOUYqTabNmRrQzGM5BfymmoynHouY85YQuH6YOviqijNcq5QgviP9ZnPiD\n c4dkUI5juovTZ82MaI2R+5g1NysfRQyUEvb3lEjwj3n4GBPfVNUBLnKub0VHoW8upPedC9v8HeotMVhO\n yE3jalIj2uySrAyzlwZ3DgbKCb2lGEJBcN9UxDuJ93NiHi1YMz/tJDOizS5ywFmE+sA+wjuhZ17YIk5t\n ETAZfuk4jmdP92ClOFcGwTk37SQzos1yfoPw6tzL5KrN2lhM4UqQn+L4k5xzRRteI1rDKFNCFX7XPHme\n MvAlUq/XNZyuhQyGqcDthBUGQ9YVRjTD9KAf+BfCWz8NRjTDNOEOWbPYusKIZpgeHAM+zxxfVW1EMzQy\n YpHsW3BGvcDTiGaYUXwT+ARTMNFtRDMYsnEj8FFgv3WFEc0wfZbsPzC1e5fMa9iEtWE86AG+DHyckMq3\n uMyIZphiPAh8lrDt97PWHUa0mUL1dUrz+R3nHniKMBn9JeAuwsJOgxFtRlDdF2O+kqwb2A38HPi+CHbU\n XEUj2kwjJuyF/zRhP/y5LIA5Wedn9UwH5CbeQXjJRg8N/MooI9r8xgDwGeC780AIIz3DIR19ej4rpzKi\n zToqwL06DIYxaTODwWBEMxiMaAaDwYhmMBjRDAYjmsFgMKIZDEY0g8FgRDMYjGgGgxHNYDAY0QwGI5rB\n cAZjpOr9JmA94SUMWa9KnexL9BxhKcYewkJDw+wjJ+Xra8YpYWaXzTi1I92W6iLbmNlfmpTLaJtX2/x4\n iOYI7+76AHAp0Jt6UF9DlMl0ZgLcSnjTpL2FZHZxLuEVUh0pgckT1qb9C2GR60wtcD0HeAnQRnhLDUAz\n Ya3cLcDjs0i2xcArgI0yQLH+dq/a1j8eokW60GWEl4cPpNzMJHXxqXh53osIewN+GltsOJuezb8C3ivh\n rkgR5oB9wC/0OVN4LfAnIldVJgqEhan7gcdmsa8uAD4EnKd+qgCLgP+lfhoX0fJyGxcBB3VyrsZ0+yki\n WgF4H/BL4E5sX4rZQBdwIdnvajumYyZJfy6wJOO7QZFttmQkB1wEnA201Hx3SO0bV4y2EHgesAo4wukb\n 0Tid1y1TWRZZRkOsuO/5un4aW4A3yPyWTe5nHJuA1XW++yFwcgbbskHtycoJ3K6YfrawGDg/g2T7ZCTG\n RbSq23gusFdEqwZ+Tlash/CanptEoPwYiZYHfksuSmfNPc8TAY+a3M84ttYR7jJhk56BGWzLOWpPljV7\n cIbbUoul4katvD9M2DUsmYhFW6kkyKB+l8h0LhT5bmJiW0LvA3YAV3D69EK7XNW5RrQFstJdZGdiI8Ua\n Rwnbtp3M0ODn6vmzdtTy6vO7gEenIY7NExJfCzK+OyJlO5Ou2hZgRR0Xdjez+0bRjfLyarFnNPc6X+dv\n MfCQBr4anyVyEQ+LYBMlxAkNYC2KIvZcQjPwJuAPJahZAunkMt+mIDpNtPWEPexfqd/EdVymBUoOPDUN\n RFsJbK7j/t/PzE69dMg1a8747glmN9uYUyKk1sXul0UbHC/RlgG7pKG7gdYaq1OUCT80wQZfDVzCcyfL\n d4uEcwmLgd+WRRsNJzOU04uAa+po8FoX7rgU31RjveLxrOKF23TfmUK1LVl4dIaTMrVor2P594kPpfES\n rVlaroUwb5EegDZdsJfheZax7Nab6HpXAP9R7kEaB4Bvj9bYBoMDto0gGGkcV1IhbR1apCE7x3D+z5Qo\n mg6ibQTW1vnugdE09RRjVZ2kTFHWfHAWx3uVLH+tQqruh+nHQ7S8SNYm4e9O/cZLKyfAlYSJbDdGosUK\n JF8j4azFF5RRmksoANvlAaTRq3jqYXkD7Ypz7skIrLdkZLD2KwFxXH2+BPiOXPapRqviwyyy72Vm586Q\n bCzP+PthubGzue//9jpJmocYw0s/aonWIg19vh5qsRhcrQKJpXHWKaYYK7x+X3vOAPDPwKdmWVtNBLEE\n I1fznN8DPqg4NJeKfWorX7oImT5X417+NfCP8iYSkaHE9GTbVsqqZo3lT6RsZzKptFNKPov0jzG7pVfb\n MpTqs8APxuLS5uu4RI/W+OZexFuhzlg8RY2/Ffgzst8aGUnrr1Dnt0noBhSAHteD1nutayRtvZnhCfaq\n u5sosH485Y6tk4JpSv0tkUW5X/fdqu8HpXl3ZSiUigZki4g2IMuwSW3pF0mvlNuWRp+usTXlqnfLhfMZ\n FnWZXJpWhqs5vM45KgGonneh7l9R3zyivl1Txyu5LyNp1SYFsVL9UC2RGtRzHtR9kwmSfmud756aZFJm\n kdq9pEY+hiR7xxmev+1S7FzQ9yf0/fIapYoU4DZCSVazvu/TeD+TDoXyNQTbALxKn4dr3MZKimD9+lvE\n 6Klfrwa0ZnzXrQFPY4nIvFMdf5bOrRKtqPsfVibqYbmdD2b41B8AXq1zfMqyDsly7EkJ3jXAv1WHpYm2\n CPifOvdNcgXLsv5rMpTUlYQ5wRZdaz9wgwbkdSmiLee51Q9LgT9IuUjteq5/l+qnLiWTLkr1T7VsKqfP\n k4TaxF8BP9ZzvF8CUdLz3iCF2lpnzPamMpybgRfruc5KeTRt+k2/iLZH7b1TrvLJcZChel0ysnr3TYBo\n eeCFhKmkc6T4lqbCHS85eFxEflD9cSVhnreaBX5A8fWWDMvflRqvKgkH1Q/3yuW/o5ZoOQXFWxiuBMml\n GpaXBfk7sbWV4bT/aEQrA28BXlDz3YWK9W7TdS5XFu8yuaitI7ioiTqqRwL1TeAfUgOyThYnK9DvlWCU\n UrHKBYTSGpfhIi6WRRotu+jU+V0156/RuWvGEDNtysjGHpGGfS1wlYS+2j/1qnJK0q7Xqo92SNCqz98s\n AVyWce79Iks78DvAr6t/FqU0dxZepHs+Q3jl0+cI9X9jwfl1xupZ4G7GN3+2XYrz9VIS7RmxcBUXiyjV\n OcPVOqeKJ/TMazISIc0ySlnPcrmU/CeA6/M1rsgmCfZhCXKV+dV5jbuA/62Hz43jwRN1/idrOnMDoUr7\n VkJR64fk7jXVyYDdTZi8vVyfrTpWqHO3AdfJhVmfEqwsQbo3pSTWqi1ZLxa8XYPwsgm4LCVp9kFGT+HX\n wzckZO8H3iF3s3ae6XG1s1XWbq36cIn+X/tce6WcLqvTRzfq9/8JeJsUh8uIr2+Wq7hDiqQgpbRYY3Ee\n YWXGd0bxfDpknQt1EiHjSQRdTZjXvDgjFV+WUt+n9l2iexb027Nq2lliuIB5YZ37PSmlEstjWMvw+/Mu\n Bj4K7M7XuC27ZNH2yYL5VEeURLD9E/TBbxCR1taQe4M04X8WybKSDl+TZnhKbXkLoRB5UY3L+Q6R4q80\n yEvqtGV3TaboQlmzrLmkR9UPZ02QKPsYLt2ptfSjZWyPSCm8SwmWlRm/+SXwYf2uXYP94Zr21t6nmj1e\n WueZ++U+vbOmj9PCf50SP71SctWJ97S23yWyHidMUdTDmhHis0cZ+xKq1wH/RePpMryY/y5ZOia5+2Pg\n jRleSfo5j8jCZRVc3wL8jax/Cfg14CM1FvEs4K351MU7Nfh3qmPyNUHwccUJE838nJ2hFWIJ4NvrpP29\n tOZfSpCqrsQXFcP9WkbW9LXSWmvrWN2K4pd0lnPTCAmeIVm/j+s3g3K5rqpxR07Il/+VLEtef/upBLo6\n /5gHXi4rkKtxUW6UEBTU53fJBX5HHZI9ImH5cUop3qD47ffrPE9RMcQiWf1a3KsxeWUdkg3KSn2O4SUh\n x3TOzoxztst9fWAEwpwrdyurrb9gbO/M3iSFdEEGyUrKbH8iFVocJrzj7ooRrNU+3ftSnrtS5S5Zq1tS\n sez1wEsle2mv44X5VOB4ntyjQVkCn7I6zTKR90yQZOcqu7gxY9DaGJ6Ty/LPv8RzaypPjpBSXSd3tGuE\n zrs9la3skIC0jCCUP5d7G4kc784g+R5Z7IPqs+qUyJDO+aFcl00SqqiG/F9T0uWExiOSe/bv68Qug7Io\n P6lxd/oZuTzuiAi6nOy6vYelUJbXOf9u4Cucvu6qoqmAvgyiNUuprCPMOWVhS53xqlr0yhiJdl4dC/2U\n pkxqEyr7NcYLR+irsvrD1bjN35IcxTVK+ViGmxznU5Zgoy7WU6Npyzo6FISf0O9HyzZWG3CetP8lGbFX\n US7FNXWIdlSD4zOyc1vq3LdtlMTDfg2eV7D8JmnvXJ3717ou9Yi5T1apHqoWdDXPnT/rkTI5kPGsLSNc\n 74EMD6NjhL6p3qtX45I1Z/W42hjVGdNfZGQTC4T51+V1zuml/jxpp9yrrPF/UAp+LGirk0FNNOZZymdr\n nWRQ1dV8WrLWlSG3BzISNB0a29pY885qCdUqmbwolU0klRJvlZW4NJVGHksCJJJ17Kjzm/uA/yNtt63O\n /MfqjMzcWyTsWdij9tUrjdoG/A8JwIWpBFAWDimJU9uZtdnJfsb+9s8tGQJ5uA7JqhammBHYFzIsnVOG\n 8KoR7n9IfbihjnA/KQJflZHAydWJpbYD/7pOP5bkyu+t054NGod6331EJC3UyfK2yWIdlKJbXfNckZ6j\n ds54vVLz9WT5aV33wox+7pQrX6uM3qwEU65GId6QT6Wkz07N3dTGSZEEs8DYK0KqQtOXMtnpuax9wH9T\n YuKLCpxrXcvl6ox++cQblP5/Wx1N/6Qym5eNYAmWy4IyBoXxEKdPpkeKAZZlEOXGMfTJQglqLWnuGUFz\n f0PtfWOGBr9WWv9mKaurgN+jfv3kCf1+YR2rt0fPcrMyZh/IENBdyoB+TUr3Yt3zgjoy8H3gy9RfdXBW\n nXOrFmfTKNMpeT3Te6W0L8ro301K1vyt+uB8ZSZHyiSfkFVbkSEneSmWQ4TKkAXAbyrXUBtL/zVwdzWz\n eBT4qtyKaAQLNRkkOro00DcokEz0+UFprx01WvulcgMPylfeXEeQnlCG6wZGnu9yY7TIgyJA2uVokpu5\n LCNL9+gYrrmOMJdYqHHNH6P+yoWikkEtcnXT1uU8JWkeU99sHSHTWm3nQY1BZx2iHZAV+q/6fF+NR7JE\n Y/UbIto6eUS5DJfxc8r07R1hLLbWcWFJpd7HMlZHlIxYrwRRS41SeqvClz5ZvbNGkIOKSLSoThKqGhL9\n qRIwzSJzbXz6SSVhevMaoHdrEKdrPZhXh3WKVJ9SnFRKBZHf0UBX46btKeE+V5k+V4dgXwG+K2IUlUDZ\n RagMqIduCdW6Oq7tCVndSs3Av6DGqifSqGOpXNjGc6sfjusZRqr1vEfW5Sbgd1N9k5fiOSsjWL9NSnNX\n KgN2QsK1uU48czilWI7L4/hlyqJW+2nZKLHNt5Us+IkIUC+eXyvhnyyeEoEGZEEeVHjxmpRF7tDYpadV\n vLyWg7KEy1LJtr1SIPVWNkQay6xqll8SNpv6rghLXoOwSI2brl2oChqAHyqW+RXPXRJT1nePAV+XpjtP\n Zr5LD+3UKUfUQQ+qk5+WNU5Sgvl2kfZSCXiz7vuU3NC7Fee9X9eunp+XQrhdbq2viQ8HUtmqvNr9Pca2\n xKdVvz+s6yxTcuHeUTJrifrl03JRz1bMfIHa3q5sV3VS/+e6/lvVf073vUcEyqWC+ZKUbUmZ1ZM1yui7\n 6ovPitDbRdRF8jQOqD+e1fV3M7zieDR56pBs7Nf9k3Eq73bJ1S0pj6BbJP+5+mmnvKTqKoWSFOg9Uka7\n Rfb1+s4pLn9E7nUi0pVqvL1qsf2zUk7HJVv3K/ewL50scTs+evN6acnpWiKe0yD/gOFV22NZGl/dAqBa\n htWsBxvSMajPZAS3pFWD2abr9eu8QbWpTTFbISUU1c07+yQspRrXcXnKolUrZw4yttUHC1MZrCqpe6U4\n xrPWLK9n61RbXCq7N6B+iUTkzlRs3Kfn6dB5PjVGsQSmZ4TxiOSStaamfYakdCrqg7GObzX1v7ymLeNB\n dW/QYwyvkawnQwv0nF7t7NNnrD7qSlm7svqhqab/su4/pGcuqR9KWWPpvLfd3QyG6YbtvW8wGNEMBiOa\n wWAwohkMRjSDwYhmMBiMaAaDEc1gMBjRDAYjmsFgRDMYDEY0g8GIZjAY0QwGgxHNYDCiGQwGI5rBYEQz\n GIxoBoPBiGYwGNEMBoMRzWAwohkMRjSDwWBEMxiMaAaDEc1gMBjRDAYjmsFgMKIZDEY0g8GIZjAYjGgG\n gxHNYDAY0QwGI5rBYEQzGAxGNIPBiGYwGNEMBoMRzWAwohkMBiOawWBEMxiMaAaDwYhmMBjRDAbDKfz/\n AQADByJ1+Dnq3AAAAABJRU5ErkJggg==' + logo2 = 'AAABAAEAICAAAAEAGADYAQAAFgAAAIlQTkcNChoKAAAADUlIRFIAAAAgAAAAIAgGAAAAc3p69AAAA\n AFzUkdCAK7OHOkAAAAEZ0FNQQAAsY8L/GEFAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABbUlEQVRYR2NgG\n AWjITAaAqMhMBoCJIaATusecaOWff+xYcOmvVdDV61iJtFIBgawYU17o/BpNGg94IrLYqyOaTxgic88n\n Ya9tUYte/+C1Ri07s0EGaLftK8cXZNR814nUixGV2tYv98Ew8yWvStA6nTbdyvB5Qxb9s2ixCKS9Tbvi\n 8YaQkbN+36QbBiONIHVnOa9n0hOIyANVp0bePXr9wto1a9is6/fz4HN8NDQVcwTt91in7//vsCq/S959\n u//z0KWZdg0IVto2LL3OUgNkH4EEjds3teGrGf+kQcHYJimDsBmePeO6996dt38D8N0dwDVLMTMOojCB\n xYF1Wsv/8eHq9ZehuRzagBsaSBtwemnaQvPvMeHQ1ddYaOG/ZDSEophIUAVg4k1hBQHBE099h+GAycfe\n UCsHXjVoTngKzDr9ROD9Vv2SFPdAaSUlFSxHGQIKZbC1FLNcrADmveeJwE7UdXyUcNGQ4CWIQAAiakrc\n tfuVAEAAAAASUVORK5CYII=' +except Exception: + logo1 = '' + logo2 = '' + +if conf_sign: + about_tool = '\n \n \n \n \n \n \n \n \n

{}

version: '.format(cgc.title) + version + '
\n


\n \n \n \n \n ' +else: + about_tool = ' \n \n \n \n \n \n \n \n \n \n \n

Bouffalo Lab Dev Cube

version: ' + version + '
jxtan@bouffalolab.com
\n


\n \n \n \n \n ' +DEFAULT_STYLE = '\nQProgressBar{\n border: 1px solid grey;\n border-radius: 5px;\n text-align: center\n}\n\nQProgressBar::chunk {\n background-color: grey;\n width: 1px;\n margin: 0.1px;\n}\n' +SUCCESS_STYLE = '\nQProgressBar{\n border: 1px solid grey;\n border-radius: 5px;\n text-align: center\n}\n\nQProgressBar::chunk {\n background-color: green;\n width: 1px;\n margin: 0.1px;\n}\n' +ERROR_STYLE = '\nQProgressBar{\n border: 1px solid grey;\n border-radius: 5px;\n text-align: center\n}\n\nQProgressBar::chunk {\n background-color: red;\n width: 1px;\n margin: 0.1px;\n}\n' +WARN_STYLE = '\nQProgressBar{\n border: 1px solid grey;\n border-radius: 5px;\n text-align: center\n}\n\nQProgressBar::chunk {\n background-color: orange;\n width: 1px;\n margin: 0.1px;\n}\n' +# okay decompiling ./config.pyc diff --git a/libs/__init__.py b/libs/__init__.py index 0c20ed1..7f18e7c 100644 --- a/libs/__init__.py +++ b/libs/__init__.py @@ -16,45 +16,45 @@ from .base import bflb_base_eflash_loader from .base import bflb_img_create from .base import bflb_serial from .base import bflb_img_loader -from base.bl602 import flash_select_do -from base.bl602 import bootheader_cfg_keys -from base.bl602 import jlink_load_cfg -from base.bl602 import cklink_load_cfg -from base.bl602 import openocd_load_cfg -from base.bl602 import img_create_do -from base.bl702 import chiptype_patch -from base.bl702 import flash_select_do -from base.bl702 import bootheader_cfg_keys -from base.bl702 import jlink_load_cfg -from base.bl702 import cklink_load_cfg -from base.bl702 import openocd_load_cfg -from base.bl702 import img_create_do -from base.bl808 import chiptype_patch -from base.bl808 import flash_select_do -from base.bl808 import bootheader_cfg_keys -from base.bl808 import jlink_load_cfg -from base.bl808 import cklink_load_cfg -from base.bl808 import openocd_load_cfg -from base.bl808 import img_create_do -from base.bl616 import chiptype_patch -from base.bl616 import flash_select_do -from base.bl616 import bootheader_cfg_keys -from base.bl616 import jlink_load_cfg -from base.bl616 import cklink_load_cfg -from base.bl616 import openocd_load_cfg -from base.bl616 import img_create_do -from base.wb03 import chiptype_patch -from base.wb03 import flash_select_do -from base.wb03 import bootheader_cfg_keys -from base.wb03 import jlink_load_cfg -from base.wb03 import cklink_load_cfg -from base.wb03 import openocd_load_cfg -from base.wb03 import img_create_do -from base.bl702l import chiptype_patch -from base.bl702l import flash_select_do -from base.bl702l import bootheader_cfg_keys -from base.bl702l import jlink_load_cfg -from base.bl702l import cklink_load_cfg -from base.bl702l import openocd_load_cfg -from base.bl702l import img_create_do +from .base.bl602 import flash_select_do +from .base.bl602 import bootheader_cfg_keys +from .base.bl602 import jlink_load_cfg +from .base.bl602 import cklink_load_cfg +from .base.bl602 import openocd_load_cfg +from .base.bl602 import img_create_do +from .base.bl702 import chiptype_patch +from .base.bl702 import flash_select_do +from .base.bl702 import bootheader_cfg_keys +from .base.bl702 import jlink_load_cfg +from .base.bl702 import cklink_load_cfg +from .base.bl702 import openocd_load_cfg +from .base.bl702 import img_create_do +from .base.bl808 import chiptype_patch +from .base.bl808 import flash_select_do +from .base.bl808 import bootheader_cfg_keys +from .base.bl808 import jlink_load_cfg +from .base.bl808 import cklink_load_cfg +from .base.bl808 import openocd_load_cfg +from .base.bl808 import img_create_do +from .base.bl616 import chiptype_patch +from .base.bl616 import flash_select_do +from .base.bl616 import bootheader_cfg_keys +from .base.bl616 import jlink_load_cfg +from .base.bl616 import cklink_load_cfg +from .base.bl616 import openocd_load_cfg +from .base.bl616 import img_create_do +from .base.wb03 import chiptype_patch +from .base.wb03 import flash_select_do +from .base.wb03 import bootheader_cfg_keys +from .base.wb03 import jlink_load_cfg +from .base.wb03 import cklink_load_cfg +from .base.wb03 import openocd_load_cfg +from .base.wb03 import img_create_do +from .base.bl702l import chiptype_patch +from .base.bl702l import flash_select_do +from .base.bl702l import bootheader_cfg_keys +from .base.bl702l import jlink_load_cfg +from .base.bl702l import cklink_load_cfg +from .base.bl702l import openocd_load_cfg +from .base.bl702l import img_create_do # okay decompiling ./libs/__init__.pyc diff --git a/libs/base.py b/libs/base.py deleted file mode 100644 index aef52ed..0000000 --- a/libs/base.py +++ /dev/null @@ -1,7 +0,0 @@ -# decompyle3 version 3.9.0 -# Python bytecode version base 3.7.0 (3394) -# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) -# [GCC 12.2.1 20220924] -# Embedded file name: - -pass -# okay decompiling ./libs/base.pyc diff --git a/libs/base/bflb_base_eflash_loader.py b/libs/base/bflb_base_eflash_loader.py new file mode 100644 index 0000000..9a4fb87 --- /dev/null +++ b/libs/base/bflb_base_eflash_loader.py @@ -0,0 +1,2205 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/bflb_base_eflash_loader.py +__doc__ = '\nCreated on 20220908\n\n@author: Dillon\n' +import os, lzma, ecdsa, config as gol +from libs.bflb_utils import * +from libs.bflb_configobj import BFConfigParser +from libs import bflb_ecdh +from libs import bflb_interface_jlink +from libs import bflb_interface_cklink +from libs import bflb_interface_openocd +from libs.base import bflb_img_loader +from libs.base import bflb_flash_select +from libs.base import bflb_efuse_boothd_create +from libs.base import bflb_img_create as img_create +from pickle import NONE +FLASH_LOAD_SHAKE_HAND = 'Flash load shake hand' +FLASH_ERASE_SHAKE_HAND = 'Flash erase shake hand' + +class BaseEflashLoader(object): + __doc__ = '\n Load the flash base execution file.\n ' + + def __init__(self, chip_type, args, config, callback, macaddr_callback, create_simple_callback, create_img_callback, task_num): + self.chip_type = chip_type + self.chip_name = '' + self.args = args + self.config = config + self.callback = callback + self.macaddr_callback = macaddr_callback + self.create_simple_callback = create_simple_callback + self.create_img_callback = create_img_callback + self.temp_task_num = task_num + self.task_num = None + self.device = '' + self.speed = 0 + self.boot_speed = 0 + self.bflb_serial_object = None + self.start = '' + self.end = '' + self.file = '' + self.address = '' + self.macaddr = '' + self.bootinfo = None + self.flash_set = 0 + self.read_flash_id = 0 + self.id_valid_flag = '80' + self.read_flash2_id = 0 + self.id2_valid_flag = '80' + self.do_reset = True + self.reset_hold_time = 100 + self.shake_hand_delay = 100 + self.reset_revert = True + self.cutoff_time = 0 + self.shake_hand_retry = 2 + self.flash_burn_retry = 1 + self.ram_load = False + self.load_function = 1 + self.macaddr_check = False + self.NUM_ERR = 5 + self.cfg = '' + self.eflash_loader_file = '' + self.cpu_reset = False + self.retry_delay_after_cpu_reset = 0 + self.input_macaddr = '' + self.isp_mode_sign = False + self.create_cfg = None + self._skip_addr = [] + self._skip_len = [] + self.address_list = [] + self.flash_file_list = [] + self.encrypt_key = None + self.encrypt_iv = None + self.public_key = None + self.private_key = None + self.load_file = '' + self._mac_addr = bytearray(0) + self._need_shake_hand = True + self._isp_shakehand_timeout = 0 + self._macaddr_check = bytearray(0) + self._default_time_out = 2.0 + self._flash2_en = False + self._flash1_size = 0 + self._flash2_size = 0 + self._flash2_select = False + self._efuse_bootheader_file = '' + self._img_create_file = '' + self._com_cmds = {'change_rate':{'cmd_id':'20', + 'data_len':'0008', + 'callback':None}, + 'reset':{'cmd_id':'21', + 'data_len':'0000', + 'callback':None}, + 'clk_set':{'cmd_id':'22', + 'data_len':'0000', + 'callback':None}, + 'opt_finish':{'cmd_id':'23', + 'data_len':'0000', + 'callback':None}, + 'flash_erase':{'cmd_id':'30', + 'data_len':'0000', + 'callback':None}, + 'flash_write':{'cmd_id':'31', + 'data_len':'0100', + 'callback':None}, + 'flash_read':{'cmd_id':'32', + 'data_len':'0100', + 'callback':None}, + 'flash_boot':{'cmd_id':'33', + 'data_len':'0000', + 'callback':None}, + 'flash_xip_read':{'cmd_id':'34', + 'data_len':'0100', + 'callback':None}, + 'flash_switch_bank':{'cmd_id':'35', + 'data_len':'0100', + 'callback':None}, + 'flash_read_jid':{'cmd_id':'36', + 'data_len':'0000', + 'callback':None}, + 'flash_read_status_reg':{'cmd_id':'37', + 'data_len':'0000', + 'callback':None}, + 'flash_write_status_reg':{'cmd_id':'38', + 'data_len':'0000', + 'callback':None}, + 'flash_write_check':{'cmd_id':'3a', + 'data_len':'0000', + 'callback':None}, + 'flash_set_para':{'cmd_id':'3b', + 'data_len':'0000', + 'callback':None}, + 'flash_chiperase':{'cmd_id':'3c', + 'data_len':'0000', + 'callback':None}, + 'flash_readSha':{'cmd_id':'3d', + 'data_len':'0100', + 'callback':None}, + 'flash_xip_readSha':{'cmd_id':'3e', + 'data_len':'0100', + 'callback':None}, + 'flash_decompress_write':{'cmd_id':'3f', + 'data_len':'0100', + 'callback':None}, + 'efuse_write':{'cmd_id':'40', + 'data_len':'0080', + 'callback':None}, + 'efuse_read':{'cmd_id':'41', + 'data_len':'0000', + 'callback':None}, + 'efuse_read_mac':{'cmd_id':'42', + 'data_len':'0000', + 'callback':None}, + 'efuse_write_mac':{'cmd_id':'43', + 'data_len':'0006', + 'callback':None}, + 'flash_xip_read_start':{'cmd_id':'60', + 'data_len':'0080', + 'callback':None}, + 'flash_xip_read_finish':{'cmd_id':'61', + 'data_len':'0000', + 'callback':None}, + 'log_read':{'cmd_id':'71', + 'data_len':'0000', + 'callback':None}, + 'efuse_security_write':{'cmd_id':'80', + 'data_len':'0080', + 'callback':None}, + 'efuse_security_read':{'cmd_id':'81', + 'data_len':'0000', + 'callback':None}, + 'ecdh_get_pk':{'cmd_id':'90', + 'data_len':'0000', + 'callback':None}, + 'ecdh_chanllenge':{'cmd_id':'91', + 'data_len':'0000', + 'callback':None}} + self._resp_cmds = [ + 'flash_read','flash_xip_read','efuse_read','efuse_read_mac','flash_readSha','flash_xip_readSha','flash_read_jid', + 'flash_read_status_reg','log_read','ecdh_get_pk','ecdh_chanllenge','efuse_security_read'] + + def first_run_step_load_parameter(self): + """ + First step: init. + """ + if self.temp_task_num == None: + local_log_enable(True) + if self.temp_task_num != None: + if self.temp_task_num > 256: + self.task_num = self.temp_task_num - 256 + else: + self.task_num = self.temp_task_num + else: + self.task_num = None + printf('========= eflash loader cmd arguments =========') + self.interface = self.config['param']['interface_type'].lower() + self.chip_name = self.config['param']['chip_name'] + self.config_file = os.path.join(app_path, 'chips', self.chip_name.lower(), 'eflash_loader', 'eflash_loader_cfg.ini') + if not os.path.exists(self.config_file): + conf_file = self.config_file.replace('.ini', '.conf') + if os.path.exists(conf_file): + shutil.copy(conf_file, self.config_file) + if os.path.exists(self.config_file): + self.cfg = BFConfigParser() + self.cfg.read(self.config_file) + else: + printf('Config file not found') + self.error_code_print('000B') + return (False, 0) + if self.interface == 'openocd': + self.device = self.cfg.get('LOAD_CFG', 'openocd_config') + self._bflb_sn_device = self.config['param']['comport_uart'] + else: + if self.interface == 'cklink': + self.device = self.cfg.get('LOAD_CFG', 'cklink_vidpid') + self._bflb_sn_device = self.cfg.get('LOAD_CFG', 'cklink_type') + ' ' + self.config['param']['comport_uart'] + else: + self.device = self.config['param']['comport_uart'] + if 'aes_key' in self.config['param']: + if self.config['check_box']['encrypt']: + self.encrypt_key = self.config['param']['aes_key'] + if 'aes_iv' in self.config['param']: + if self.config['check_box']['sign']: + self.encrypt_iv = self.config['param']['aes_iv'] + if 'input_path' in self.config: + if 'publickey' in self.config['input_path']['publickey']: + self.public_key = self.config['input_path']['publickey'] + if 'input_path' in self.config: + if 'privatekey' in self.config['input_path']['privatekey']: + self.private_key = self.config['input_path']['privatekey'] + xtal_type = self.config['param']['chip_xtal'] + if self.interface == 'uart': + temp_speed = int(self.config['param']['speed_uart']) + else: + temp_speed = int(self.config['param']['speed_jlink']) + printf('serial port is ', self.device) + printf('chiptype: ', self.chip_type) + try: + if self.args.start: + self.start = self.args.start + if self.args.end: + self.end = self.args.end + if self.args.file: + self.file = self.args.file + if self.args.addr: + self.address = self.args.addr + if self.args.mac: + self.macaddr = self.args.mac + if self.args.createcfg: + self.create_cfg = self.args.createcfg + if self.args.loadfile: + self.load_file = self.args.loadfile + if self.args.usage: + printf('-e --start=00000000 --end=0000FFFF -c config.ini') + printf('-w --flash -c config.ini') + printf('-w --flash --file=1.bin,2.bin --addr=00000000,00001000 -c config.ini') + printf('-r --flash --start=00000000 --end=0000FFFF --file=flash.bin -c config.ini') + except Exception as e: + try: + printf(e) + self.error_code_print('0002') + return (False, 0) + finally: + e = None + del e + + if self.cfg.has_option('LOAD_CFG', 'verify'): + if self.cfg.get('LOAD_CFG', 'verify') == '1': + self.verify = 1 + else: + self.verify = 0 + else: + self.verify = 0 + try: + self.erase = int(self.config['param']['erase']) + except: + self.erase = 1 + + try: + boot2_isp_mode = int(self.config['param']['boot2_isp_mode']) + if int(boot2_isp_mode) == 1: + self.isp_mode_sign = True + except: + pass + + if not 'skip_mode' in self.config['param'] or self.config['param']['skip_mode']: + skip_para = self.config['param']['skip_mode'].replace(' ', '') + if skip_para[-1] == ';': + skip_para = skip_para[:-1] + skip_para_list = skip_para.split(';') + for temp_value in skip_para_list: + temp_list = temp_value.split(',') + if temp_list[0][0:2] == '0x': + self._skip_addr.append(int(temp_list[0][2:], 16)) + else: + self._skip_addr.append(int(temp_list[0], 10)) + if temp_list[1][0:2] == '0x': + self._skip_len.append(int(temp_list[1][2:], 16)) + else: + self._skip_len.append(int(temp_list[1], 10)) + + if len(self._skip_len) > 1 or len(self._skip_len) == 1 and self._skip_len[0] > 0: + if self.erase == 2: + printf('Error: skip mode can not set flash chiperase!') + self.error_code_print('0044') + return (False, 0) + if self.cfg.has_option('LOAD_CFG', 'local_log'): + if self.cfg.get('LOAD_CFG', 'local_log') == 'true': + printf('local log enable') + local_log_enable(True) + self.input_macaddr = self.macaddr + else: + local_log_enable(False) + self.input_macaddr = '' + if self.interface == 'cklink': + self._bflb_com_tx_size = 14344 + else: + self._bflb_com_tx_size = int(self.cfg.get('LOAD_CFG', 'tx_size')) + if self.cfg.has_option('LOAD_CFG', 'erase_time_out'): + self._erase_time_out = int(self.cfg.get('LOAD_CFG', 'erase_time_out')) + if self.cfg.has_option('LOAD_CFG', 'shake_hand_retry'): + self.shake_hand_retry = int(self.cfg.get('LOAD_CFG', 'shake_hand_retry')) + if self.cfg.has_option('LOAD_CFG', 'flash_burn_retry'): + self.flash_burn_retry = int(self.cfg.get('LOAD_CFG', 'flash_burn_retry')) + if self.cfg.has_option('LOAD_CFG', 'checksum_err_retry'): + self._checksum_err_retry_limit = int(self.cfg.get('LOAD_CFG', 'checksum_err_retry')) + if self.cfg.has_option('LOAD_CFG', 'cpu_reset_after_load'): + self.cpu_reset = self.cfg.get('LOAD_CFG', 'cpu_reset_after_load') == 'true' + if self.cfg.has_option('LOAD_CFG', 'retry_delay_after_cpu_reset'): + self.retry_delay_after_cpu_reset = int(self.cfg.get('LOAD_CFG', 'retry_delay_after_cpu_reset')) + printf('retry delay: ', self.retry_delay_after_cpu_reset) + if self.cfg.has_option('LOAD_CFG', 'eflash_loader_file'): + if self.eflash_loader_file is None: + self.eflash_loader_file = self.cfg.get('LOAD_CFG', 'eflash_loader_file') + printf('cpu_reset=', self.cpu_reset) + if xtal_type != '': + self.eflash_loader_file = 'chips/' + self.chip_name.lower() + '/eflash_loader/eflash_loader_' + xtal_type.replace('.', 'p').lower() + '.bin' + if self.load_file and not self.eflash_loader_file: + self.eflash_loader_file = self.load_file + else: + if self.eflash_loader_file is not None: + self.eflash_loader_file = os.path.join(app_path, self.eflash_loader_file) + self.load_function = 1 + if self.cfg.has_option('LOAD_CFG', 'isp_shakehand_timeout'): + self._isp_shakehand_timeout = int(self.cfg.get('LOAD_CFG', 'isp_shakehand_timeout')) + result, address, flash_file = self.get_flash_file_and_address() + if not result: + return (False, self.flash_burn_retry) + temp_file_list = [] + for one in flash_file: + if os.path.join(chip_path, self.chip_name) in one: + temp_file_list.append(one.replace(app_path, '')[1:]) + else: + temp_file_list.append(os.path.join('chips', self.chip_name, 'img_create', os.path.basename(one))) + + if 'erase' in self.config['param']: + if self.config['param']['erase']: + update_cfg(self.cfg, 'LOAD_CFG', 'erase', str(self.erase)) + if 'skip_mode' in self.config['param']: + if self.config['param']['skip_mode']: + update_cfg(self.cfg, 'LOAD_CFG', 'skip_mode', self.config['param']['skip_mode']) + if 'boot2_isp_mode' in self.config['param']: + if self.config['param']['boot2_isp_mode']: + update_cfg(self.cfg, 'LOAD_CFG', 'boot2_isp_mode', self.config['param']['boot2_isp_mode']) + update_cfg(self.cfg, 'FLASH_CFG', 'file', ' '.join(temp_file_list)) + update_cfg(self.cfg, 'FLASH_CFG', 'address', ' '.join(address)) + self.cfg.write(self.config_file, 'w+') + with open((self.config_file), 'r', encoding='utf-8') as cf_file: + cf_context = cf_file.read().replace('"', '') + with open((self.config_file), 'w', encoding='utf-8') as cf_file: + cf_file.write(cf_context) + self.bl_write_flash_img(address, flash_file) + self.address_list = address[:] + self.flash_file_list = flash_file[:] + if self.args.efuse: + try: + if self.config['input_path']['efuse']: + if self.config['check_box']['efuse']: + efusefile = self.config['input_path']['efuse'] + except: + efusefile = '' + + if efusefile: + efuse_file = efusefile + mask_file = efuse_file.replace('.bin', '_mask.bin') + relpath_efuse_file = os.path.relpath(os.path.join('chips', self.chip_name, 'img_create', os.path.basename(efuse_file))) + relpath_mask_file = os.path.relpath(os.path.join('chips', self.chip_name, 'img_create', os.path.basename(mask_file))) + if self.cfg.has_option('EFUSE_CFG', 'file'): + update_cfg(self.cfg, 'EFUSE_CFG', 'file', relpath_efuse_file) + update_cfg(self.cfg, 'EFUSE_CFG', 'maskfile', relpath_mask_file) + self.cfg.write(self.config_file, 'w+') + with open((self.config_file), 'r', encoding='utf-8') as cf_file: + cf_context = cf_file.read().replace('"', '') + with open((self.config_file), 'w', encoding='utf-8') as cf_file: + cf_file.write(cf_context) + else: + efuse_file = self.cfg.get('EFUSE_CFG', 'file') + mask_file = self.cfg.get('EFUSE_CFG', 'maskfile') + if self.temp_task_num != None: + efuse_file = 'task' + str(self.temp_task_num) + '/' + efuse_file + ret = img_create.compress_dir(self.chip_name, 'img_create', self.args.efuse, address, flash_file, efuse_file, mask_file) + if ret is not True: + return errorcode_msg() + else: + ret = img_create.compress_dir(self.chip_name, 'img_create', False, address, flash_file) + if ret is not True: + return errorcode_msg() + if self.interface == 'uart' or self.interface == 'sdio': + if temp_speed: + self.speed = temp_speed + self.boot_speed = int(self.cfg.get('LOAD_CFG', 'speed_uart_boot')) + self.set_boot_speed() + if self.cfg.has_option('LOAD_CFG', 'reset_hold_time'): + self.reset_hold_time = int(self.cfg.get('LOAD_CFG', 'reset_hold_time')) + if self.cfg.has_option('LOAD_CFG', 'shake_hand_delay'): + self.shake_hand_delay = int(self.cfg.get('LOAD_CFG', 'shake_hand_delay')) + if self.cfg.has_option('LOAD_CFG', 'do_reset'): + self.do_reset = self.cfg.get('LOAD_CFG', 'do_reset') == 'true' + if self.cfg.has_option('LOAD_CFG', 'reset_revert'): + self.reset_revert = self.cfg.get('LOAD_CFG', 'reset_revert') == 'true' + if self.cfg.has_option('LOAD_CFG', 'cutoff_time'): + self.cutoff_time = int(self.cfg.get('LOAD_CFG', 'cutoff_time')) + printf('========= Interface is %s =========' % self.interface) + self._bflb_com_img_loader = bflb_img_loader.BflbImgLoader(self.device, self.speed, self.boot_speed, self.interface, self.chip_type, self.chip_name, self.eflash_loader_file, '', self.callback, self.do_reset, self.reset_hold_time, self.shake_hand_delay, self.reset_revert, self.cutoff_time, self.shake_hand_retry, self.isp_mode_sign, self._isp_shakehand_timeout, self.encrypt_key, self.encrypt_iv, self.public_key, self.private_key) + self.bflb_serial_object = self._bflb_com_img_loader.bflb_serial_object + if not self.cfg.has_option('LOAD_CFG', 'isp_mode_speed') or self.isp_mode_sign is True: + isp_mode_speed = int(self.cfg.get('LOAD_CFG', 'isp_mode_speed')) + self._bflb_com_img_loader.set_isp_baudrate(isp_mode_speed) + else: + if self.interface == 'jlink': + printf('========= Interface is JLink =========') + self.bflb_serial_object = bflb_interface_jlink.BflbJLinkPort() + if temp_speed: + self.speed = temp_speed + printf('com speed: %dk' % self.speed) + else: + self.speed = int(self.cfg.get('LOAD_CFG', 'speed_jlink')) + self.boot_speed = self.speed + else: + if self.interface == 'openocd': + printf('========= Interface is Openocd =========') + self.bflb_serial_object = bflb_interface_openocd.BflbOpenocdPort() + if temp_speed: + self.speed = temp_speed + printf('com speed: %dk' % self.speed) + else: + self.speed = int(self.cfg.get('LOAD_CFG', 'speed_jlink')) + self.boot_speed = self.speed + else: + if self.interface == 'cklink': + printf('========= Interface is CKLink =========') + self.bflb_serial_object = bflb_interface_cklink.BflbCKLinkPort() + if temp_speed: + self.speed = temp_speed + printf('com speed: %dk' % self.speed) + else: + self.speed = int(self.cfg.get('LOAD_CFG', 'speed_jlink')) + self.boot_speed = self.speed + else: + printf(self.interface + ' is not supported ') + return ( + False, self.flash_burn_retry) + if self.args.chipid: + ret, self.bootinfo, res = self.get_boot_info() + if ret is False: + self.error_code_print('0003') + return ( + False, self.flash_burn_retry) + return ( + True, self.flash_burn_retry) + if self.cfg.has_option('LOAD_CFG', 'load_function'): + self.load_function = int(self.cfg.get('LOAD_CFG', 'load_function')) + if self.isp_mode_sign is True: + if self._isp_shakehand_timeout == 0: + self._isp_shakehand_timeout = 5 + self.set_load_function() + return (True, 'continue') + + def second_run_step_shake_hand(self): + """ + Second step: shake hand and load eflash_loader.bin. + """ + try: + if self.load_function == 0: + printf('No need load eflash_loader.bin') + else: + if self.load_function == 1: + load_bin_pass = False + printf('Eflash load bin file: ', self.eflash_loader_file) + ret, self.bootinfo, res = self.load_eflash_loader_bin() + if res == 'shake hand fail': + self.error_code_print('0050') + if res.startswith('repeat_burn') is True: + return ('repeat_burn', self.flash_burn_retry) + if res.startswith('error_shakehand') is True: + if self.cpu_reset is True: + self.error_code_print('0003') + return ( + False, self.flash_burn_retry) + load_bin_pass = True + time.sleep(4.5) + if ret is False: + if load_bin_pass == False: + self.error_code_print('0003') + return ( + False, self.flash_burn_retry) + if self.ram_load: + return (True, self.flash_burn_retry) + else: + if self.load_function == 2: + load_bin_pass = False + printf('Bootrom load') + ret, self.bootinfo, res = self.get_boot_info() + if res == 'shake hand fail': + self.error_code_print('0050') + if res.startswith('repeat_burn') is True: + self.error_code_print('000A') + return ( + 'repeat_burn', self.flash_burn_retry) + if res.startswith('error_shakehand') is True: + if self.cpu_reset is True: + self.error_code_print('0003') + return ( + False, self.flash_burn_retry) + load_bin_pass = True + time.sleep(4.5) + if ret is False: + if load_bin_pass == False: + self.error_code_print('0050') + return ( + False, self.flash_burn_retry) + self._need_shake_hand = False + clock_para = bytearray(0) + if self.cfg.has_option('LOAD_CFG', 'clock_para'): + clock_para_str = self.cfg.get('LOAD_CFG', 'clock_para') + if clock_para_str != '': + clock_para_file = os.path.join(app_path, clock_para_str) + printf('clock para file: ', clock_para_file) + clock_para = self.clock_para_update(clock_para_file) + printf('change bdrate: ', self.speed) + ret = self.clock_pll_set(self._need_shake_hand, True, clock_para) + if ret is False: + printf('pll set fail!!') + return ( + False, self.flash_burn_retry) + return (True, 'continue') + except Exception as e: + try: + printf(e) + self.error_code_print('0003') + return ( + False, self.flash_burn_retry) + finally: + e = None + del e + + def third_run_step_read_mac_address(self): + """ + Third step: read mac address. + """ + time.sleep(0.1) + if self.isp_mode_sign is True: + if self.cpu_reset is True: + self.set_clear_boot_status(self._need_shake_hand) + if self.cfg.has_option('LOAD_CFG', 'check_mac'): + self.macaddr_check = self.cfg.get('LOAD_CFG', 'check_mac') == 'true' + if self.macaddr_check: + if self.isp_mode_sign is False: + ret, self._mac_addr = self.efuse_read_mac_addr_process() + if ret is False: + printf('read mac addr fail!!') + return ( + False, self.flash_burn_retry) + if self._mac_addr == self._macaddr_check: + self.error_code_print('000A') + return ( + False, self.flash_burn_retry) + self._need_shake_hand = False + self._macaddr_check_status = True + if self.macaddr_callback is not None: + ret, self._efuse_data, self._efuse_mask_data, macaddr = self.macaddr_callback(binascii.hexlify(self._mac_addr).decode('utf-8')) + if ret is False: + return (False, self.flash_burn_retry) + if self._efuse_data != bytearray(0) and self._efuse_mask_data != bytearray(0) or macaddr != '': + self.args.efuse = True + if self.callback: + self.callback(0, 100, 'running', 'blue') + return (True, 'continue') + + def fourth_run_step_interact_chip(self): + """ + Fourth step: Interact with chip, read chip ID and update flash parameter. + """ + if self.args.flash: + flash_pin = 0 + flash_clock_cfg = 0 + flash_io_mode = 0 + flash_clk_delay = 0 + if self.cfg.has_option('FLASH_CFG', 'decompress_write'): + self.decompress_write = self.cfg.get('FLASH_CFG', 'decompress_write') == 'true' + self.set_decompress_write() + printf('flash set para') + if self.cfg.get('FLASH_CFG', 'flash_pin'): + flash_pin_cfg = self.cfg.get('FLASH_CFG', 'flash_pin') + if flash_pin_cfg.startswith('0x'): + flash_pin = int(flash_pin_cfg, 16) + else: + flash_pin = int(flash_pin_cfg, 10) + if flash_pin == 128: + flash_pin = self.get_flash_pin_from_bootinfo(self.chip_type, self.bootinfo) + printf('get flash pin cfg from bootinfo: 0x%02X' % flash_pin) + else: + flash_pin = self.get_flash_pin() + if self.cfg.has_option('FLASH_CFG', 'flash_clock_cfg'): + clock_div_cfg = self.cfg.get('FLASH_CFG', 'flash_clock_cfg') + if clock_div_cfg.startswith('0x'): + flash_clock_cfg = int(clock_div_cfg, 16) + else: + flash_clock_cfg = int(clock_div_cfg, 10) + if self.cfg.has_option('FLASH_CFG', 'flash_io_mode'): + io_mode_cfg = self.cfg.get('FLASH_CFG', 'flash_io_mode') + if io_mode_cfg.startswith('0x'): + flash_io_mode = int(io_mode_cfg, 16) + else: + flash_io_mode = int(io_mode_cfg, 10) + if self.cfg.has_option('FLASH_CFG', 'flash_clock_delay'): + clk_delay_cfg = self.cfg.get('FLASH_CFG', 'flash_clock_delay') + if clk_delay_cfg.startswith('0x'): + flash_clk_delay = int(clk_delay_cfg, 16) + else: + flash_clk_delay = int(clk_delay_cfg, 10) + self.flash_set = (flash_pin << 0) + (flash_clock_cfg << 8) + (flash_io_mode << 16) + (flash_clk_delay << 24) + if self.flash_set != 66047 or self.load_function == 2: + printf('set flash cfg: %X' % self.flash_set) + ret = self.flash_set_para_main_process(self.flash_set, bytearray(0)) + self._need_shake_hand = False + if ret is False: + return (False, self.flash_burn_retry) + ret, data = self.flash_read_jedec_id_process() + if ret: + self._need_shake_hand = False + data = binascii.hexlify(data).decode('utf-8') + self.id_valid_flag = data[6:] + read_id = data[0:6] + self.read_flash_id = read_id + if self.cfg.has_option('FLASH_CFG', 'flash_para'): + flash_para_file = os.path.join(app_path, self.cfg.get('FLASH_CFG', 'flash_para')) + self.flash_para_update(flash_para_file, read_id) + if self.id_valid_flag != '80': + if not self.show_identify_fail(): + return (False, self.flash_burn_retry) + if self.is_conf_exist(self.read_flash_id) is False: + self.error_code_print('003D') + return ( + False, self.flash_burn_retry) + else: + self.error_code_print('0030') + return ( + False, self.flash_burn_retry) + result, content = self.run_flash2() + return ( + result, content) + return (True, 'continue') + + def fifth_run_step_write_flash_and_check(self): + """ + Fifth step: write flash and check. + """ + if self.args.none: + return (True, self.flash_burn_retry) + if self.args.write: + if not self.args.flash: + if not self.args.efuse: + printf('No target select') + return ( + False, self.flash_burn_retry) + printf('Program operation') + if self.args.flash: + flash_para_file = '' + flash2_para_file = '' + if self.cfg.has_option('FLASH_CFG', 'flash_para'): + flash_para_file = os.path.join(app_path, self.cfg.get('FLASH_CFG', 'flash_para')) + if self.cfg.has_option('FLASH2_CFG', 'flash2_para'): + flash2_para_file = os.path.join(app_path, self.cfg.get('FLASH2_CFG', 'flash2_para')) + address = self.address_list + flash_file = self.flash_file_list + if self.erase == 2: + ret = self.flash_chiperase_main_process() + if ret is False: + return (False, self.flash_burn_retry) + self._need_shake_hand = False + self.erase = 0 + if len(flash_file) > 0: + size_before = 0 + size_all = 0 + i = 0 + for item in flash_file: + if self.temp_task_num != None: + size_all += os.path.getsize(os.path.join(app_path, convert_path('task' + str(self.temp_task_num) + '/' + item))) + else: + size_all += os.path.getsize(os.path.join(app_path, convert_path(item))) + + try: + ret = False + while i < len(flash_file): + if self.temp_task_num != None: + flash_file[i] = 'task' + str(self.temp_task_num) + '/' + flash_file[i] + size_current = os.path.getsize(os.path.join(app_path, convert_path(flash_file[i]))) + else: + size_current = os.path.getsize(os.path.join(app_path, convert_path(flash_file[i]))) + if self.callback: + self.callback(size_before, size_all, 'program1') + else: + if self.callback: + self.callback(size_current, size_all, 'program2') + printf('Dealing Index ', i) + if self.isp_mode_sign is True: + printf('========= programming ', convert_path(flash_file[i])) + else: + printf('========= programming ', convert_path(flash_file[i]), ' to 0x', address[i]) + flash1_bin = '' + flash1_bin_len = 0 + flash2_bin = '' + flash2_bin_len = 0 + flash1_bin, flash1_bin_len, flash2_bin, flash2_bin_len = self.get_flash1_and_flash2(flash_file, address, size_current, i) + if flash1_bin != '' and flash2_bin != '': + ret = self.flash_cfg_option(self.read_flash_id, flash_para_file, self.flash_set, self.id_valid_flag, flash1_bin, self.config_file, self.cfg, self.create_img_callback, self.create_simple_callback) + if ret is False: + return (False, self.flash_burn_retry) + printf('========= programming ', convert_path(flash1_bin), ' to 0x', address[i]) + ret = self.flash_load_specified(convert_path(flash1_bin), int(address[i], 16), self.callback) + if ret is False: + return (False, self.flash_burn_retry) + ret = self.flash_switch_bank_process(1) + self._need_shake_hand = False + if ret is False: + return (False, self.flash_burn_retry) + ret = self.flash_cfg_option(self.read_flash2_id, flash2_para_file, self.flash2_set, self.id2_valid_flag, flash_file[i], self.config_file, self.cfg, self.create_img_callback, self.create_simple_callback) + if ret is False: + return (False, self.flash_burn_retry) + printf('========= programming ', convert_path(flash2_bin), ' to 0x%08X' % (int(address[i], 16) + flash1_bin_len)) + ret = self.flash_load_specified(convert_path(flash2_bin), int(address[i], 16) + flash1_bin_len, self.callback) + if ret is False: + return (False, self.flash_burn_retry) + else: + if not (self._flash2_en is False or self._flash2_select) is False or int(address[i], 16) < self._flash1_size: + ret = self.flash_cfg_option(self.read_flash_id, flash_para_file, self.flash_set, self.id_valid_flag, flash_file[i], self.config_file, self.cfg, self.create_img_callback, self.create_simple_callback) + if ret is False: + return (False, self.flash_burn_retry) + else: + if self._flash2_select is False: + if int(address[i], 16) >= self._flash1_size: + ret = self.flash_switch_bank_process(1) + self._need_shake_hand = False + if ret is False: + return (False, self.flash_burn_retry) + ret = self.flash_cfg_option(self.read_flash2_id, flash2_para_file, self.flash2_set, self.id2_valid_flag, flash_file[i], self.config_file, self.cfg, self.create_img_callback, self.create_simple_callback) + if ret is False: + return (False, self.flash_burn_retry) + if 'eflash_loader_cfg.ini' in flash_file[i]: + print('11111') + ret = self.flash_load_specified(convert_path(flash_file[i]), int(address[i], 16), self.callback) + if ret is False: + return (False, self.flash_burn_retry) + size_before += os.path.getsize(os.path.join(app_path, convert_path(flash_file[i]))) + i += 1 + if self.callback: + self.callback(i, len(flash_file), 'program') + self._need_shake_hand = False + + if self._flash2_select is True: + ret = self.flash_switch_bank_process(0) + self._need_shake_hand = False + if ret is False: + return (False, self.flash_burn_retry) + printf('Program Finished') + except Exception as e: + try: + printf(e) + traceback.print_exc(limit=(self.NUM_ERR), file=(sys.stdout)) + return ( + False, self.flash_burn_retry) + finally: + e = None + del e + + else: + printf('Warning: No input file to program to flash') + return (True, 'continue') + + def sixth_run_step_write_efuse(self): + """ + Sixth step: write efuse. + """ + if self.args.efuse: + try: + if self.config['input_path']['efuse']: + efusefile = self.config['input_path']['efuse'] + except: + efusefile = '' + + if efusefile: + efuse_file = efusefile + mask_file = efuse_file.replace('.bin', '_mask.bin') + else: + efuse_file = self.cfg.get('EFUSE_CFG', 'file') + mask_file = self.cfg.get('EFUSE_CFG', 'maskfile') + if self.temp_task_num != None: + efuse_file = 'task' + str(self.temp_task_num) + '/' + efuse_file + efuse_load = True + efuse_verify = 0 + if self.cfg.has_option('EFUSE_CFG', 'burn_en'): + efuse_load = self.cfg.get('EFUSE_CFG', 'burn_en') == 'true' + if self.cfg.has_option('EFUSE_CFG', 'factory_mode'): + if self.cfg.get('EFUSE_CFG', 'factory_mode') == 'true': + efuse_verify = 1 + security_write = self.cfg.get('EFUSE_CFG', 'security_write') == 'true' + if efuse_load and self.isp_mode_sign is False: + ret = self.efuse_load_specified(efuse_file, mask_file, bytearray(0), bytearray(0), efuse_verify, security_write) + if self.callback: + self.callback(1, 1, 'APP_WR') + if ret is False: + return (False, self.flash_burn_retry) + else: + printf('efuse load disalbe') + self._need_shake_hand = False + return (True, 'continue') + + def seventh_run_step_erase(self): + """ + Seventh step: erase. + """ + if self.args.erase: + printf('Erase flash operation') + if self.end == '0': + ret = self.flash_chiperase_main_process() + if ret is False: + return (False, self.flash_burn_retry) + else: + ret = self.flash_erase_main_process(int(self.start, 16), int(self.end, 16), self._need_shake_hand) + if ret is False: + return (False, self.flash_burn_retry) + printf('Erase flash OK') + return (True, 'continue') + + def eighth_run_step_read(self): + """ + Eighth step: read. + """ + if self.args.read: + printf('Read operation') + if not self.args.flash: + if not self.args.efuse: + printf('No target select') + return ( + False, self.flash_burn_retry) + if not (self.args.flash and self.start and self.end): + self.flash_read_jedec_id_process(self.callback) + else: + start_addr = int(self.start, 16) + end_addr = int(self.end, 16) + ret, readdata = self.flash_read_main_process(start_addr, end_addr - start_addr + 1, self._need_shake_hand, self.file, self.callback) + if ret is False: + return (False, self.flash_burn_retry) + if self.args.efuse: + start_addr = int(self.start, 16) + end_addr = int(self.end, 16) + if self.efuse_read_main_process(start_addr, end_addr - start_addr + 1, self._need_shake_hand, self.file) is False: + return (False, self.flash_burn_retry) + return (True, 'continue') + + def ninth_run_step_end(self): + """ + Ninth step: run end. + """ + self.run_reset_cpu() + if self.macaddr_check is True: + self._bootinfo = self.bootinfo + self._macaddr_check = self._mac_addr + self._macaddr_check_status = False + return ( + True, self.flash_burn_retry) + + def set_clear_boot_status(self, shakehand=0): + pass + + def set_boot_speed(self): + pass + + def set_load_function(self): + self.load_function = 2 + + def set_decompress_write(self): + pass + + def get_flash_pin(self): + return 0 + + def show_identify_fail(self): + return True + + def run_flash2(self): + return (True, 'continue') + + def get_flash1_and_flash2(self, flash_file, address, size_current, i): + return ('', 0, '', 0) + + def run_reset_cpu(self): + pass + + def get_mac_len(self): + return 6 + + def get_isp_sh_time(self): + return 0 + + def write_flash_data(self, file, start_addr, callback): + pass + + def clear_boot_status(self, shakehand=0): + printf('Clear boot status at hbn rsvd register') + if shakehand != 0: + printf(FLASH_ERASE_SHAKE_HAND) + if self.img_load_shake_hand() is False: + return False + data = bytearray(12) + data[0] = 80 + data[1] = 0 + data[2] = 8 + data[3] = 0 + data[4] = 8 + data[5] = 241 + data[6] = 0 + data[7] = 32 + data[8] = 0 + data[9] = 0 + data[10] = 0 + data[11] = 0 + self.bflb_serial_object.write(data) + self.bflb_serial_object.deal_ack(dmy_data=False) + return True + + def set_config_file(self, bootheaderFile, imgCreateFile): + self._efuse_bootheader_file = bootheaderFile + self._img_create_file = imgCreateFile + + def load_eflash_loader_bin(self): + """ + This function is used to load eflash loader bin file. + """ + printf('========= load eflash_loader.bin =========') + bootinfo = None + if self.interface == 'jlink': + printf('Load eflash_loader.bin via jlink') + self.bflb_serial_object.if_init(self.device, self.speed, self.chip_type, self.chip_name) + self.bflb_serial_object.reset_cpu() + imge_fp = open_file(self.eflash_loader_file, 'rb') + fw_data = bytearray(imge_fp.read())[192:] + bytearray(0) + imge_fp.close() + sub_module = __import__(('libs.base.' + self.chip_type), fromlist=[self.chip_type]) + load_addr = sub_module.jlink_load_cfg.jlink_load_addr + self.bflb_serial_object.if_raw_write(load_addr, fw_data) + pc = fw_data[4:8] + pc = bytes([pc[3], pc[2], pc[1], pc[0]]) + msp = fw_data[0:4] + msp = bytes([msp[3], msp[2], msp[1], msp[0]]) + self.bflb_serial_object.set_pc_msp(binascii.hexlify(pc), binascii.hexlify(msp).decode('utf-8')) + time.sleep(0.01) + self.bflb_serial_object.if_close() + return ( + True, bootinfo, '') + if self.interface == 'openocd': + printf('Load eflash_loader.bin via openocd') + self.bflb_serial_object.if_init(self.device, self._bflb_sn_device, self.speed, self.chip_type, self.chip_name) + self.bflb_serial_object.halt_cpu() + imge_fp = open_file(self.eflash_loader_file, 'rb') + fw_data = bytearray(imge_fp.read())[192:] + bytearray(0) + imge_fp.close() + sub_module = __import__(('libs.base.' + self.chip_type), fromlist=[self.chip_type]) + load_addr = sub_module.openocd_load_cfg.openocd_load_addr + self.bflb_serial_object.if_raw_write(load_addr, fw_data) + pc = fw_data[4:8] + pc = bytes([pc[3], pc[2], pc[1], pc[0]]) + msp = fw_data[0:4] + msp = bytes([msp[3], msp[2], msp[1], msp[0]]) + self.bflb_serial_object.set_pc_msp(binascii.hexlify(pc), binascii.hexlify(msp).decode('utf-8')) + return ( + True, bootinfo, '') + if self.interface == 'cklink': + printf('Load eflash_loader.bin via cklink') + self.bflb_serial_object.if_init(self.device, self._bflb_sn_device, self.speed, self.chip_type, self.chip_name) + self.bflb_serial_object.halt_cpu() + imge_fp = open_file(self.eflash_loader_file, 'rb') + fw_data = bytearray(imge_fp.read())[192:] + bytearray(0) + imge_fp.close() + sub_module = __import__(('libs.base.' + self.chip_type), fromlist=[self.chip_type]) + load_addr = sub_module.openocd_load_cfg.openocd_load_addr + self.bflb_serial_object.if_raw_write(load_addr, fw_data) + pc = fw_data[4:8] + pc = bytes([pc[3], pc[2], pc[1], pc[0]]) + msp = fw_data[0:4] + msp = bytes([msp[3], msp[2], msp[1], msp[0]]) + self.bflb_serial_object.set_pc_msp(binascii.hexlify(pc), binascii.hexlify(msp).decode('utf-8')) + self.bflb_serial_object.resume_cpu() + return ( + True, bootinfo, '') + if self.interface.lower() == 'uart' or self.interface == 'sdio': + ret = True + printf('Load eflash_loader.bin via %s' % self.interface) + start_time = time.time() * 1000 + ret, bootinfo, res = self._bflb_com_img_loader.img_load_process(self.boot_speed, self.boot_speed, None, self.do_reset, self.reset_hold_time, self.shake_hand_delay, self.reset_revert, self.cutoff_time, self.shake_hand_retry, self.isp_mode_sign, self._isp_shakehand_timeout, True, bootinfo) + printf('Load helper bin time cost(ms): ', time.time() * 1000 - start_time) + return ( + ret, bootinfo, res) + + def set_temp_timeout(self): + self.bflb_serial_object.set_timeout(self._erase_time_out / 1000) + + def get_new_bh_data(self, section, bh_data, fp): + return b'' + + def get_chip_id(self, bootinfo): + chip_id = bootinfo[34:36] + bootinfo[32:34] + bootinfo[30:32] + bootinfo[28:30] + bootinfo[26:28] + bootinfo[24:26] + return chip_id + + def get_flash_file_and_address(self): + result = True + temp_files = [] + temp_addrs = [] + temp_dict = {} + temp_set_addrs = [] + for key, value_dict in self.config.items(): + if isinstance(value_dict, dict): + if 'addr' in value_dict: + if value_dict['addr'] in temp_set_addrs: + printf('Error: %s has duplicate addresse %s!' % (key, value_dict['addr'])) + return ( + False, temp_addrs, temp_files) + else: + temp_dict[value_dict['addr']] = value_dict['path'] + temp_set_addrs.append(value_dict['addr']) + + if temp_dict: + temp_list = sorted((temp_dict.items()), key=(lambda x: int(x[0], 16) +), reverse=False) + for i in range(len(temp_list)): + temp_addrs.append(temp_list[i][0].replace('0x', '')) + temp_files.append(temp_list[i][1]) + if i != 0: + temp_length = int(temp_list[i][0], 16) - int(temp_list[i - 1][0], 16) + file_length = os.path.getsize(temp_list[i - 1][1]) + if temp_length < file_length: + result = False + printf('Error: path: %s size: %s range: %s' % (temp_list[i - 1][1], str(file_length), str(temp_length))) + printf('Error: The file size exceeds the address space size!') + + return ( + result, temp_addrs, temp_files) + + def get_boot_info(self): + """ + This function is used to get boot information from chips. At the same time, it can get chip ID. + """ + printf('========= get_boot_info =========') + bootinfo = None + if self.interface == 'uart': + ret = True + start_time = time.time() * 1000 + ret, bootinfo = self._bflb_com_img_loader.img_get_bootinfo(self.boot_speed, self.boot_speed, None, self.do_reset, self.reset_hold_time, self.shake_hand_delay, self.reset_revert, self.cutoff_time, self.shake_hand_retry, self.isp_mode_sign, self._isp_shakehand_timeout) + bootinfo = bootinfo.decode('utf-8') + chipid = '' + chipid = self.get_chip_id(bootinfo) + printf('========= ChipID: ', chipid, ' =========') + printf('Get bootinfo time cost(ms): ', time.time() * 1000 - start_time) + return ( + ret, bootinfo, 'OK') + printf('interface not fit') + return ( + False, bootinfo, '') + + def error_code_print(self, code): + set_error_code(code, self.task_num) + printf('{"ErrorCode": "' + code + '","ErrorMsg":"' + eflash_loader_error_code[code] + '"}') + + def clock_para_update(self, file): + if os.path.isfile(file) is False: + efuse_bootheader_path = os.path.join(chip_path, self.chip_name, 'efuse_bootheader') + efuse_bh_cfg = efuse_bootheader_path + '/efuse_bootheader_cfg.conf' + sub_module = __import__(('libs.base.' + self.chip_type), fromlist=[self.chip_type]) + section = 'BOOTHEADER_GROUP0_CFG' + fp = open(efuse_bh_cfg, 'r') + data = fp.read() + fp.close() + if 'BOOTHEADER_CFG' in data: + section = 'BOOTHEADER_CFG' + else: + if 'BOOTHEADER_CPU0_CFG' in data: + section = 'BOOTHEADER_CPU0_CFG' + else: + if 'BOOTHEADER_GROUP0_CFG' in data: + section = 'BOOTHEADER_GROUP0_CFG' + bh_data, tmp = bflb_efuse_boothd_create.update_data_from_cfg(sub_module.bootheader_cfg_keys.bootheader_cfg_keys, efuse_bh_cfg, section) + bh_data = bflb_efuse_boothd_create.bootheader_update_flash_pll_crc(bh_data, self.chip_type) + fp = open(file, 'wb+') + self.get_new_bh_data(section, bh_data, fp) + fp.close() + fp = open_file(file, 'rb') + clock_para = bytearray(fp.read()) + fp.close() + return clock_para + + def clock_pll_set(self, shakehand, irq_en, clk_para): + printf('Clock PLL set') + if shakehand != 0: + printf('clock set shake hand') + if self.img_load_shake_hand() is False: + return False + start_time = time.time() * 1000 + cmd_id = hexstr_to_bytearray(self._com_cmds.get('clk_set')['cmd_id']) + irq_enable = bytearray(4) + load_speed = bytearray(4) + if irq_en: + irq_enable = b'\x01\x00\x00\x00' + load_speed = int_to_4bytearray_l(int(self.speed)) + data_send = irq_enable + load_speed + clk_para + try_cnt = 0 + while True: + ret, dmy = self.com_process_one_cmd('clk_set', cmd_id, data_send) + if ret.startswith('OK'): + break + if try_cnt < self._checksum_err_retry_limit: + printf('Retry') + try_cnt += 1 + else: + self.error_code_print('000C') + return False + + printf('Set clock time cost(ms): ', time.time() * 1000 - start_time) + self.bflb_serial_object.repeat_init(self.device, self.speed, self.chip_type, self.chip_name) + self.bflb_serial_object.clear_buf() + time.sleep(0.01) + return True + + def efuse_read_mac_addr_process(self, callback=None): + readdata = bytearray(0) + macLen = self.get_mac_len() + if self._need_shake_hand != 0: + printf(FLASH_LOAD_SHAKE_HAND) + if self.img_load_shake_hand() is False: + return (False, None) + cmd_id = hexstr_to_bytearray(self._com_cmds.get('efuse_read_mac')['cmd_id']) + printf('Read mac addr ') + ret, data_read = self.com_process_one_cmd('efuse_read_mac', cmd_id, bytearray(0)) + if ret.startswith('OK') is False: + self.error_code_print('0023') + return (False, None) + readdata += data_read + crcarray = get_crc32_bytearray(readdata[:macLen]) + if crcarray != readdata[macLen:macLen + 4]: + printf(binascii.hexlify(crcarray)) + printf(binascii.hexlify(readdata[macLen:macLen + 4])) + self.error_code_print('0025') + return (False, None) + return (True, readdata[:macLen]) + + def flash_set_para_main_process(self, flash_pin, flash_para): + printf('Set flash config ') + if flash_para != bytearray(0): + if flash_para[13:14] == b'\xff': + printf('Skip set flash para due to flash id is 0xFF') + return True + if self._need_shake_hand != 0: + printf('Flash set para shake hand') + if self.img_load_shake_hand() is False: + return False + start_time = time.time() * 1000 + cmd_id = hexstr_to_bytearray(self._com_cmds.get('flash_set_para')['cmd_id']) + data_send = int_to_4bytearray_l(flash_pin) + flash_para + try_cnt = 0 + while True: + ret, dmy = self.com_process_one_cmd('flash_set_para', cmd_id, data_send) + if ret.startswith('OK'): + break + if try_cnt < self._checksum_err_retry_limit: + printf('Retry') + try_cnt += 1 + else: + self.error_code_print('003B') + return False + + printf('Set para time cost(ms): ', time.time() * 1000 - start_time) + return True + + def flash_read_jedec_id_process(self, callback=None): + printf('========= flash read jedec ID =========') + readdata = bytearray(0) + if self._need_shake_hand is not False: + printf(FLASH_LOAD_SHAKE_HAND) + if self.img_load_shake_hand() is False: + return (False, None) + cmd_id = hexstr_to_bytearray(self._com_cmds.get('flash_read_jid')['cmd_id']) + ret, data_read = self.com_process_one_cmd('flash_read_jid', cmd_id, bytearray(0)) + printf('Read flash jedec ID ') + if ret.startswith('OK') is False: + self.error_code_print('0030') + return (False, None) + readdata += data_read + printf('readdata: ') + printf(binascii.hexlify(readdata)) + printf('Finished') + return ( + True, readdata[:4]) + + def flash_para_update(self, file, jedec_id): + flash_para = bytearray(0) + if self.is_conf_exist(jedec_id) is True: + sub_module = __import__(('libs.base.' + self.chip_type), fromlist=[self.chip_type]) + cfg_dir = app_path + '/utils/flash/' + self.chip_type + '/' + conf_name = sub_module.flash_select_do.get_suitable_file_name(cfg_dir, jedec_id) + offset, flashCfgLen, flash_para, flashCrcOffset, crcOffset = bflb_flash_select.update_flash_para_from_cfg(sub_module.bootheader_cfg_keys.bootheader_cfg_keys, cfg_dir + conf_name) + fp = open(os.path.join(app_path, file), 'wb+') + fp.write(flash_para) + fp.close() + return flash_para + + def is_conf_exist(self, flash_id): + cfg_dir = app_path + '/utils/flash/' + self.chip_type + '/' + conf_name = self.get_suitable_conf_name(cfg_dir, flash_id) + if os.path.isfile(cfg_dir + conf_name) is False: + return False + return True + + def flash_chiperase_main_process(self): + printf('Flash Chip Erase All') + if self._need_shake_hand != 0: + printf(FLASH_ERASE_SHAKE_HAND) + if self.img_load_shake_hand() is False: + printf('Shake hand fail') + return False + start_time = time.time() * 1000 + self.set_temp_timeout() + cmd_id = hexstr_to_bytearray(self._com_cmds.get('flash_chiperase')['cmd_id']) + try_cnt = 0 + while True: + ret, dmy = self.com_process_one_cmd('flash_chiperase', cmd_id, bytearray(0)) + if ret.startswith('OK'): + break + else: + if ret.startswith('PD'): + printf('erase pending') + while True: + ret = self.bflb_serial_object.deal_ack() + if ret.startswith('PD'): + printf('erase pending') + else: + self.bflb_serial_object.set_timeout(0.02) + self.bflb_serial_object.read(1000) + break + if time.time() * 1000 - start_time > self._erase_time_out: + printf('erase timeout') + break + + if ret.startswith('OK'): + break + if try_cnt < self._checksum_err_retry_limit: + printf('Retry') + try_cnt += 1 + else: + printf('Erase Fail') + self.bflb_serial_object.set_timeout(self._default_time_out) + self.error_code_print('0033') + return False + + printf('Chip erase time cost(ms): ', time.time() * 1000 - start_time) + self.bflb_serial_object.set_timeout(self._default_time_out) + return True + + def flash_cfg_option(self, read_flash_id, flash_para_file, flash_set, id_valid_flag, binfile, cfgfile, cfg, create_img_callback=None, create_simple_callback=None): + ret = bflb_flash_select.flash_bootheader_config_check(self.chip_type, read_flash_id, convert_path(binfile), flash_para_file) + if ret is False: + printf('flashcfg not match first') + if self.is_conf_exist(read_flash_id) is True: + update_cfg(cfg, 'FLASH_CFG', 'flash_id', read_flash_id) + if isinstance(cfgfile, BFConfigParser) == False: + cfg.write(cfgfile, 'w+') + if create_img_callback is not None: + create_img_callback() + else: + if create_simple_callback is not None: + create_simple_callback() + else: + self.error_code_print('003D') + return False + ret = bflb_flash_select.flash_bootheader_config_check(self.chip_name, read_flash_id, convert_path(binfile), flash_para_file) + if ret is False: + printf('flashcfg not match again') + self.error_code_print('0040') + return False + if flash_para_file: + if id_valid_flag != '80': + printf('flash para file: ', flash_para_file) + fp = open_file(flash_para_file, 'rb') + flash_para = bytearray(fp.read()) + fp.close() + ret = self.flash_set_para_main_process(flash_set, flash_para) + self._need_shake_hand = False + if ret is False: + return False + + def flash_switch_bank_process(self, bank): + """When the chip has two flashes, switch the flashes according to bank.""" + printf('Flash Switch Bank') + if self._need_shake_hand != 0: + printf('Flash switch bank shake hand') + if self.img_load_shake_hand() is False: + printf('Shake hand fail') + return False + start_time = time.time() * 1000 + self.bflb_serial_object.set_timeout(self._erase_time_out / 1000) + cmd_id = hexstr_to_bytearray(self._com_cmds.get('flash_switch_bank')['cmd_id']) + data_send = int_to_4bytearray_l(bank) + ret, dmy = self.com_process_one_cmd('flash_switch_bank', cmd_id, data_send) + if ret.startswith('OK') is False: + printf('Switch Fail') + self.bflb_serial_object.set_timeout(self._default_time_out) + self.error_code_print('0042') + return False + printf('Switch bank time cost(ms): ', time.time() * 1000 - start_time) + self.bflb_serial_object.set_timeout(self._default_time_out) + if bank == 0: + self._flash2_select = False + else: + self._flash2_select = True + return True + + def flash_load_opt(self, file, start_addr, callback=None): + printf('========= flash load =========') + if self._need_shake_hand != 0: + printf(FLASH_LOAD_SHAKE_HAND) + if self.img_load_shake_hand() is False: + return False + if self._flash2_select is True: + start_addr -= self._flash1_size + self.write_flash_data(file, start_addr, callback) + ret = self.flash_load_main_process(file, start_addr, callback) + if ret is False: + printf('Flash load fail') + return ret + fw_sha256 = '' + fp = open_file(file, 'rb') + flash_data = fp.read() + fp.close() + flash_data_len = len(flash_data) + if flash_data_len > 2097152: + self.bflb_serial_object.set_timeout(2.0 * (flash_data_len / 2097152 + 1)) + sh = hashlib.sha256() + sh.update(flash_data) + fw_sha256 = sh.hexdigest() + fw_sha256 = hexstr_to_bytearray(fw_sha256) + printf('Sha caled by host: ', binascii.hexlify(fw_sha256).decode('utf-8')) + del sh + printf('xip mode Verify') + ret, read_data = self.flash_xip_read_sha_main_process(start_addr, flash_data_len, 0, None, callback) + try: + printf('Sha caled by dev: ', binascii.hexlify(read_data).decode('utf-8')) + except: + printf('Sha caled by dev: ', binascii.hexlify(read_data)) + + if ret is True and read_data == fw_sha256: + printf('Verify success') + else: + printf('Verify fail') + self.flash_load_tips() + self.error_code_print('003E') + ret = False + if self.verify > 0: + fp = open_file(file, 'rb') + flash_data = bytearray(fp.read()) + fp.close() + flash_data_len = len(flash_data) + ret, read_data = self.flash_read_main_process(start_addr, flash_data_len, 0, None, callback) + if ret is True and read_data == flash_data: + printf('Verify success') + else: + printf('Verify fail') + self.flash_load_tips() + self.error_code_print('003E') + ret = False + printf('sbus mode Verify') + ret, read_data = self.flash_read_sha_main_process(start_addr, flash_data_len, 0, None, callback) + printf('Sha caled by dev: ', binascii.hexlify(read_data).decode('utf-8')) + if ret is True and read_data == fw_sha256: + printf('Verify success') + else: + printf('Verify fail') + self.flash_load_tips() + self.error_code_print('003E') + ret = False + self.bflb_serial_object.set_timeout(self._default_time_out) + return ret + + def flash_load_specified(self, file, start_addr, callback=None): + ret = False + run_state = 0 + temp_start_addr = start_addr + if len(self._skip_len) > 0 and self._skip_len[0] > 0: + fp = open_file(file, 'rb') + flash_data = fp.read() + fp.close() + flash_data_len = len(flash_data) + if self._skip_addr[0] > temp_start_addr + flash_data_len or self._skip_addr[-1] + self._skip_len[-1] < temp_start_addr: + ret = self.flash_load_opt(file, start_addr, callback) + return ret + for i in range(len(self._skip_addr)): + if self._skip_addr[i] <= start_addr: + if self._skip_addr[i] + self._skip_len[i] > start_addr and self._skip_addr[i] + self._skip_len[i] < temp_start_addr + flash_data_len: + addr = self._skip_addr[i] + self._skip_len[i] + start_addr = self._skip_addr[i] + self._skip_len[i] + else: + if self._skip_addr[i] > start_addr and self._skip_addr[i] + self._skip_len[i] < temp_start_addr + flash_data_len: + printf('skip flash file, skip addr 0x%08X, skip len 0x%08X' % ( + self._skip_addr[i], self._skip_len[i])) + addr = start_addr + data = flash_data[start_addr - temp_start_addr:self._skip_addr[i] - temp_start_addr] + filename, ext = os.path.splitext(file) + file_temp = os.path.join(app_path, filename + '_skip' + str(i) + ext) + fp = open(file_temp, 'wb') + fp.write(data) + fp.close() + ret = self.flash_load_opt(file_temp, addr, callback) + start_addr = self._skip_addr[i] + self._skip_len[i] + else: + if self._skip_addr[i] > start_addr: + if self._skip_addr[i] < temp_start_addr + flash_data_len and self._skip_addr[i] + self._skip_len[i] >= temp_start_addr + flash_data_len: + printf('skip flash file, skip addr 0x%08X, skip len 0x%08X' % ( + self._skip_addr[i], self._skip_len[i])) + addr = start_addr + data = flash_data[start_addr - temp_start_addr:self._skip_addr[i] - temp_start_addr] + filename, ext = os.path.splitext(file) + file_temp = os.path.join(app_path, filename + '_skip' + str(i) + ext) + fp = open(file_temp, 'wb') + fp.write(data) + fp.close() + ret = self.flash_load_opt(file_temp, addr, callback) + start_addr = temp_start_addr + flash_data_len + else: + if self._skip_addr[i] <= start_addr: + if self._skip_addr[i] + self._skip_len[i] >= temp_start_addr + flash_data_len: + printf('skip flash file, skip addr 0x%08X, skip len 0x%08X' % ( + self._skip_addr[i], self._skip_len[i])) + start_addr = temp_start_addr + flash_data_len + return True + + if start_addr < temp_start_addr + flash_data_len: + addr = start_addr + data = flash_data[start_addr - temp_start_addr:] + filename, ext = os.path.splitext(file) + file_temp = os.path.join(app_path, filename + '_skip' + str(i + 1) + ext) + fp = open(file_temp, 'wb') + fp.write(data) + fp.close() + ret = self.flash_load_opt(file_temp, addr, callback) + else: + ret = self.flash_load_opt(file, start_addr, callback) + return ret + + def flash_load_main_process(self, file, start_addr, callback=None): + fp = open_file(file, 'rb') + flash_data = bytearray(fp.read()) + fp.close() + flash_data_len = len(flash_data) + i = 0 + cur_len = 0 + if self.erase == 1: + ret = self.flash_erase_main_process(start_addr, start_addr + flash_data_len - 1) + if ret is False: + return False + start_time = time.time() * 1000 + log = '' + if self.decompress_write and flash_data_len > 4096: + self.bflb_serial_object.set_timeout(30.0) + start_addr |= 2147483648 + cmd_name = 'flash_decompress_write' + ret, flash_data, flash_data_len = self.flash_load_xz_compress(file) + if ret is False: + printf('Flash write data xz fail') + self.bflb_serial_object.set_timeout(self._default_time_out) + return False + if time.time() * 1000 - start_time > 2200: + printf(FLASH_LOAD_SHAKE_HAND) + if self.img_load_shake_hand() is False: + return False + else: + if time.time() * 1000 - start_time > 1800: + time.sleep(0.5) + printf(FLASH_LOAD_SHAKE_HAND) + if self.img_load_shake_hand() is False: + return False + printf('decompress flash load ', flash_data_len) + else: + cmd_name = 'flash_write' + while i < flash_data_len: + cur_len = flash_data_len - i + if cur_len > self._bflb_com_tx_size - 8: + cur_len = self._bflb_com_tx_size - 8 + cmd_id = hexstr_to_bytearray(self._com_cmds.get(cmd_name)['cmd_id']) + data_send = int_to_4bytearray_l(i + start_addr) + flash_data[i:i + cur_len] + start_addr &= 2147483647 + try_cnt = 0 + while True: + ret, dmy = self.com_process_one_cmd(cmd_name, cmd_id, data_send) + if ret.startswith('OK'): + break + if try_cnt < self._checksum_err_retry_limit: + printf('Retry') + try_cnt += 1 + else: + self.error_code_print('0036') + self.bflb_serial_object.set_timeout(self._default_time_out) + return False + + i += cur_len + log = 'Load ' + str(i) + '/' + str(flash_data_len) + ' {"progress":' + str(i * 100 // flash_data_len) + '}' + printf(log) + if callback is not None: + if flash_data_len > 200: + callback(i, flash_data_len, 'APP_WR') + + printf(log) + if self.flash_write_check_main_process() is False: + printf('Flash write check fail') + self.bflb_serial_object.set_timeout(self._default_time_out) + return False + self.bflb_serial_object.set_timeout(self._default_time_out) + printf('Flash load time cost(ms): ', time.time() * 1000 - start_time) + printf('Finished') + return True + + def flash_xip_read_sha_main_process(self, start_addr, flash_data_len, shakehand=0, file=None, callback=None): + readdata = bytearray(0) + if shakehand != 0: + printf(FLASH_LOAD_SHAKE_HAND) + if self.img_load_shake_hand() is False: + return (False, None) + cmd_id = hexstr_to_bytearray(self._com_cmds.get('flash_xip_read_start')['cmd_id']) + ret, dmy = self.com_process_one_cmd('flash_xip_read_start', cmd_id, bytearray(0)) + if ret.startswith('OK') is False: + self.error_code_print('0039') + return (False, None) + start_time = time.time() * 1000 + log = '' + cmd_id = hexstr_to_bytearray(self._com_cmds.get('flash_xip_readSha')['cmd_id']) + data_send = int_to_4bytearray_l(start_addr) + int_to_4bytearray_l(flash_data_len) + try_cnt = 0 + while True: + ret, data_read = self.com_process_one_cmd('flash_xip_readSha', cmd_id, data_send) + if ret.startswith('OK'): + break + if try_cnt < self._checksum_err_retry_limit: + printf('Retry') + try_cnt += 1 + else: + printf('Read Fail') + cmd_id = hexstr_to_bytearray(self._com_cmds.get('flash_xip_read_finish')['cmd_id']) + ret, dmy = self.com_process_one_cmd('flash_xip_read_finish', cmd_id, bytearray(0)) + if ret.startswith('OK') is False: + self.error_code_print('0039') + return (False, None) + return (False, None) + + log += 'Read Sha256/' + str(flash_data_len) + if callback is not None: + callback(flash_data_len, flash_data_len, 'APP_VR') + readdata += data_read + printf(log) + printf('Flash xip readsha time cost(ms): ', time.time() * 1000 - start_time) + printf('Finished') + if file is not None: + fp = open_file(file, 'wb+') + fp.write(readdata) + fp.close() + cmd_id = hexstr_to_bytearray(self._com_cmds.get('flash_xip_read_finish')['cmd_id']) + ret, dmy = self.com_process_one_cmd('flash_xip_read_finish', cmd_id, bytearray(0)) + if ret.startswith('OK') is False: + self.error_code_print('0039') + return (False, None) + return (True, readdata) + + def flash_read_sha_main_process(self, start_addr, flash_data_len, shakehand=0, file=None, callback=None): + readdata = bytearray(0) + if shakehand != 0: + printf(FLASH_LOAD_SHAKE_HAND) + if self.img_load_shake_hand() is False: + return (False, None) + start_time = time.time() * 1000 + log = '' + cmd_id = hexstr_to_bytearray(self._com_cmds.get('flash_readSha')['cmd_id']) + data_send = int_to_4bytearray_l(start_addr) + int_to_4bytearray_l(flash_data_len) + try_cnt = 0 + while True: + ret, data_read = self.com_process_one_cmd('flash_readSha', cmd_id, data_send) + if ret.startswith('OK'): + break + if try_cnt < self._checksum_err_retry_limit: + printf('Retry') + try_cnt += 1 + else: + self.error_code_print('0038') + return (False, None) + + log += 'Read Sha256/' + str(flash_data_len) + if callback is not None: + callback(flash_data_len, flash_data_len, 'APP_VR') + readdata += data_read + printf(log) + printf('Flash readsha time cost(ms): ', time.time() * 1000 - start_time) + printf('Finished') + if file is not None: + fp = open_file(file, 'wb+') + fp.write(readdata) + fp.close() + return (True, readdata) + + def flash_load_xz_compress(self, file): + try: + xz_filters = [ + {'id':lzma.FILTER_LZMA2, + 'dict_size':32768}] + fp = open_file(file, 'rb') + data = bytearray(fp.read()) + fp.close() + flash_data = lzma.compress(data, check=(lzma.CHECK_CRC32), filters=xz_filters) + flash_data_len = len(flash_data) + except Exception as e: + try: + printf(e) + return (False, None, None) + finally: + e = None + del e + + return ( + True, flash_data, flash_data_len) + + def flash_load_tips(self): + printf('########################################################################') + printf('请按照以下描述排查问题:') + printf('是否降低烧录波特率到500K测试过') + printf('烧写文件的大小是否超过Flash所能存储的最大空间') + printf('Flash是否被写保护') + printf('########################################################################') + + def flash_erase_main_process(self, start_addr, end_addr, shakehand=0): + printf('========= flash erase =========') + printf('Erase flash from ', hex(start_addr), ' to ', hex(end_addr)) + if shakehand != 0: + printf(FLASH_ERASE_SHAKE_HAND) + if self.img_load_shake_hand() is False: + printf('Shake hand fail') + return False + start_time = time.time() * 1000 + self.set_temp_timeout() + cmd_id = hexstr_to_bytearray(self._com_cmds.get('flash_erase')['cmd_id']) + data_send = int_to_4bytearray_l(start_addr) + int_to_4bytearray_l(end_addr) + try_cnt = 0 + while True: + ret, dmy = self.com_process_one_cmd('flash_erase', cmd_id, data_send) + if ret.startswith('OK'): + break + else: + if ret.startswith('PD'): + printf('erase pending') + while True: + ret = self.bflb_serial_object.deal_ack() + if ret.startswith('PD'): + printf('erase pending') + else: + self.bflb_serial_object.set_timeout(0.02) + self.bflb_serial_object.read(1000) + break + if time.time() * 1000 - start_time > self._erase_time_out: + printf('erase timeout') + break + + if ret.startswith('OK'): + break + if try_cnt < self._checksum_err_retry_limit: + printf('Retry') + try_cnt += 1 + else: + printf('Erase Fail') + self.bflb_serial_object.set_timeout(self._default_time_out) + self.error_code_print('0034') + return False + + printf('Erase time cost(ms): ', time.time() * 1000 - start_time) + self.bflb_serial_object.set_timeout(self._default_time_out) + return True + + def flash_read_main_process(self, start_addr, flash_data_len, shakehand=0, file=None, callback=None): + printf('========= flash read =========') + i = 0 + cur_len = 0 + readdata = bytearray(0) + if shakehand != 0: + printf(FLASH_LOAD_SHAKE_HAND) + if self.img_load_shake_hand() is False: + return (False, None) + start_time = time.time() * 1000 + log = '' + while i < flash_data_len: + cur_len = flash_data_len - i + if cur_len > self._bflb_com_tx_size - 8: + cur_len = self._bflb_com_tx_size - 8 + else: + cmd_id = hexstr_to_bytearray(self._com_cmds.get('flash_read')['cmd_id']) + data_send = int_to_4bytearray_l(i + start_addr) + int_to_4bytearray_l(cur_len) + try_cnt = 0 + while True: + ret, data_read = self.com_process_one_cmd('flash_read', cmd_id, data_send) + if ret.startswith('OK'): + break + if try_cnt < self._checksum_err_retry_limit: + printf('Retry') + try_cnt += 1 + else: + self.error_code_print('0035') + return (False, None) + + i += cur_len + log += 'Read ' + str(i) + '/' + str(flash_data_len) + if len(log) > 50: + printf(log) + log = '' + else: + log += '\n' + if callback is not None: + callback(i, flash_data_len, 'APP_VR') + readdata += data_read + + printf(log) + printf('Flash read time cost(ms): ', time.time() * 1000 - start_time) + printf('Finished') + if file is not None: + fp = open_file(file, 'wb+') + fp.write(readdata) + fp.close() + return (True, readdata) + + def flash_write_check_main_process(self, shakehand=0): + printf('Write check') + if shakehand != 0: + printf(FLASH_LOAD_SHAKE_HAND) + if self.img_load_shake_hand() is False: + return False + cmd_id = hexstr_to_bytearray(self._com_cmds.get('flash_write_check')['cmd_id']) + try_cnt = 0 + while True: + retry = 0 + if self.decompress_write: + retry = 10 + ret, dmy = self.com_process_one_cmd('flash_write_check', cmd_id, bytearray(0)) + if ret.startswith('OK'): + break + if try_cnt < self._checksum_err_retry_limit + retry: + printf('Retry') + try_cnt += 1 + else: + self.error_code_print('0037') + return False + + return True + + def efuse_load_specified(self, file, maskfile, efusedata, efusedatamask, verify=0, security_write=False): + printf('========= efuse load =========') + if self._need_shake_hand != 0: + printf('Efuse load shake hand') + ret = self.img_load_shake_hand() + if ret is False: + return False + ret = self.efuse_load_main_process(file, maskfile, efusedata, efusedatamask, verify, security_write) + return ret + + def efuse_load_main_process(self, file, maskfile, efusedata, efusedatamask, verify=0, security_write=False): + if efusedata != bytearray(0): + printf('Load data') + efuse_data = efusedata + mask_data = efusedatamask + else: + if file is not None: + printf('Load file: ', file) + fp = open_file(file, 'rb') + efuse_data = bytearray(fp.read()) + bytearray(0) + fp.close() + if verify: + fp = open_file(maskfile, 'rb') + mask_data = bytearray(fp.read()) + bytearray(0) + fp.close() + else: + mask_data = bytearray(0) + if len(efuse_data) > 4096: + printf('Decrypt efuse data') + efuse_data = efuse_data[4096:] + security_key, security_iv = get_security_key() + efuse_data = aes_decrypt_data(efuse_data, security_key, security_iv, 0) + else: + efuse_data = self._efuse_data + if verify: + mask_data = self._efuse_mask_data + else: + mask_data = bytearray(0) + if security_write: + if self.get_ecdh_shared_key() is not True: + return False + printf('Load efuse 0') + if security_write: + cmd_name = 'efuse_security_write' + else: + cmd_name = 'efuse_write' + cmd_id = hexstr_to_bytearray(self._com_cmds.get(cmd_name)['cmd_id']) + data_send = efuse_data[0:124] + bytearray(4) + if security_write: + data_send = self.ecdh_encrypt_data(data_send) + data_send = int_to_4bytearray_l(0) + data_send + ret, dmy = self.com_process_one_cmd(cmd_name, cmd_id, data_send) + if ret.startswith('OK') is False: + printf('Write Fail') + self.error_code_print('0021') + return False + if verify >= 1: + ret, read_data = self.efuse_read_main_process(0, 128, shakehand=0, file=None, security_read=security_write) + if ret is True and self.efuse_compare(read_data, mask_data[0:124] + bytearray(4), efuse_data[0:124] + bytearray(4)): + printf('Verify success') + else: + printf('Read: ') + printf(binascii.hexlify(read_data[0:124]).decode('utf-8')) + printf('Expected: ') + printf(binascii.hexlify(efuse_data[0:124]).decode('utf-8')) + printf('Verify fail') + self.error_code_print('0022') + return False + data_send = bytearray(12) + efuse_data[124:128] + if security_write: + data_send = self.ecdh_encrypt_data(data_send) + data_send = int_to_4bytearray_l(112) + data_send + ret, dmy = self.com_process_one_cmd(cmd_name, cmd_id, data_send) + if ret.startswith('OK') is False: + printf('Write Fail') + self.error_code_print('0021') + return False + if verify >= 1: + ret, read_data = self.efuse_read_main_process(112, 16, shakehand=0, file=None, security_read=security_write) + if ret is True and self.efuse_compare(read_data, bytearray(12) + mask_data[124:128], bytearray(12) + efuse_data[124:128]): + printf('Verify success') + else: + printf('Read: ') + printf(binascii.hexlify(read_data[12:16])) + printf('Expected: ') + printf(binascii.hexlify(efuse_data[124:128])) + printf('Verify fail') + self.error_code_print('0022') + return False + if len(efuse_data) > 128: + printf('Load efuse 1') + if security_write: + cmd_name = 'efuse_security_write' + else: + cmd_name = 'efuse_write' + cmd_id = hexstr_to_bytearray(self._com_cmds.get(cmd_name)['cmd_id']) + data_send = efuse_data[128:252] + bytearray(4) + if security_write: + data_send = self.ecdh_encrypt_data(data_send) + data_send = int_to_4bytearray_l(128) + data_send + ret, dmy = self.com_process_one_cmd(cmd_name, cmd_id, data_send) + if ret.startswith('OK') is False: + printf('Write Fail') + self.error_code_print('0021') + return False + if verify >= 1: + ret, read_data = self.efuse_read_main_process(128, 128, shakehand=0, file=None, security_read=security_write) + if ret is True and self.efuse_compare(read_data, mask_data[128:252] + bytearray(4), efuse_data[128:252] + bytearray(4)): + printf('Verify success') + else: + printf('Verify fail') + self.error_code_print('0022') + return False + data_send = bytearray(12) + efuse_data[252:256] + if security_write: + data_send = self.ecdh_encrypt_data(data_send) + data_send = int_to_4bytearray_l(240) + data_send + ret, dmy = self.com_process_one_cmd(cmd_name, cmd_id, data_send) + if ret.startswith('OK') is False: + printf('Write Fail') + self.error_code_print('0021') + return False + if verify >= 1: + ret, read_data = self.efuse_read_main_process(240, 16, shakehand=0, file=None, security_read=security_write) + if ret is True and self.efuse_compare(read_data, bytearray(12) + mask_data[252:256], bytearray(12) + efuse_data[252:256]): + printf('Verify success') + else: + printf('Verify fail') + self.error_code_print('0022') + printf('Finished') + return True + + def efuse_read_main_process(self, start_addr, data_len, shakehand=0, file=None, security_read=False): + readdata = bytearray(0) + if shakehand != 0: + printf(FLASH_LOAD_SHAKE_HAND) + if self.img_load_shake_hand() is False: + return (False, None) + if security_read: + cmd_name = 'efuse_security_read' + else: + cmd_name = 'efuse_read' + cmd_id = hexstr_to_bytearray(self._com_cmds.get(cmd_name)['cmd_id']) + data_send = int_to_4bytearray_l(start_addr) + int_to_4bytearray_l(data_len) + ret, data_read = self.com_process_one_cmd(cmd_name, cmd_id, data_send) + printf('Read efuse ') + if ret.startswith('OK') is False: + self.error_code_print('0020') + return (False, None) + readdata += data_read + if security_read: + readdata = self.ecdh_decrypt_data(readdata) + printf('Finished') + if file is not None: + fp = open_file(file, 'wb+') + fp.write(readdata) + fp.close() + return (True, readdata) + + def efuse_compare(self, read_data, maskdata, write_data): + i = 0 + for i in range(len(read_data)): + compare_data = read_data[i] & maskdata[i] + if compare_data & write_data[i] != write_data[i]: + printf('compare fail: ', i) + printf(read_data[i], write_data[i]) + return False + + return True + + def img_load_shake_hand(self): + isp_sh_time = self.get_isp_sh_time() + if self.interface.lower() == 'uart': + self.bflb_serial_object.repeat_init(self.device, self.speed, self.chip_type, self.chip_name) + if self._bflb_com_img_loader.toggle_boot_or_shake_hand(2, do_reset=False, + reset_hold_time=100, + shake_hand_delay=100, + reset_revert=True, + cutoff_time=0, + isp_mode_sign=(self.isp_mode_sign), + isp_timeout=isp_sh_time, + boot_load=False, + shake_hand_retry=2) != 'OK': + self.error_code_print('0001') + return False + else: + self.bflb_serial_object.if_init(self.device, self.speed, self.chip_type, self.chip_name) + if self.bflb_serial_object.if_shakehand(do_reset=False, reset_hold_time=100, + shake_hand_delay=100, + reset_revert=True, + cutoff_time=0, + shake_hand_retry=2, + isp_timeout=isp_sh_time, + boot_load=False) != 'OK': + self.error_code_print('0001') + return False + self._need_shake_hand = False + return True + + def com_process_one_cmd(self, section, cmd_id, data_send): + data_read = bytearray(0) + data_len = int_to_2bytearray_l(len(data_send)) + checksum = 0 + checksum += bytearray_to_int(data_len[0:1]) + bytearray_to_int(data_len[1:2]) + for char in data_send: + checksum += char + + data = cmd_id + int_to_2bytearray_l(checksum & 255)[0:1] + data_len + data_send + if self.interface.lower() == 'uart': + self.bflb_serial_object.write(data) + if section in self._resp_cmds: + res, data_read = self.bflb_serial_object.deal_response() + else: + res = self.bflb_serial_object.deal_ack() + else: + self.bflb_serial_object.if_write(data) + if section in self._resp_cmds: + res, data_read = self.bflb_serial_object.if_deal_response() + else: + res = self.bflb_serial_object.if_deal_ack() + return ( + res, data_read) + + def get_suitable_conf_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: + printf('Flash id duplicate and alternative is:') + for i in range(len(conf_files)): + tmp = conf_files[i].split('.')[0] + printf('%d:%s' % (i + 1, tmp)) + + return conf_files[i] + if len(conf_files) == 1: + return conf_files[0] + return '' + + def get_ecdh_shared_key(self, shakehand=0): + printf('========= get ecdh shared key =========') + publickey_file = 'utils/pem/publickey_uecc.pem' + if shakehand != 0: + printf('Shake hand') + ret = self.img_load_shake_hand() + if ret is False: + return + tmp_ecdh = bflb_ecdh.BflbEcdh() + self._ecdh_public_key = tmp_ecdh.create_public_key() + self._ecdh_private_key = binascii.hexlify(tmp_ecdh.ecdh.private_key.to_string()).decode('utf-8') + printf('ecdh public key') + printf(self._ecdh_public_key) + printf('ecdh private key') + printf(self._ecdh_private_key) + cmd_id = hexstr_to_bytearray(self._com_cmds.get('ecdh_get_pk')['cmd_id']) + data_send = bytearray.fromhex(self._ecdh_public_key) + ret, data_read = self.com_process_one_cmd('ecdh_get_pk', cmd_id, data_send) + if ret.startswith('OK') is True: + self._ecdh_peer_public_key = binascii.hexlify(data_read).decode('utf-8') + printf('ecdh peer key') + printf(self._ecdh_peer_public_key) + self._ecdh_shared_key = tmp_ecdh.create_shared_key(self._ecdh_peer_public_key[0:128]) + printf('ecdh shared key') + printf(self._ecdh_shared_key) + cmd_id = hexstr_to_bytearray(self._com_cmds.get('ecdh_chanllenge')['cmd_id']) + data_send = bytearray(0) + ret, data_read = self.com_process_one_cmd('ecdh_chanllenge', cmd_id, data_send) + if ret.startswith('OK') is True: + printf('challenge data') + printf(binascii.hexlify(data_read).decode('utf-8')) + encrypted_data = data_read[0:32] + signature = data_read[32:96] + signature_r = data_read[32:64] + signature_s = data_read[64:96] + vk = ecdsa.VerifyingKey.from_pem(open_file('utils\\pem\\room_root_publickey_ecc.pem').read()) + try: + ret = vk.verify(signature, (self.ecdh_decrypt_data(encrypted_data)), + hashfunc=(hashlib.sha256), + sigdecode=(ecdsa.util.sigdecode_string)) + except Exception as err: + try: + printf(err) + finally: + err = None + del err + + if ret is True: + return True + printf('Challenge verify fail') + return False + else: + printf('Challenge ack fail') + return False + else: + printf('Get shared key fail') + return False + + def ecdh_encrypt_data(self, data): + cryptor = AES.new(bytearray.fromhex(self._ecdh_shared_key[0:32]), AES.MODE_CBC, bytearray(16)) + ciphertext = cryptor.encrypt(data) + return ciphertext + + def ecdh_decrypt_data(self, data): + cryptor = AES.new(bytearray.fromhex(self._ecdh_shared_key[0:32]), AES.MODE_CBC, bytearray(16)) + plaintext = cryptor.decrypt(data) + return plaintext + + def close_serial(self): + if self.bflb_serial_object: + try: + self.bflb_serial_object.close() + except Exception as e: + try: + printf(e) + finally: + e = None + del e + + def clear_all_data(self): + if self.bflb_serial_object: + try: + self.bflb_serial_object.clear_buf() + except Exception as e: + try: + printf(e) + finally: + e = None + del e + + def base_reset_cpu(self): + if self.bflb_serial_object: + self.bflb_serial_object.reset_cpu() + + def object_status_clear(self): + self.bootinfo = None + self._macaddr_check = bytearray(0) + self._macaddr_check_status = False + + def flash_read_status_reg_process(self, cmd, len, callback=None): + printf('========= flash read status register =========') + readdata = bytearray(0) + if self._need_shake_hand is not False: + printf(FLASH_LOAD_SHAKE_HAND) + if self.img_load_shake_hand() is False: + return (False, None) + cmd_id = hexstr_to_bytearray(self._com_cmds.get('flash_read_status_reg')['cmd_id']) + data_send = int_to_4bytearray_l(int(cmd, 16)) + int_to_4bytearray_l(len) + ret, data_read = self.com_process_one_cmd('flash_read_status_reg', cmd_id, data_send) + printf('Read flash status register ') + if ret.startswith('OK') is False: + self.error_code_print('0031') + return (False, None) + readdata += data_read + printf('readdata: ') + printf(binascii.hexlify(readdata)) + printf('Finished') + return ( + True, readdata) + + def flash_write_status_reg_process(self, cmd, len, write_data, callback=None): + printf('========= flash write status register =========') + if self._need_shake_hand is not False: + printf(FLASH_LOAD_SHAKE_HAND) + if self.img_load_shake_hand() is False: + return (False, 'Flash load shake hand fail') + printf('write_data ', write_data) + cmd_id = hexstr_to_bytearray(self._com_cmds.get('flash_write_status_reg')['cmd_id']) + data_send = int_to_4bytearray_l(int(cmd, 16)) + int_to_4bytearray_l(len) + int_to_4bytearray_l(int(write_data, 16)) + ret, data_read = self.com_process_one_cmd('flash_write_status_reg', cmd_id, data_send) + printf('Write flash status register ') + if ret.startswith('OK') is False: + self.error_code_print('0032') + return (False, 'Write fail') + printf('Finished') + return (True, None) + + 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) + if os.path.exists(files[i]): + datalen = os.path.getsize(files[i]) + else: + datalen = os.path.getsize(os.path.join(app_path, files[i])) + + return maxlen + datalen + + def bl_get_file_data(self, files): + datas = [] + for file in files: + if os.path.exists(file): + temp_path = file + else: + temp_path = os.path.join(app_path, file) + with open(temp_path, 'rb') as fp: + data = fp.read() + datas.append(data) + + return datas + + def bl_create_flash_default_data(self, length): + datas = bytearray(length) + for i in range(length): + datas[i] = 255 + + return datas + + def bl_write_flash_img(self, d_addrs, d_files, flash_size='1M'): + whole_img_len = self.bl_get_largest_addr(d_addrs, d_files) + whole_img_data = self.bl_create_flash_default_data(whole_img_len) + whole_img_file = os.path.join(chip_path, self.chip_name, 'img_create', 'whole_flash_data.bin') + if os.path.exists(whole_img_file): + os.remove(whole_img_file) + 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] + + if not os.path.exists(os.path.dirname(whole_img_file)): + os.makedirs(os.path.dirname(whole_img_file)) + fp = open(whole_img_file, 'wb+') + fp.write(whole_img_data) + fp.close() + + def get_flash_pin_from_bootinfo(self, chiptype, bootinfo): + return 128 +# okay decompiling ./libs/base/bflb_base_eflash_loader.pyc diff --git a/libs/base/bflb_efuse_boothd_create.py b/libs/base/bflb_efuse_boothd_create.py new file mode 100644 index 0000000..2712d80 --- /dev/null +++ b/libs/base/bflb_efuse_boothd_create.py @@ -0,0 +1,241 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/bflb_efuse_boothd_create.py +import os, sys, shutil, traceback +from libs import bflb_utils +from libs.bflb_utils import app_path, chip_path, convert_path +from libs.bflb_configobj import BFConfigParser + +def bootheader_update_flash_pll_crc(bootheader_data, chiptype): + flash_cfg_start = 8 + flash_cfg_len = 92 + if chiptype == 'wb03': + flash_cfg_start += 208 + flash_cfg = bootheader_data[flash_cfg_start + 4:flash_cfg_start + flash_cfg_len - 4] + crcarray = bflb_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 = 16 + if chiptype == 'bl808': + pll_cfg_len = 28 + else: + if chiptype == 'bl616' or chiptype == 'wb03': + pll_cfg_len = 20 + pll_cfg = bootheader_data[pll_cfg_start + 4:pll_cfg_start + pll_cfg_len - 4] + crcarray = bflb_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(pos, length): + ones = '11111111111111111111111111111111' + zeros = '00000000000000000000000000000000' + mask = ones[0:32 - pos - length] + zeros[0:length] + ones[0:pos] + return int(mask, 2) + + +def update_data_from_cfg(config_keys, config_file, section): + bflb_utils.printf('Updating data according to <' + config_file + '[' + section + ']>') + cfg = BFConfigParser() + cfg.read(config_file) + filelen = 0 + for key in config_keys: + offset = int(config_keys.get(key)['offset'], 10) + if offset > filelen: + filelen = offset + + filelen += 4 + bflb_utils.printf('Created file len:' + str(filelen)) + data = bytearray(filelen) + data_mask = bytearray(filelen) + for key in cfg.options(section): + if config_keys.get(key) is None: + bflb_utils.printf(key + ' not exist') + continue + else: + 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 = bflb_utils.bytearray_to_int(bflb_utils.bytearray_reverse(data[offset:offset + 4])) + oldval_mask = bflb_utils.bytearray_to_int(bflb_utils.bytearray_reverse(data_mask[offset:offset + 4])) + newval = (oldval & get_int_mask(pos, bitlen)) + (val << pos) + if val != 0: + newval_mask = oldval_mask | ~get_int_mask(pos, bitlen) + else: + newval_mask = oldval_mask + data[offset:offset + 4] = bflb_utils.int_to_4bytearray_l(newval) + data_mask[offset:offset + 4] = bflb_utils.int_to_4bytearray_l(newval_mask) + + return (data, data_mask) + + +def bootheader_create_do(chipname, chiptype, config_file, section, output_file=None, if_img=False): + efuse_bootheader_path = os.path.join(chip_path, chipname, 'efuse_bootheader') + try: + bflb_utils.printf('Create bootheader using ', config_file) + sub_module = __import__(('libs.' + chiptype), fromlist=[chiptype]) + bh_data, tmp = update_data_from_cfg(sub_module.bootheader_cfg_keys.bootheader_cfg_keys, config_file, section) + bh_data = bootheader_update_flash_pll_crc(bh_data, chiptype) + if output_file is None: + fp = open(efuse_bootheader_path + '/' + section.lower().replace('_cfg', '.bin'), 'wb+') + else: + fp = open(output_file, 'wb+') + if section == 'BOOTHEADER_CFG': + if chiptype == 'bl60x': + final_data = bytearray(8192) + bh_data[118] = bh_data[118] | 4 + final_data[0:176] = bh_data + final_data[4096:4272] = bh_data + final_data[4098] = 65 + final_data[117] = final_data[117] | 240 + final_data[4214] = final_data[4214] | 3 + bh_data = final_data + if if_img is True: + bh_data[8:12] = bytearray(4) + bh_data[100:104] = bytearray(4) + if chiptype == 'bl808': + fp.write(bh_data[0:384]) + else: + if chiptype == 'bl616': + fp.write(bh_data[0:256]) + else: + if chiptype == 'wb03': + fp.write(bh_data[0:464]) + else: + if chiptype == 'bl702l': + fp.write(bh_data[0:240]) + else: + fp.write(bh_data[0:176]) + else: + fp.write(bh_data) + fp.close() + if chiptype == 'bl808': + if section == 'BOOTHEADER_GROUP0_CFG': + fp = open(efuse_bootheader_path + '/clock_para.bin', 'wb+') + fp.write(bh_data[100:128]) + fp.close() + fp = open(efuse_bootheader_path + '/flash_para.bin', 'wb+') + fp.write(bh_data[12:96]) + fp.close() + else: + if chiptype == 'bl616': + if section == 'BOOTHEADER_GROUP0_CFG': + fp = open(efuse_bootheader_path + '/clock_para.bin', 'wb+') + fp.write(bh_data[100:120]) + fp.close() + fp = open(efuse_bootheader_path + '/flash_para.bin', 'wb+') + fp.write(bh_data[12:96]) + fp.close() + else: + if chiptype == 'wb03': + if section == 'BOOTHEADER_GROUP0_CFG': + fp = open(efuse_bootheader_path + '/clock_para.bin', 'wb+') + fp.write(bh_data[308:328]) + fp.close() + fp = open(efuse_bootheader_path + '/flash_para.bin', 'wb+') + fp.write(bh_data[220:304]) + fp.close() + else: + if chiptype == 'bl702l': + if section == 'BOOTHEADER_CFG': + fp = open(efuse_bootheader_path + '/clock_para.bin', 'wb+') + fp.write(bh_data[100:116]) + fp.close() + fp = open(efuse_bootheader_path + '/flash_para.bin', 'wb+') + fp.write(bh_data[12:96]) + fp.close() + else: + fp = open(efuse_bootheader_path + '/flash_para.bin', 'wb+') + fp.write(bh_data[12:96]) + fp.close() + except Exception as e: + try: + bflb_utils.printf('bootheader_create_do fail!!') + bflb_utils.printf(e) + traceback.print_exc(limit=5, file=(sys.stdout)) + finally: + e = None + del e + + +def bootheader_create_process(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: + bootheader_create_do(chipname, chiptype, config_file, 'BOOTHEADER_CFG', output_file1, if_img) + if 'BOOTHEADER_CPU0_CFG' in data: + bootheader_create_do(chipname, chiptype, config_file, 'BOOTHEADER_CPU0_CFG', output_file1, if_img) + if 'BOOTHEADER_CPU1_CFG' in data: + bootheader_create_do(chipname, chiptype, config_file, 'BOOTHEADER_CPU1_CFG', output_file2, if_img) + if 'BOOTHEADER_GROUP0_CFG' in data: + bootheader_create_do(chipname, chiptype, config_file, 'BOOTHEADER_GROUP0_CFG', output_file1, if_img) + if 'BOOTHEADER_GROUP1_CFG' in data: + bootheader_create_do(chipname, chiptype, config_file, 'BOOTHEADER_GROUP1_CFG', output_file2, if_img) + + +def efuse_create_process(chipname, chiptype, config_file, output_file=None): + efuse_bootheader_path = os.path.join(chip_path, chipname, 'efuse_bootheader') + eflash_loader_path = os.path.join(chip_path, chipname, 'eflash_loader') + filedir = '' + bflb_utils.printf('Create efuse using ', config_file) + cfgfile = eflash_loader_path + '/eflash_loader_cfg.ini' + if os.path.isfile(cfgfile) is False: + shutil.copyfile(eflash_loader_path + '/eflash_loader_cfg.conf', cfgfile) + cfg = BFConfigParser() + cfg.read(cfgfile) + sub_module = __import__(('libs.' + chiptype), fromlist=[chiptype]) + efuse_data, mask = update_data_from_cfg(sub_module.efuse_cfg_keys.efuse_cfg_keys, config_file, 'EFUSE_CFG') + if output_file is None: + filedir = efuse_bootheader_path + '/efusedata.bin' + else: + filedir = output_file + fp = open(filedir, 'wb+') + fp.write(efuse_data) + fp.close() + bflb_utils.update_cfg(cfg, 'EFUSE_CFG', 'file', convert_path(os.path.relpath(filedir, app_path))) + if output_file is None: + filedir = efuse_bootheader_path + '/efusedata_mask.bin' + else: + filedir = output_file.replace('.bin', '_mask.bin') + fp = open(filedir, 'wb+') + fp.write(mask) + fp.close() + bflb_utils.update_cfg(cfg, 'EFUSE_CFG', 'maskfile', convert_path(os.path.relpath(filedir, app_path))) + cfg.write(cfgfile, 'w+') + + +def efuse_boothd_create_process(chipname, chiptype, config_file): + bootheader_create_process(chipname, chiptype, config_file) + efuse_create_process(chipname, chiptype, config_file) + + +def run(): + chip_dict = { + 'bl56x': 'bl60x', + 'bl60x': 'bl60x', + 'bl562': 'bl602', + 'bl602': 'bl602', + 'bl702': 'bl702', + 'bl702l': 'bl702l', + 'bl808': 'bl808', + 'bl616': 'bl616', + 'wb03': 'wb03'} + chipname = sys.argv[1] + chiptype = chip_dict[chipname] + img_create_path = os.path.join(chip_path, chipname, 'img_create_mcu') + bh_cfg_file = img_create_path + '/efuse_bootheader_cfg.ini' + bh_file = img_create_path + '/bootheader.bin' + bootheader_create_process(chipname, chiptype, bh_cfg_file, bh_file, img_create_path + '/bootheader_dummy.bin') + + +if __name__ == '__main__': + run() +# okay decompiling ./libs/base/bflb_efuse_boothd_create.pyc diff --git a/libs/base/bflb_flash_select.py b/libs/base/bflb_flash_select.py new file mode 100644 index 0000000..2ac6e2d --- /dev/null +++ b/libs/base/bflb_flash_select.py @@ -0,0 +1,170 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/bflb_flash_select.py +import os, re +from libs import bflb_utils +from libs.bflb_utils import app_path, chip_path, conf_sign +from libs.bflb_configobj import BFConfigParser + +def get_int_mask(pos, length): + ones = '11111111111111111111111111111111' + zeros = '00000000000000000000000000000000' + mask = ones[0:32 - pos - length] + zeros[0:length] + ones[0:pos] + return int(mask, 2) + + +def update_flash_para_from_cfg(config_keys, config_file): + section = 'FLASH_CFG' + cfg = BFConfigParser() + cfg.read(config_file) + filelen = 0 + offset = 0 + minOffset = 4294967295 + maxOffset = 0 + flashCrcOffset = 0 + crcOffset = 0 + if config_keys.get('crc32') != None: + crcOffset = int(config_keys.get('crc32')['offset'], 10) + if config_keys.get('flashcfg_crc32') != None: + flashCrcOffset = int(config_keys.get('flashcfg_crc32')['offset'], 10) + for key in cfg.options(section): + if config_keys.get(key) == None: + continue + else: + offset = int(config_keys.get(key)['offset'], 10) + if offset < minOffset: + minOffset = offset + if offset > maxOffset: + maxOffset = offset + + filelen = maxOffset - minOffset + 4 + data = bytearray(filelen) + for key in cfg.options(section): + if config_keys.get(key) == None: + bflb_utils.printf(key + ' not exist') + continue + else: + 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) - minOffset + pos = int(config_keys.get(key)['pos'], 10) + bitlen = int(config_keys.get(key)['bitlen'], 10) + oldval = bflb_utils.bytearray_to_int(bflb_utils.bytearray_reverse(data[offset:offset + 4])) + newval = (oldval & get_int_mask(pos, bitlen)) + (val << pos) + data[offset:offset + 4] = bflb_utils.int_to_4bytearray_l(newval) + + return (minOffset, filelen, data, flashCrcOffset, crcOffset) + + +def update_flash_cfg_data_do(chiptype, flash_id): + cfg_dir = app_path + '/utils/flash/' + chiptype + '/' + sub_module = __import__(('libs.base.' + chiptype), fromlist=[chiptype]) + conf_name = sub_module.flash_select_do.get_suitable_file_name(cfg_dir, flash_id) + if os.path.isfile(cfg_dir + conf_name) == False: + return (None, None, None, None, None) + return update_flash_para_from_cfg(sub_module.bootheader_cfg_keys.bootheader_cfg_keys, cfg_dir + conf_name) + + +def flash_bootheader_config_check(chiptype, flashid, file, parafile): + magic_code = 1347307074 + flash_magic_code = 1195787078 + offset, flashCfgLen, data, flashCrcOffset, crcOffset = update_flash_cfg_data_do(chiptype, flashid) + if data is None: + offset = 12 + flashCfgLen = 84 + if parafile != '': + if data != None: + fp = open(os.path.join(app_path, parafile), 'wb') + fp.write(data) + fp.close() + fp = open(os.path.join(app_path, file), 'rb') + rdata = bytearray(fp.read()) + fp.close() + i = 0 + length = 128 + flashCfg = bytearray(256) + while i < length: + if rdata[i:i + 4] == bflb_utils.int_to_4bytearray_l(magic_code): + if rdata[i + 8:i + 12] == bflb_utils.int_to_4bytearray_l(flash_magic_code): + if data != None: + data[2:4] = rdata[i + 14:i + 16] + flashCfg = rdata[i + offset:i + offset + flashCfgLen] + if data != None: + if not data != flashCfg and flashCfg[13:14] != b'\xff' or flashCfg[13:14] != b'\x00': + return False + else: + if flashCfg[13:14] != b'\xff': + if flashCfg[13:14] != b'\x00': + return False + i += 4 + + return True + + +def update_flash_cfg_data(chiptype, flash_id, cfg, bh_cfg_file, cfg_key): + cfg2 = BFConfigParser() + cfg2.read(bh_cfg_file) + magic_code = cfg2.get(cfg_key, 'magic_code') + magic_code = int(magic_code, 16) + flash_magic_code = cfg2.get(cfg_key, 'flashcfg_magic_code') + flash_magic_code = int(flash_magic_code, 16) + sub_module = __import__(('libs.' + chiptype), fromlist=[chiptype]) + offset, flashCfgLen, data, flashCrcOffset, crcOffset = update_flash_cfg_data_do(chiptype, flash_id) + para_file = cfg.get('FLASH_CFG', 'flash_para') + if para_file != '': + fp = open(os.path.join(app_path, para_file), 'wb') + fp.write(data) + fp.close() + flash_file = re.compile('\\s+').split(cfg.get('FLASH_CFG', 'file')) + for f in flash_file: + fp = open(os.path.join(app_path, f), 'rb') + rdata = bytearray(fp.read()) + fp.close() + i = 0 + length = len(rdata) + while i < length: + if rdata[i:i + 4] == bflb_utils.int_to_4bytearray_l(magic_code): + if rdata[i + 8:i + 12] == bflb_utils.int_to_4bytearray_l(flash_magic_code): + data[2:4] = rdata[i + 14:i + 16] + flashCfg = rdata[i + offset:i + offset + flashCfgLen] + if data != flashCfg: + return False + i += 4 + + return True + + +def check_basic_flash_cfg(cfg_file, section): + if os.path.isfile(cfg_file) is False: + return False + cfg = BFConfigParser() + cfg.read(cfg_file) + if cfg.has_option(section, 'mfg_id'): + if cfg.get(section, 'mfg_id') == '0xff' or cfg.get(section, 'mfg_id') == '0xFF': + cfg.set(section, 'io_mode', '0x10') + cfg.set(section, 'cont_read_support', '0') + cfg.write(cfg_file, 'w+') + return True + if cfg.get(section, 'mfg_id') == '0x00': + return True + return False + + +def update_flash_cfg(chipname, chiptype, flash_id, file=None, create=False, section=None): + sub_module = __import__(('libs.' + chiptype), fromlist=[chiptype]) + if check_basic_flash_cfg(file, section): + return True + if sub_module.flash_select_do.update_flash_cfg_do(chipname, chiptype, flash_id, file, create, section) == False: + return False + return True + + +def get_supported_flash(chiptype): + sub_module = __import__(('libs.' + chiptype), fromlist=[chiptype]) + return sub_module.flash_select_do.get_supported_flash_do() +# okay decompiling ./libs/base/bflb_flash_select.pyc diff --git a/libs/base/bflb_img_create.py b/libs/base/bflb_img_create.py new file mode 100644 index 0000000..681a1b7 --- /dev/null +++ b/libs/base/bflb_img_create.py @@ -0,0 +1,179 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/bflb_img_create.py +import re, os, sys, time, shutil, zipfile +from libs import bflb_utils +from libs.bflb_utils import app_path, chip_path, set_error_code, convert_path +from libs.bflb_configobj import BFConfigParser +from libs.base import bflb_efuse_boothd_create + +def take_second(elem): + return elem[1] + + +def factory_mode_set(file, value): + cfg = BFConfigParser() + cfg.read(file) + if cfg.has_option('EFUSE_CFG', 'factory_mode'): + cfg.set('EFUSE_CFG', 'factory_mode', value) + cfg.write(file, 'w') + + +def check_pt_file(file, addr): + if len(file) > 0: + i = 0 + L = [] + while i < len(file): + L.append([convert_path(file[i]), int(addr[i], 16)]) + i += 1 + + L.sort(key=take_second) + i = 0 + try: + while i < len(L) - 1: + address = L[i][1] + address_next = L[i + 1][1] + file_size = os.path.getsize(os.path.join(app_path, L[i][0])) + if address_next < address + file_size: + bflb_utils.printf('pt check fail, %s is overlayed with %s in flash layout, please check your partition table to fix this issue' % ( + L[i][0], L[i + 1][0])) + return False + else: + i += 1 + + except Exception as e: + try: + bflb_utils.printf(e) + return False + finally: + e = None + del e + + return True + + +def compress_dir(chipname, zippath, efuse_load=False, address=None, flash_file=None, efuse_file=None, efuse_mask_file=None): + zip_file = os.path.join(chip_path, chipname, zippath, 'whole_img.pack') + dir_path = os.path.join(chip_path, chipname, chipname) + cfg_file = os.path.join(chip_path, chipname, 'eflash_loader/eflash_loader_cfg.ini') + cfg = BFConfigParser() + cfg.read(cfg_file) + if not address: + address = [] + if not flash_file: + flash_file = [] + if check_pt_file(flash_file, address) is not True: + bflb_utils.printf('PT Check Fail') + set_error_code('0082') + return False + flash_file.append(os.path.join(chip_path, chipname, 'eflash_loader/eflash_loader_cfg.ini')) + if efuse_load: + if efuse_file: + flash_file.append(efuse_file) + if efuse_mask_file: + flash_file.append(efuse_mask_file) + if len(flash_file) > 0: + i = 0 + try: + while i < len(flash_file): + if chip_path in flash_file[i]: + relpath = os.path.relpath(os.path.join(app_path, convert_path(flash_file[i])), chip_path) + dir = os.path.join(chip_path, chipname, relpath) + if os.path.isdir(os.path.dirname(dir)) is False: + os.makedirs(os.path.dirname(dir)) + shutil.copyfile(os.path.join(app_path, convert_path(flash_file[i])), dir) + else: + relpath = os.path.relpath(os.path.join(chipname, 'img_create', os.path.basename(flash_file[i]))) + dir = os.path.join(chip_path, chipname, relpath) + if os.path.isdir(os.path.dirname(dir)) is False: + os.makedirs(os.path.dirname(dir)) + shutil.copyfile(flash_file[i], dir) + i += 1 + + verfile = os.path.join(chip_path, chipname, chipname, 'version.txt') + with open(verfile, mode='w') as f: + f.write(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())) + except Exception as e: + try: + bflb_utils.printf(e) + return False + finally: + e = None + del e + + try: + z = zipfile.ZipFile(zip_file, 'w') + for dirpath, dirnames, filenames in os.walk(dir_path): + for file in filenames: + z.write(os.path.join(dirpath, file), os.path.relpath(os.path.join(dirpath, file), os.path.join(chip_path, chipname))) + + z.close() + shutil.rmtree(dir_path) + except Exception as e: + try: + bflb_utils.printf(e) + return False + finally: + e = None + del e + + return True + + +def img_create(args, chipname='bl60x', chiptype='bl60x', img_dir=None, config_file=None): + sub_module = __import__(('libs.' + chiptype), fromlist=[chiptype]) + img_dir_path = os.path.join(chip_path, chipname, 'img_create') + if img_dir is None: + sub_module.img_create_do.img_create_do(args, img_dir_path, config_file) + else: + sub_module.img_create_do.img_create_do(args, img_dir, config_file) + + +def create_sp_media_image_file(config, chiptype='bl60x', cpu_type=None): + sub_module = __import__(('libs.' + chiptype), fromlist=[chiptype]) + sub_module.img_create_do.create_sp_media_image(config, cpu_type) + + +def encrypt_loader_bin(chiptype, file, sign, encrypt, encrypt_key, encrypt_iv, publickey_file, privatekey_file): + sub_module = __import__(('libs.base.' + chiptype), fromlist=[chiptype]) + return sub_module.img_create_do.encrypt_loader_bin_do(file, sign, encrypt, encrypt_key, encrypt_iv, publickey_file, privatekey_file) + + +def run(): + parser_image = bflb_utils.image_create_parser_init() + args = parser_image.parse_args() + bflb_utils.printf('Chipname: %s' % args.chipname) + if args.chipname: + chip_dict = { 'bl56x': 'bl60x', + 'bl60x': 'bl60x', + 'bl562': 'bl602', + 'bl602': 'bl602', + 'bl702': 'bl702', + 'bl702l': 'bl702l', + 'bl808': 'bl808', + 'bl606p': 'bl808', + 'bl616': 'bl616', + 'wb03': 'wb03'} + chipname = args.chipname + chiptype = chip_dict[chipname] + img_create_path = os.path.join(chip_path, chipname, 'img_create_mcu') + img_create_cfg = os.path.join(chip_path, chipname, 'img_create_mcu') + '/img_create_cfg.ini' + bh_cfg_file = img_create_path + '/efuse_bootheader_cfg.ini' + bh_file = img_create_path + '/bootheader.bin' + if args.imgfile: + imgbin = args.imgfile + cfg = BFConfigParser() + cfg.read(img_create_cfg) + cfg.set('Img_Cfg', 'segdata_file', imgbin) + cfg.write(img_create_cfg, 'w') + bflb_efuse_boothd_create.bootheader_create_process(chipname, chiptype, bh_cfg_file, bh_file, img_create_path + '/bootheader_dummy.bin') + img_create(args, chipname, chiptype, img_create_path, img_create_cfg) + else: + bflb_utils.printf('Please set chipname config, exit') + + +if __name__ == '__main__': + run() +# okay decompiling ./libs/base/bflb_img_create.pyc diff --git a/libs/base/bflb_img_loader.py b/libs/base/bflb_img_loader.py new file mode 100644 index 0000000..cdde7d4 --- /dev/null +++ b/libs/base/bflb_img_loader.py @@ -0,0 +1,787 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/bflb_img_loader.py +import os, sys, time, hashlib, binascii, traceback, threading +from Crypto.Cipher import AES +from libs import bflb_utils +from libs.base import bflb_img_create +from libs.base import bflb_serial +import config as gol +from libs.bflb_utils import app_path + +class BflbImgLoader(object): + + def __init__(self, device, speed, boot_speed, interface='uart', chip_type='bl602', chip_name='bl602', eflash_loader_file1='', eflash_loader_file2='', callback=None, do_reset=False, reset_hold_time=100, shake_hand_delay=100, reset_revert=True, cutoff_time=0, shake_hand_retry=2, isp_mode_sign=False, isp_timeout=0, encrypt_key=None, encrypt_iv=None, public_key=None, private_key=None): + self._device = device + self._speed = speed + self._interface = interface.lower() + self._chip_type = chip_type + self._chip_name = chip_name + self._eflash_loader_file1 = eflash_loader_file1 + self._eflash_loader_file2 = eflash_loader_file2 + self._callback = callback + self._do_reset = do_reset + self._reset_hold_time = reset_hold_time + self._shake_hand_delay = shake_hand_delay + self._reset_revert = reset_revert + self._cutoff_time = cutoff_time + self._shake_hand_retry = shake_hand_retry + self._isp_mode_sign = isp_mode_sign + self._isp_timeout = isp_timeout + self._boot_speed = boot_speed + self.encrypt_key = encrypt_key + self.encrypt_iv = encrypt_iv + self.public_key = public_key + self.private_key = private_key + self._boot_load = True + self._record_bootinfo = None + self.bflb_serial_object = None + self._imge_fp = None + self._segcnt = 0 + self._602a0_dln_fix = False + self.isp_baudrate = 2000000 + if interface == 'uart': + self.bflb_serial_object = bflb_serial.BLSerialUart(rts_state=True, dtr_state=True) + self._bootrom_cmds = {'get_chip_id':{'cmd_id':'05', + 'data_len':'0000', + 'callback':None}, + 'get_boot_info':{'cmd_id':'10', + 'data_len':'0000', + 'callback':None}, + 'load_boot_header':{'cmd_id':'11', + 'data_len':'00b0', + 'callback':None}, + '808_load_boot_header':{'cmd_id':'11', + 'data_len':'0160', + 'callback':None}, + '628_load_boot_header':{'cmd_id':'11', + 'data_len':'0100', + 'callback':None}, + '616_load_boot_header':{'cmd_id':'11', + 'data_len':'0100', + 'callback':None}, + '702l_load_boot_header':{'cmd_id':'11', + 'data_len':'00F0', + 'callback':None}, + 'load_publick_key':{'cmd_id':'12', + 'data_len':'0044', + 'callback':None}, + 'load_publick_key2':{'cmd_id':'13', + 'data_len':'0044', + 'callback':None}, + 'load_signature':{'cmd_id':'14', + 'data_len':'0004', + 'callback':None}, + 'load_signature2':{'cmd_id':'15', + 'data_len':'0004', + 'callback':None}, + 'load_aes_iv':{'cmd_id':'16', + 'data_len':'0014', + 'callback':None}, + 'load_seg_header':{'cmd_id':'17', + 'data_len':'0010', + 'callback':None}, + 'load_seg_data':{'cmd_id':'18', + 'data_len':'0100', + 'callback':None}, + 'check_image':{'cmd_id':'19', + 'data_len':'0000', + 'callback':None}, + 'run_image':{'cmd_id':'1a', + 'data_len':'0000', + 'callback':None}, + 'change_rate':{'cmd_id':'20', + 'data_len':'0008', + 'callback':None}, + 'reset':{'cmd_id':'21', + 'data_len':'0000', + 'callback':None}, + 'flash_erase':{'cmd_id':'30', + 'data_len':'0000', + 'callback':None}, + 'flash_write':{'cmd_id':'31', + 'data_len':'0100', + 'callback':None}, + 'flash_read':{'cmd_id':'32', + 'data_len':'0100', + 'callback':None}, + 'flash_boot':{'cmd_id':'33', + 'data_len':'0000', + 'callback':None}, + 'efuse_write':{'cmd_id':'40', + 'data_len':'0080', + 'callback':None}, + 'efuse_read':{'cmd_id':'41', + 'data_len':'0000', + 'callback':None}} + + def close_port(self): + if self.bflb_serial_object is not None: + self.bflb_serial_object.close() + + def boot_process_load_cmd(self, section, read_len): + read_data = bytearray(0) + if read_len != 0: + read_data = bytearray(self._imge_fp.read(read_len)) + if len(read_data) != read_len: + bflb_utils.printf('read error,expected len=', read_len, 'read len=', len(read_data)) + return bytearray(0) + if section == 'load_boot_header': + tmp = bflb_utils.bytearray_reverse(read_data[120:124]) + self._segcnt = bflb_utils.bytearray_to_int(tmp) + bflb_utils.printf('segcnt is ', self._segcnt) + else: + if section == '808_load_boot_header': + tmp = bflb_utils.bytearray_reverse(read_data[140:144]) + self._segcnt = bflb_utils.bytearray_to_int(tmp) + bflb_utils.printf('segcnt is ', self._segcnt) + else: + if section == '628_load_boot_header': + tmp = bflb_utils.bytearray_reverse(read_data[136:140]) + self._segcnt = bflb_utils.bytearray_to_int(tmp) + bflb_utils.printf('segcnt is ', self._segcnt) + else: + if section == '616_load_boot_header': + tmp = bflb_utils.bytearray_reverse(read_data[132:136]) + self._segcnt = bflb_utils.bytearray_to_int(tmp) + bflb_utils.printf('segcnt is ', self._segcnt) + else: + if section == '702l_load_boot_header': + tmp = bflb_utils.bytearray_reverse(read_data[120:124]) + self._segcnt = bflb_utils.bytearray_to_int(tmp) + bflb_utils.printf('segcnt is ', self._segcnt) + if section == 'load_signature' or section == 'load_signature2': + tmp = bflb_utils.bytearray_reverse(read_data[0:4]) + sig_len = bflb_utils.bytearray_to_int(tmp) + read_data = read_data + bytearray(self._imge_fp.read(sig_len + 4)) + if len(read_data) != sig_len + 8: + bflb_utils.printf('read signature error,expected len=', sig_len + 4, 'read len=', len(read_data)) + return read_data + + def boot_process_one_cmd(self, section, cmd_id, cmd_len): + read_len = bflb_utils.bytearray_to_int(cmd_len) + read_data = self._bootrom_cmds.get(section)['callback'](section, read_len) + tmp = bytearray(2) + tmp[0] = cmd_len[1] + tmp[1] = cmd_len[0] + data_read = bytearray(0) + tmp = bflb_utils.int_to_2bytearray_l(len(read_data)) + data = cmd_id + bytearray(1) + tmp + read_data + if self._chip_type == 'bl702': + if section == 'run_image': + sub_module = __import__(('libs.base.' + self._chip_type), fromlist=[self._chip_type]) + data = sub_module.chiptype_patch.img_load_create_predata_before_run_img() + self.bflb_serial_object.write(data) + if section == 'get_boot_info' or section == 'load_seg_header' or section == 'get_chip_id': + res, data_read = self.bflb_serial_object.deal_response() + else: + res = self.bflb_serial_object.deal_ack() + if res.startswith('OK') is True: + pass + else: + try: + bflb_utils.printf('result: ', res) + except IOError: + bflb_utils.printf('python IO error') + + return (res, data_read) + + def boot_process_one_section(self, section, data_len): + cmd_id = bflb_utils.hexstr_to_bytearray(self._bootrom_cmds.get(section)['cmd_id']) + if data_len == 0: + length = bflb_utils.hexstr_to_bytearray(self._bootrom_cmds.get(section)['data_len']) + else: + length = bflb_utils.int_to_2bytearray_b(data_len) + return self.boot_process_one_cmd(section, cmd_id, length) + + def boot_inf_change_rate(self, comnum, section, newrate): + cmd_id = bflb_utils.hexstr_to_bytearray(self._bootrom_cmds.get(section)['cmd_id']) + cmd_len = bflb_utils.hexstr_to_bytearray(self._bootrom_cmds.get(section)['data_len']) + bflb_utils.printf('process', section, ',cmd=', binascii.hexlify(cmd_id), ',data len=', binascii.hexlify(cmd_len)) + baudrate = self.bflb_serial_object.if_get_rate() + oldv = bflb_utils.int_to_4bytearray_l(baudrate) + newv = bflb_utils.int_to_4bytearray_l(newrate) + tmp = bytearray(3) + tmp[1] = cmd_len[1] + tmp[2] = cmd_len[0] + data = cmd_id + tmp + oldv + newv + self.bflb_serial_object.if_write(data) + bflb_utils.printf() + stime = 110 / float(baudrate) * 2 + if stime < 0.003: + stime = 0.003 + time.sleep(stime) + self.bflb_serial_object.if_close() + self.bflb_serial_object.if_init(comnum, newrate, self._chip_type, self._chip_name) + return self.bflb_serial_object.if_deal_ack(dmy_data=False) + + def boot_install_cmds_callback(self): + self._bootrom_cmds.get('get_chip_id')['callback'] = self.boot_process_load_cmd + self._bootrom_cmds.get('get_boot_info')['callback'] = self.boot_process_load_cmd + self._bootrom_cmds.get('load_boot_header')['callback'] = self.boot_process_load_cmd + self._bootrom_cmds.get('808_load_boot_header')['callback'] = self.boot_process_load_cmd + self._bootrom_cmds.get('628_load_boot_header')['callback'] = self.boot_process_load_cmd + self._bootrom_cmds.get('616_load_boot_header')['callback'] = self.boot_process_load_cmd + self._bootrom_cmds.get('702l_load_boot_header')['callback'] = self.boot_process_load_cmd + self._bootrom_cmds.get('load_publick_key')['callback'] = self.boot_process_load_cmd + self._bootrom_cmds.get('load_publick_key2')['callback'] = self.boot_process_load_cmd + self._bootrom_cmds.get('load_signature')['callback'] = self.boot_process_load_cmd + self._bootrom_cmds.get('load_signature2')['callback'] = self.boot_process_load_cmd + self._bootrom_cmds.get('load_aes_iv')['callback'] = self.boot_process_load_cmd + self._bootrom_cmds.get('load_seg_header')['callback'] = self.boot_process_load_cmd + self._bootrom_cmds.get('load_seg_data')['callback'] = self.boot_process_load_cmd + self._bootrom_cmds.get('check_image')['callback'] = self.boot_process_load_cmd + self._bootrom_cmds.get('run_image')['callback'] = self.boot_process_load_cmd + self._bootrom_cmds.get('reset')['callback'] = self.boot_process_load_cmd + + def issue_log_print(self): + bflb_utils.printf('########################################################################') + bflb_utils.printf('请按照以下描述排查问题:') + if self._chip_type == 'bl60x': + bflb_utils.printf('GPIO24是否上拉到板子自身的3.3V,而不是外部的3.3V') + bflb_utils.printf('GPIO7(RX)是否连接到USB转串口的TX引脚') + bflb_utils.printf('GPIO14(TX)是否连接到USB转串口的RX引脚') + bflb_utils.printf('在使用烧录软件进行烧录前,是否在GPIO24拉高的情况下,使用Reset/Chip_En复位了芯片') + else: + if self._chip_type == 'bl602': + bflb_utils.printf('GPIO8是否上拉到板子自身的3.3V,而不是外部的3.3V') + bflb_utils.printf('GPIO7(RX)是否连接到USB转串口的TX引脚') + bflb_utils.printf('GPIO16(TX)是否连接到USB转串口的RX引脚') + bflb_utils.printf('在使用烧录软件进行烧录前,是否在GPIO8拉高的情况下,使用Reset/Chip_En复位了芯片') + else: + if self._chip_type == 'bl702': + bflb_utils.printf('GPIO28是否上拉到板子自身的3.3V,而不是外部的3.3V') + bflb_utils.printf('GPIO15(RX)是否连接到USB转串口的TX引脚') + bflb_utils.printf('GPIO14(TX)是否连接到USB转串口的RX引脚') + bflb_utils.printf('在使用烧录软件进行烧录前,是否在GPIO28拉高的情况下,使用Reset/Chip_En复位了芯片') + else: + bflb_utils.printf('Boot pin是否上拉到板子自身的3.3V,而不是外部的3.3V') + bflb_utils.printf('UART RX是否连接到USB转串口的TX引脚') + bflb_utils.printf('UART TX是否连接到USB转串口的RX引脚') + bflb_utils.printf('在使用烧录软件进行烧录前,是否在Boot pin拉高的情况下,使用Reset/Chip_En复位了芯片') + bflb_utils.printf('烧录软件所选择的COM口,是否是连接芯片的串口') + bflb_utils.printf('烧录软件上选择的波特率是否是USB转串口支持的波特率') + bflb_utils.printf('3.3V供电是否正常') + bflb_utils.printf('板子供电电流是否正常(烧录模式下,芯片耗电电流5-7mA)') + bflb_utils.printf('########################################################################') + + def send_55_command(self, speed): + try: + while True: + if self._shakehand_flag is True: + break + if not self._chip_type == 'bl702' or self._chip_type == 'bl702l': + self.bflb_serial_object.write(self.get_sync_bytes(int(0.003 * speed / 10))) + else: + self.bflb_serial_object.write(self.get_sync_bytes(int(0.006 * speed / 10))) + + except Exception as e: + try: + bflb_utils.printf('Error: %s' % e) + finally: + e = None + del e + + def get_sync_bytes(self, length): + try: + data = bytearray(length) + i = 0 + while i < length: + data[i] = 85 + i += 1 + + return data + except Exception as e: + try: + bflb_utils.printf('Error: %s' % e) + finally: + e = None + del e + + def set_isp_baudrate(self, isp_baudrate): + bflb_utils.printf('isp mode speed: ', isp_baudrate) + self.isp_baudrate = isp_baudrate + + def toggle_boot_or_shake_hand(self, run_sign, do_reset=False, reset_hold_time=100, shake_hand_delay=100, reset_revert=True, cutoff_time=0, isp_mode_sign=False, isp_timeout=0, boot_load=False, shake_hand_retry=2): + """ + When run_sign is 2, it run shakehand. + """ + device = self._device + speed = self._speed + if run_sign == 2: + shake_hand_retry = shake_hand_retry + else: + if run_sign == 1: + shake_hand_retry = 1 + if self.bflb_serial_object: + try: + timeout = self.bflb_serial_object.get_timeout() + blusbserialwriteflag = False + if isp_mode_sign: + if isp_timeout > 0: + wait_timeout = isp_timeout + self.bflb_serial_object.set_timeout(0.1) + self._shakehand_flag = False + cutoff_time = 0 + do_reset = False + self.bflb_serial_object.repeat_init(device, self.isp_baudrate, self._chip_type, self._chip_name) + self.bflb_serial_object.write(b'\r\nispboot if\r\nreboot\r\n') + fl_thrx = None + fl_thrx = threading.Thread(target=(self.send_55_command), args=(speed,)) + fl_thrx.setDaemon(True) + fl_thrx.start() + bflb_utils.printf('Please Press Reset Key!') + self.bflb_serial_object.setRTS(1) + time.sleep(0.2) + self.bflb_serial_object.setRTS(0) + time_stamp = time.time() + while time.time() - time_stamp < wait_timeout: + if self._chip_type == 'bl602' or self._chip_type == 'bl702': + self.bflb_serial_object.set_timeout(0.01) + success, ack = self.bflb_serial_object.read(3000) + if ack.find(b'Boot2 ISP Shakehand Suss') != -1: + self._shakehand_flag = True + if ack.find(b'Boot2 ISP Ready') != -1: + bflb_utils.printf('isp ready') + self.bflb_serial_object.write(bytearray.fromhex('a0000000')) + self.bflb_serial_object.set_timeout(timeout) + return 'OK' + else: + success, ack = self.bflb_serial_object.read(3000) + if ack.find(b'Boot2 ISP Ready') != -1: + bflb_utils.printf('isp ready') + self._shakehand_flag = True + if self._shakehand_flag is True: + self.bflb_serial_object.set_timeout(timeout) + tmp_timeout = self.bflb_serial_object.get_timeout() + self.bflb_serial_object.set_timeout(0.1) + if self._chip_type == 'bl602' or self._chip_type == 'bl702': + self.bflb_serial_object.set_timeout(0.5) + success, ack = self.bflb_serial_object.read(15) + self.bflb_serial_object.set_timeout(0.005) + ack += self.bflb_serial_object.read(15)[1] + self.bflb_serial_object.set_timeout(tmp_timeout) + bflb_utils.printf('read ready') + if ack.find(b'Boot2 ISP Ready') == -1: + bflb_utils.printf('Boot2 isp is not ready') + return 'FL' + self.bflb_serial_object.write(bytearray.fromhex('a0000000')) + return 'OK' + else: + while 1: + ack = self.bflb_serial_object.raw_read() + if len(ack) == 0: + break + + time.sleep(0.1) + while True: + ack = self.bflb_serial_object.raw_read() + if len(ack) == 0: + break + + self.bflb_serial_object.set_timeout(tmp_timeout) + break + + self._shakehand_flag = True + self.bflb_serial_object.set_timeout(timeout) + self.bflb_serial_object.repeat_init(device, speed, self._chip_type, self._chip_name) + time.sleep(2.2) + if self.bflb_serial_object._is_bouffalo_chip(): + if boot_load: + blusbserialwriteflag = True + while shake_hand_retry > 0: + if cutoff_time != 0 and blusbserialwriteflag is not True: + cutoff_revert = False + if cutoff_time > 1000: + cutoff_revert = True + cutoff_time = cutoff_time - 1000 + self.bflb_serial_object.setRTS(1) + time.sleep(0.2) + self.bflb_serial_object.setRTS(0) + time.sleep(0.05) + self.bflb_serial_object.setRTS(1) + if cutoff_revert: + self.bflb_serial_object.setDTR(0) + else: + self.bflb_serial_object.setDTR(1) + bflb_utils.printf('tx rx and power off, press the machine!') + bflb_utils.printf('cutoff time is ', cutoff_time / 1000.0) + time.sleep(cutoff_time / 1000.0) + if cutoff_revert: + self.bflb_serial_object.setDTR(1) + else: + self.bflb_serial_object.setDTR(0) + bflb_utils.printf('power on tx and rx ') + time.sleep(0.1) + else: + if run_sign == 2: + self.bflb_serial_object.setDTR(0) + bflb_utils.printf('default set DTR high ') + time.sleep(0.1) + if do_reset is True: + if blusbserialwriteflag is not True: + self.bflb_serial_object.setRTS(0) + time.sleep(0.2) + if reset_revert: + self.bflb_serial_object.setRTS(1) + time.sleep(0.001) + reset_cnt = 2 + if reset_hold_time > 1000: + reset_cnt = int(reset_hold_time // 1000) + reset_hold_time = reset_hold_time % 1000 + while reset_cnt > 0: + if reset_revert: + self.bflb_serial_object.setRTS(0) + else: + self.bflb_serial_object.setRTS(1) + time.sleep(reset_hold_time / 1000.0) + if reset_revert: + self.bflb_serial_object.setRTS(1) + else: + self.bflb_serial_object.setRTS(0) + if shake_hand_delay > 0: + time.sleep(shake_hand_delay / 1000.0) + else: + time.sleep(0.005) + if reset_revert: + self.bflb_serial_object.setRTS(0) + else: + self.bflb_serial_object.setRTS(1) + time.sleep(reset_hold_time / 1000.0) + if reset_revert: + self.bflb_serial_object.setRTS(1) + else: + self.bflb_serial_object.setRTS(0) + if shake_hand_delay > 0: + time.sleep(shake_hand_delay / 1000.0) + else: + time.sleep(0.005) + reset_cnt -= 1 + + bflb_utils.printf('reset cnt: ' + str(reset_cnt) + ', reset hold: ' + str(reset_hold_time / 1000.0) + ', shake hand delay: ' + str(shake_hand_delay / 1000.0)) + if blusbserialwriteflag: + self.bflb_serial_object.bl_usb_serial_write(cutoff_time, reset_revert) + else: + bflb_utils.printf('clean buf') + self.bflb_serial_object.set_timeout(0.1) + self.bflb_serial_object.clear_buf() + if run_sign == 1: + self.bflb_serial_object.set_timeout(timeout) + return 'OK' + if self._602a0_dln_fix: + self.bflb_serial_object.set_timeout(0.5) + else: + self.bflb_serial_object.set_timeout(0.1) + bflb_utils.printf('send sync') + if self._chip_type == 'bl702' or self._chip_type == 'bl702l': + self.bflb_serial_object.write(self.get_sync_bytes(int(0.003 * speed / 10))) + else: + self.bflb_serial_object.write(self.get_sync_bytes(int(0.006 * speed / 10))) + if self._chip_type == 'bl808': + time.sleep(0.3) + self.bflb_serial_object.write(bflb_utils.hexstr_to_bytearray('5000080038F0002000000018')) + if self._602a0_dln_fix: + time.sleep(4) + success, ack = self.bflb_serial_object.read(1000) + bflb_utils.printf('ack is ', binascii.hexlify(ack)) + if ack.find(b'O') != -1 or ack.find(b'K') != -1: + self.bflb_serial_object.set_timeout(timeout) + if self._602a0_dln_fix: + self.bflb_serial_object.write(bytearray(2)) + time.sleep(0.03) + return 'OK' + if len(ack) != 0: + bflb_utils.printf('reshake') + if do_reset is False: + bflb_utils.printf('sleep') + time.sleep(3) + else: + bflb_utils.printf('retry') + shake_hand_retry -= 1 + + self.bflb_serial_object.set_timeout(timeout) + return 'FL' + except Exception as e: + try: + bflb_utils.printf('Error: %s' % e) + finally: + e = None + del e + + else: + return 'FL' + + def img_load_shake_hand(self, sh_baudrate, wk_baudrate, do_reset=False, reset_hold_time=100, shake_hand_delay=100, reset_revert=True, cutoff_time=0, shake_hand_retry=2, isp_mode_sign=False, isp_timeout=0, boot_load=True): + self.bflb_serial_object.repeat_init(self._device, sh_baudrate, self._chip_type, self._chip_name) + self.boot_install_cmds_callback() + if self._chip_type == 'wb03': + self.toggle_boot_or_shake_hand(1, do_reset, reset_hold_time, shake_hand_delay, reset_revert, cutoff_time, isp_mode_sign, isp_timeout, boot_load) + bflb_utils.printf('get_chip_id') + ret, data_read = self.boot_process_one_section('get_chip_id', 0) + if ret.startswith('OK') is False: + bflb_utils.printf('fail') + return ( + ret, None) + data_read = binascii.hexlify(data_read) + bflb_utils.printf('data read is ', data_read) + chip_id = data_read.decode('utf-8') + if chip_id != '43484950574230334130305f424c0000': + if chip_id != '43484950574230334130305F424C0000': + return 'shake hand fail' + else: + if self._chip_type == 'bl602': + self._602a0_dln_fix = False + ret = self.toggle_boot_or_shake_hand(2, do_reset, reset_hold_time, shake_hand_delay, reset_revert, cutoff_time, isp_mode_sign, isp_timeout, boot_load, shake_hand_retry) + if self._chip_type == 'bl602': + self._602a0_dln_fix = False + if ret != 'OK': + bflb_utils.printf('shake hand fail') + self.issue_log_print() + bflb_utils.set_error_code('0050') + return 'shake hand fail' + if sh_baudrate != wk_baudrate: + if self.boot_inf_change_rate(self._device, 'change_rate', wk_baudrate) != 'OK': + bflb_utils.printf('change rate fail') + return 'change rate fail' + bflb_utils.printf('shake hand success') + return ret + + def img_load_main_process(self, file, group, record_bootinfo=None): + encrypt_blk_size = 16 + bflb_utils.printf('get_boot_info') + ret, data_read = self.boot_process_one_section('get_boot_info', 0) + if ret.startswith('OK') is False: + bflb_utils.printf('fail') + return ( + ret, None) + data_read = binascii.hexlify(data_read) + bflb_utils.printf('data read is ', data_read) + bootinfo = data_read.decode('utf-8') + chipid = '' + if self._chip_type == 'bl702' or self._chip_type == 'bl702l': + chipid = bootinfo[32:34] + bootinfo[34:36] + bootinfo[36:38] + bootinfo[38:40] + bootinfo[40:42] + bootinfo[42:44] + bootinfo[44:46] + bootinfo[46:48] + else: + chipid = bootinfo[34:36] + bootinfo[32:34] + bootinfo[30:32] + bootinfo[28:30] + bootinfo[26:28] + bootinfo[24:26] + bflb_utils.printf('========= ChipID: ', chipid, ' =========') + bflb_utils.printf('last boot info: ', record_bootinfo) + if record_bootinfo != None: + if bootinfo[8:] == record_bootinfo[8:]: + bflb_utils.printf('repeated chip') + return ( + 'repeat_burn', bootinfo) + if bootinfo[:8] == 'FFFFFFFF' or bootinfo[:8] == 'ffffffff': + bflb_utils.printf('eflash loader present') + return ( + 'error_shakehand', bootinfo) + sign = 0 + encrypt = 0 + if self._chip_type == 'bl60x': + sign = int(data_read[8:10], 16) & 3 + encrypt = (int(data_read[8:10], 16) & 12) >> 2 + else: + if self._chip_type == 'bl602' or self._chip_type == 'bl702' or self._chip_type == 'bl702l': + sign = int(data_read[8:10], 16) + encrypt = int(data_read[10:12], 16) + else: + if self._chip_type == 'bl808' or self._chip_type == 'bl628': + if group == 0: + sign = int(data_read[8:10], 16) + encrypt = int(data_read[12:14], 16) + else: + sign = int(data_read[10:12], 16) + encrypt = int(data_read[14:16], 16) + else: + sign = int(data_read[8:10], 16) + encrypt = int(data_read[10:12], 16) + bflb_utils.printf('sign is ', sign, ' encrypt is ', encrypt) + if encrypt == 1 or sign == 1: + if encrypt == 1 and self.encrypt_key != None and self.encrypt_iv != None and sign == 1 and self.encrypt_key != None and self.private_key != None: + ret, encrypted_data = bflb_img_create.encrypt_loader_bin(self._chip_type, file, sign, encrypt, self.encrypt_key, self.encrypt_iv, self.public_key, self.private_key) + else: + if encrypt == 1and self.encrypt_key != None and self.encrypt_key != None and sign == 0: + ret, encrypted_data = bflb_img_create.encrypt_loader_bin(self._chip_type, file, sign, encrypt, self.encrypt_key, self.encrypt_iv, self.public_key, self.private_key) + else: + if encrypt == 0and sign == 1 and sign == 1 and self.private_key != None: + ret, encrypted_data = bflb_img_create.encrypt_loader_bin(self._chip_type, file, sign, encrypt, self.encrypt_key, self.encrypt_iv, self.public_key, self.private_key) + else: + if encrypt == 1 and sign == 1: + bflb_utils.printf('Error: Aes-encrypt and ecc-signature is None!') + else: + if encrypt == 1 and sign == 0: + bflb_utils.printf('Error: Aes-encrypt is None!') + else: + if encrypt == 0: + if sign == 1: + bflb_utils.printf('Error: Ecc-signature is None!') + return ( + '', bootinfo) + if ret == True: + filename, ext = os.path.splitext(file) + file_encrypt = filename + '_encrypt' + ext + fp = open(file_encrypt, 'wb') + fp.write(encrypted_data) + fp.close() + self._imge_fp = open(file_encrypt, 'rb') + else: + file = os.path.join(bflb_utils.app_path, file) + self._imge_fp = open(file, 'rb') + else: + file = os.path.join(bflb_utils.app_path, file) + self._imge_fp = open(file, 'rb') + if self._chip_type == 'wb03': + self._imge_fp.read(208) + if self._chip_type == 'bl808': + ret, dmy = self.boot_process_one_section('808_load_boot_header', 0) + else: + if self._chip_type == 'bl628': + ret, dmy = self.boot_process_one_section('628_load_boot_header', 0) + else: + if self._chip_type == 'bl616' or self._chip_type == 'wb03': + ret, dmy = self.boot_process_one_section('616_load_boot_header', 0) + else: + if self._chip_type == 'bl702l': + ret, dmy = self.boot_process_one_section('702l_load_boot_header', 0) + else: + ret, dmy = self.boot_process_one_section('load_boot_header', 0) + if ret.startswith('OK') is False: + return (ret, bootinfo) + if sign != 0: + ret, dmy = self.boot_process_one_section('load_publick_key', 0) + if ret.startswith('OK') is False: + return (ret, bootinfo) + if self._chip_type == 'bl60x' or self._chip_type == 'bl808' or self._chip_type == 'bl628': + ret, dmy = self.boot_process_one_section('load_publick_key2', 0) + if ret.startswith('OK') is False: + return (ret, bootinfo) + ret, dmy = self.boot_process_one_section('load_signature', 0) + if ret.startswith('OK') is False: + return (ret, bootinfo) + if self._chip_type == 'bl60x' or self._chip_type == 'bl808' or self._chip_type == 'bl628': + ret, dmy = self.boot_process_one_section('load_signature2', 0) + if ret.startswith('OK') is False: + return (ret, bootinfo) + if encrypt != 0: + ret, dmy = self.boot_process_one_section('load_aes_iv', 0) + if ret.startswith('OK') is False: + return (ret, bootinfo) + segs = 0 + while segs < self._segcnt: + send_len = 0 + segdata_len = 0 + ret, data_read = self.boot_process_one_section('load_seg_header', 0) + if ret.startswith('OK') is False: + return (ret, bootinfo) + else: + tmp = bflb_utils.bytearray_reverse(data_read[4:8]) + segdata_len = bflb_utils.bytearray_to_int(tmp) + bflb_utils.printf('segdata_len is ', segdata_len) + if encrypt == 1: + if segdata_len % encrypt_blk_size != 0: + segdata_len = segdata_len + encrypt_blk_size - segdata_len % encrypt_blk_size + while send_len < segdata_len: + left = segdata_len - send_len + if left > 4080: + left = 4080 + ret, dmy = self.boot_process_one_section('load_seg_data', left) + if ret.startswith('OK') is False: + return (ret, bootinfo) + send_len = send_len + left + bflb_utils.printf(send_len, '/', segdata_len) + if self._callback is not None: + self._callback(send_len, segdata_len, sys._getframe().f_code.co_name) + + segs = segs + 1 + + ret, dmy = self.boot_process_one_section('check_image', 0) + return ( + ret, bootinfo) + + def img_get_bootinfo(self, sh_baudrate, wk_baudrate, callback=None, do_reset=False, reset_hold_time=100, shake_hand_delay=100, reset_revert=True, cutoff_time=0, shake_hand_retry=2, isp_mode_sign=False, isp_timeout=0, boot_load=True): + bflb_utils.printf('========= image get bootinfo =========') + ret = self.img_load_shake_hand(sh_baudrate, wk_baudrate, do_reset, reset_hold_time, shake_hand_delay, reset_revert, cutoff_time, shake_hand_retry, isp_mode_sign, isp_timeout, boot_load) + if ret == 'shake hand fail' or ret == 'change rate fail': + bflb_utils.printf('shake hand fail') + self.bflb_serial_object.close() + return (False, b'') + time.sleep(0.5) + ret, data_read = self.boot_process_one_section('get_boot_info', 0) + if ret.startswith('OK') is False: + bflb_utils.printf('get_boot_info no ok') + return ( + ret, b'') + data_read = binascii.hexlify(data_read) + bflb_utils.printf('data read is ', data_read) + return ( + True, data_read) + + def img_loader_reset_cpu(self): + bflb_utils.printf('========= reset cpu =========') + ret, data_read = self.boot_process_one_section('reset', 0) + if ret.startswith('OK') is False: + bflb_utils.printf('reset cpu fail') + return False + return True + + def img_load_process(self, sh_baudrate, wk_baudrate, callback=None, do_reset=False, reset_hold_time=100, shake_hand_delay=100, reset_revert=True, cutoff_time=0, shake_hand_retry=2, isp_mode_sign=False, isp_timeout=0, boot_load=True, record_bootinfo=None): + bflb_utils.printf('========= image load =========') + success = True + bootinfo = None + try: + ret = self.img_load_shake_hand(sh_baudrate, wk_baudrate, do_reset, reset_hold_time, shake_hand_delay, reset_revert, cutoff_time, shake_hand_retry, isp_mode_sign, isp_timeout, boot_load) + if ret == 'shake hand fail' or ret == 'change rate fail': + bflb_utils.printf('shake hand fail') + self.bflb_serial_object.close() + return ( + False, bootinfo, ret) + time.sleep(0.01) + if self._eflash_loader_file1 is not None: + if self._eflash_loader_file1 != '': + res, bootinfo = self.img_load_main_process(self._eflash_loader_file1, 0, record_bootinfo) + if res.startswith('OK') is False: + if res.startswith('repeat_burn') is True: + return (False, bootinfo, res) + bflb_utils.printf('Img load fail') + if res.startswith('error_shakehand') is True: + bflb_utils.printf('shakehand with eflash loader found') + return (False, bootinfo, res) + if self._eflash_loader_file2 is not None: + if self._eflash_loader_file2 != '': + res, bootinfo = self.img_load_main_process(self._eflash_loader_file2, 1, record_bootinfo) + if res.startswith('OK') is False: + if res.startswith('repeat_burn') is True: + return (False, bootinfo, res) + bflb_utils.printf('Img load fail') + if res.startswith('error_shakehand') is True: + bflb_utils.printf('shakehand with eflash loader found') + return (False, bootinfo, res) + bflb_utils.printf('Run img') + self._imge_fp.close() + res, dmy = self.boot_process_one_section('run_image', 0) + if res.startswith('OK') is False: + bflb_utils.printf('Img run fail') + success = False + time.sleep(0.1) + except Exception as e: + try: + bflb_utils.printf(e) + traceback.print_exc(limit=5, file=(sys.stdout)) + return ( + False, bootinfo, '') + finally: + e = None + del e + + return ( + success, bootinfo, '') + + +if __name__ == '__main__': + img_load_t = BflbImgLoader() + if len(sys.argv) == 3: + img_load_t.img_load_process(sys.argv[1], 115200, 115200, sys.argv[2], '') + else: + if len(sys.argv) == 4: + img_load_t.img_load_process(sys.argv[1], 115200, 115200, sys.argv[2], sys.argv[3]) +# okay decompiling ./libs/base/bflb_img_loader.pyc diff --git a/libs/base/bflb_serial.py b/libs/base/bflb_serial.py new file mode 100644 index 0000000..8840b95 --- /dev/null +++ b/libs/base/bflb_serial.py @@ -0,0 +1,714 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/bflb_serial.py +__doc__ = '\nCreated on 20220830\n\n@author: Dillon\n' +import re, os, sys, time, serial, struct, pylink, cklink, subprocess +from glob import glob +from libs.bflb_utils import * +from serial.tools.list_ports import comports +import config as gol + +class BLSerialUart(object): + __doc__ = '\n Bouffalolab serial package\n ' + + def __init__(self, rts_state=False, dtr_state=False): + self._device = 'COM1' + self._baudrate = 115200 + self._isp_baudrate = 2000000 + self._ser = None + self._shakehand_flag = False + self._chiptype = 'bl602' + self.rts_state = rts_state + self.dtr_state = dtr_state + + def repeat_init(self, device, rate=0, _chip_type='bl602', _chip_name='bl602'): + try: + if not rate: + rate = self._isp_baudrate + if self._ser is None: + self._baudrate = rate + if ' (' in device: + dev = device[:device.find(' (')] + else: + dev = device + self._device = dev.upper() + for i in range(3): + try: + self._ser = serial.Serial(dev, rate, timeout=2.0, xonxoff=False, rtscts=False, write_timeout=None, dsrdtr=False) + except Exception as error: + try: + printf(error) + time.sleep(1) + finally: + error = None + del error + + else: + break + + else: + self._ser.baudrate = rate + self._baudrate = rate + self._602a0_dln_fix = False + self._chiptype = _chip_type + self._chipname = _chip_name + except Exception as e: + try: + printf('Error: %s' % e) + finally: + e = None + del e + + def write(self, message): + if self._ser: + self._ser.write(message) + + def read(self, length=1): + try: + data = bytearray(0) + received = 0 + while received < length: + tmp = self._ser.read(length - received) + if len(tmp) == 0: + break + else: + data += tmp + received += len(tmp) + + if len(data) != length: + return (0, data) + return (1, data) + except Exception as e: + try: + printf('Error: %s' % e) + finally: + e = None + del e + + def raw_read(self): + return self._ser.read(self._ser.in_waiting or 1) + + def clear_buf(self): + if self._ser: + self._ser.read_all() + + def close(self): + if self._ser: + self._ser.close() + + def _is_bouffalo_chip(self): + bl_sign = False + if sys.platform.startswith('win'): + for port, data, info in comports(): + if not port: + continue + if self._device.upper() == port.upper(): + if not 'VID:PID=42BF:B210' in info.upper(): + if 'VID:PID=FFFF:FFFF' in info.upper(): + pass + bl_sign = True + break + + else: + if sys.platform.startswith('linux') or sys.platform.startswith('darwin'): + ports = [] + for port, data, info in comports(): + if not port: + continue + if self._device.upper() == port.upper(): + if not 'PID=FFFF' in info.upper(): + if 'PID=42BF:B210' in info.upper(): + pass + bl_sign = True + break + + return bl_sign + + def bl_usb_serial_write(self, cutoff_time, reset_revert): + try: + boot_revert = 0 + printf('usb serial port') + if cutoff_time != 0: + boot_revert = 0 + if cutoff_time > 1000: + boot_revert = 1 + data = bytearray() + specialstr = string_to_bytearray('BOUFFALOLAB5555RESET') + for b in specialstr: + data.append(b) + + data.append(boot_revert) + data.append(reset_revert) + self._ser.write(data) + time.sleep(0.05) + except Exception as e: + try: + printf('Error: %s' % e) + finally: + e = None + del e + + def set_dtr(self, dtr): + """ + dtr: If dtr is 1, it shows high. If dtr is 0, it shows low. + """ + try: + if sys.platform.startswith('darwin'): + self._ser.write(b'BOUFFALOLAB5555DTR' + str(dtr).encode()) + self.clear_buf() + if dtr == 1: + self._ser.setDTR(0) + else: + if dtr == 0: + self._ser.setDTR(1) + else: + bl_sign = self._is_bouffalo_chip() + if bl_sign: + self._ser.write(b'BOUFFALOLAB5555DTR' + str(dtr).encode()) + else: + if dtr == 1: + self._ser.setDTR(0) + else: + if dtr == 0: + self._ser.setDTR(1) + except: + pass + + def setDTR(self, dtr): + self._ser.setDTR(dtr) + + def set_rts(self, rts): + """ + rts: If rts is 1, it shows high. If rts is 0, it shows low. + """ + try: + if sys.platform.startswith('darwin'): + self._ser.write(b'BOUFFALOLAB5555RTS' + str(rts).encode()) + self.clear_buf() + if rts == 1: + self._ser.setRTS(0) + else: + if rts == 0: + self._ser.setRTS(1) + else: + bl_sign = self._is_bouffalo_chip() + if bl_sign: + self._ser.write(b'BOUFFALOLAB5555RTS' + str(rts).encode()) + else: + if rts == 1: + self._ser.setRTS(0) + else: + if rts == 0: + self._ser.setRTS(1) + except: + pass + + def setRTS(self, rts): + self._ser.setRTS(rts) + + def reset(self): + if sys.platform.startswith('darwin'): + self._ser.write(b'BOUFFALOLAB5555DTR0') + time.sleep(0.05) + self._ser.write(b'BOUFFALOLAB5555RTS0') + time.sleep(0.05) + self._ser.write(b'BOUFFALOLAB5555RTS1') + self.clear_buf() + self._ser.setDTR(1) + time.sleep(0.05) + self._ser.setRTS(1) + time.sleep(0.05) + self._ser.setRTS(0) + else: + bl_sign = self._is_bouffalo_chip() + if bl_sign: + self._ser.write(b'BOUFFALOLAB5555DTR0') + time.sleep(0.05) + self._ser.write(b'BOUFFALOLAB5555RTS0') + time.sleep(0.05) + self._ser.write(b'BOUFFALOLAB5555RTS1') + else: + self._ser.setDTR(1) + time.sleep(0.05) + self._ser.setRTS(1) + time.sleep(0.05) + self._ser.setRTS(0) + + def set_isp_baudrate(self, baudrate): + printf('isp mode speed: ', baudrate) + self._isp_baudrate = baudrate + + def set_timeout(self, timeout): + self._ser.timeout = timeout + + def get_timeout(self): + return self._ser.timeout + + def deal_ack(self): + try: + success, ack = self.read(2) + if success == 0: + printf('ack is ', str(binascii.hexlify(ack))) + return ack.decode('utf-8') + if ack.find(b'O') != -1 or ack.find(b'K') != -1: + return 'OK' + if ack.find(b'P') != -1 or ack.find(b'D') != -1: + return 'PD' + success, err_code = self.read(2) + if success == 0: + printf('err code is ', str(binascii.hexlify(err_code))) + return 'FL' + err_code_str = str(binascii.hexlify(err_code[1:2] + err_code[0:1]).decode('utf-8')) + ack = 'FL' + try: + ret = ack + err_code_str + '(' + get_bflb_error_code(err_code_str) + ')' + except Exception as e: + try: + printf(e) + ret = ack + err_code_str + ' unknown' + finally: + e = None + del e + + printf(ret) + return ret + except Exception as e: + try: + printf('Error: %s' % e) + finally: + e = None + del e + + def deal_response(self): + try: + ack = self.deal_ack() + if ack == 'OK': + success, len_bytes = self.read(2) + if success == 0: + printf('Get length error') + printf('len error is ', binascii.hexlify(len_bytes)) + return ( + 'Get length error', len_bytes) + tmp = bytearray_reverse(len_bytes) + data_len = bytearray_to_int(tmp) + success, data_bytes = self.read(data_len) + if success == 0 or len(data_bytes) != data_len: + printf('Read data error,maybe not get excepted length') + return ( + 'Read data error,maybe not get excepted length', data_bytes) + return ( + ack, data_bytes) + printf('Not ack OK') + printf(ack) + return ( + ack, None) + except Exception as e: + try: + printf('Error: %s' % e) + finally: + e = None + del e + + +class BLSerialJLink(object): + + def __init__(self, device, speed, jlink_shake_hand_addr, jlink_data_addr, jlink_set_tif, jlink_core_type, jlink_run_addr): + self.device = device + self.speed = speed + self.jlink_shake_hand_addr = jlink_shake_hand_addr + self.jlink_data_addr = jlink_data_addr + self.jlink_run_addr = jlink_run_addr + self._rx_timeout = 10000 + self._chiptype = 'bl602' + if sys.platform == 'win32': + obj_dll = pylink.Library(dllpath=path_dll) + self._jlink = pylink.JLink(lib=obj_dll) + self.jlink_path = os.path.join(app_path, 'utils/jlink', 'JLink.exe') + else: + self._jlink = pylink.JLink() + self.jlink_path = 'JLinkExe' + match = re.search('\\d{8,10}', device, re.I) + if match is not None: + self._jlink.open(serial_no=(int(self.device))) + else: + self._jlink.open() + self._jlink.set_tif(jlink_set_tif) + self._jlink.connect(jlink_core_type, self.speed) + + def set_chip_type(self, chiptype): + self._chiptype = chiptype + + def write(self, message): + self.raw_write(self.jlink_data_addr, message) + data_list = [] + data_list.append(int('59445248', 16)) + self._jlink.memory_write((int(self.jlink_shake_hand_addr, 16)), data_list, nbits=32) + + def raw_write(self, addr, data_send): + addr_int = int(addr, 16) + len2 = len(data_send) % 4 + len1 = len(data_send) - len2 + if len1 != 0: + data_list = [] + for i in range(int(len1 / 4)): + data_list.append(data_send[4 * i] + (data_send[4 * i + 1] << 8) + (data_send[4 * i + 2] << 16) + (data_send[4 * i + 3] << 24)) + + self._jlink.memory_write(addr_int, data_list, nbits=32) + if len2 != 0: + data_list = [] + for i in range(len2): + data_list.append(data_send[len1 + i]) + + self._jlink.memory_write((addr_int + len1), data_list, nbits=8) + + def raw_write_8(self, addr, data_send): + data_list = [] + for data in data_send: + data_list.append(data) + + self._jlink.memory_write((int(addr, 16)), data_list, nbits=8) + + def raw_write_16(self, addr, data_send): + data_list = [] + for i in range(int(len(data_send) / 2)): + data_list.append(data_send[2 * i] + (data_send[2 * i + 1] << 8)) + + self._jlink.memory_write((int(addr, 16)), data_list, nbits=16) + + def raw_write_32(self, addr, data_send): + data_list = [] + for i in range(int(len(data_send) / 4)): + data_list.append(data_send[4 * i] + (data_send[4 * i + 1] << 8) + (data_send[4 * i + 2] << 16) + (data_send[4 * i + 3] << 24)) + + self._jlink.memory_write((int(addr, 16)), data_list, nbits=32) + + def read(self, length): + start_time = time.time() * 1000 + while True: + ready = self._jlink.memory_read((int(self.jlink_shake_hand_addr, 16)), 1, nbits=32) + if len(ready) >= 1: + if ready[0] == int('4B434153', 16): + break + elapsed = time.time() * 1000 - start_time + if elapsed >= self._rx_timeout: + return 'waiting response time out'.encode('utf-8') + else: + time.sleep(0.001) + + data = self._raw_read(self.jlink_data_addr, length) + if len(data) != length: + return (0, data) + return (1, data) + + def _raw_read(self, addr, data_len): + addr_int = int(addr, 16) + if addr_int % 4 == 0: + len2 = data_len % 4 + len1 = data_len - len2 + data1 = bytearray(0) + data2 = bytearray(0) + if len1 != 0: + data1 = self._jlink.memory_read(addr_int, (int(len1 / 4)), nbits=32) + if len2 != 0: + data2 = self._jlink.memory_read((addr_int + len1), len2, nbits=8) + data = bytearray(0) + for tmp in data1: + data += int_to_4bytearray_l(tmp) + + data += bytearray(data2) + return data + return self._raw_read8(addr, data_len) + + def _raw_read8(self, addr, data_len): + data = self._jlink.memory_read((int(addr, 16)), data_len, nbits=8) + return bytearray(data) + + def _raw_read16(self, addr, data_len): + raw_data = self._jlink.memory_read((int(addr, 16)), (data_len / 2), nbits=16) + data = bytearray(0) + for tmp in raw_data: + data += int_to_2bytearray_l(tmp) + + return bytearray(data) + + def _raw_read32(self, addr, data_len): + raw_data = self._jlink.memory_read((int(addr, 16)), (data_len / 4), nbits=32) + data = bytearray(0) + for tmp in raw_data: + data += int_to_4bytearray_l(tmp) + + return bytearray(data) + + def set_rx_timeout(self, val): + self._rx_timeout = val * 1000 + + def halt_cpu(self): + if self._jlink.halted() is False: + self._jlink.halt() + if self._jlink.halted(): + return True + printf("couldn't halt cpu") + return False + + def reset_cpu(self, ms=0, halt=True): + if self._chiptype != 'bl60x': + self._jlink.set_reset_pin_low() + self._jlink.set_reset_pin_high() + return self._jlink.reset(ms, False) + + def set_pc_msp(self, pc, msp): + if self._jlink.halted() is False: + self._jlink.halt() + if self._jlink.halted(): + if self._chiptype == 'bl602' or self._chiptype == 'bl702' or self._chiptype == 'bl702l': + jlink_script = 'jlink.cmd' + fp = open(jlink_script, 'w+') + cmd = 'h\r\nSetPC ' + str(self._jlink_run_addr) + '\r\nexit' + printf(cmd) + fp.write(cmd) + fp.close() + if self._device: + jlink_cmd = self.jlink_path + ' -device RISC-V -Speed {0} -SelectEmuBySN {1} -IF JTAG -jtagconf -1,-1 -autoconnect 1 -CommanderScript jlink.cmd'.format(str(self._speed), str(self._device)) + else: + jlink_cmd = self.jlink_path + ' -device RISC-V -Speed {0} -IF JTAG -jtagconf -1,-1 -autoconnect 1 -CommanderScript jlink.cmd'.format(str(self._speed)) + printf(jlink_cmd) + p = subprocess.Popen(jlink_cmd, shell=True, stdin=(subprocess.PIPE), stdout=(subprocess.PIPE), stderr=(subprocess.PIPE)) + out, err = p.communicate() + printf(out, err) + os.remove(jlink_script) + else: + self._jlink.register_write(15, int(pc, 16)) + self._jlink.register_write(13, int(msp, 16)) + self._jlink.restart() + else: + printf("couldn't halt cpu") + + def shakehand(self, do_reset=False, reset_hold_time=100, shake_hand_delay=100, reset_revert=True, cutoff_time=0, shake_hand_retry=2, isp_timeout=0, boot_load=False): + self.write(bytearray(1)) + success, ack = self.if_read(2) + printf(binascii.hexlify(ack)) + if ack.find(b'O') != -1 or ack.find(b'K') != -1: + time.sleep(0.03) + return 'OK' + return 'FL' + + def deal_ack(self): + success, ack = self.read(2) + if success == 0: + printf('ack:' + str(binascii.hexlify(ack))) + return ack.decode('utf-8') + if ack.find(b'O') != -1 or ack.find(b'K') != -1: + return 'OK' + if ack.find(b'P') != -1 or ack.find(b'D') != -1: + return 'PD' + success, err_code = self.read(4) + if success == 0: + printf('err_code:' + str(binascii.hexlify(err_code))) + return 'FL' + err_code_str = str(binascii.hexlify(err_code[3:4] + err_code[2:3]).decode('utf-8')) + ack = 'FL' + try: + ret = ack + err_code_str + '(' + get_bflb_error_code(err_code_str) + ')' + except Exception: + ret = ack + err_code_str + ' unknown' + + printf(ret) + return ret + + def deal_response(self): + ack = self.if_deal_ack() + if ack == 'OK': + success, len_bytes = self.read(4) + if success == 0: + printf('Get length error') + printf(binascii.hexlify(len_bytes)) + return ( + 'Get length error', len_bytes) + tmp = bytearray_reverse(len_bytes[2:4]) + data_len = bytearray_to_int(tmp) + success, data_bytes = self.read(data_len + 4) + if success == 0: + printf('Read data error') + return ( + 'Read data error', data_bytes) + data_bytes = data_bytes[4:] + if len(data_bytes) != data_len: + printf('Not get excepted length') + return ( + 'Not get excepted length', data_bytes) + return (ack, data_bytes) + printf('Not ack OK') + printf(ack) + return ( + ack, None) + + def close(self): + self._jlink.close() + + +class BLSerialCKLink(object): + + def __init__(self, device, serial, speed, rx_timeout, cklink_shake_hand_addr='20000000', cklink_data_addr='20000004', cklink_run_addr='22010000'): + self.device = device + self.serial = serial + self._speed = speed + self._rx_timeout = rx_timeout + self._inited = False + self._cklink_reg_pc = 32 + self._cklink_shake_hand_addr = cklink_shake_hand_addr + self._cklink_data_addr = cklink_data_addr + self._cklink_run_addr = cklink_run_addr + self._chiptype = 'bl602' + self.link = gol.obj_cklink + self.temp_init() + + def temp_init(self): + if self._inited is False: + dev = self.device.split('|') + vid = int(dev[0].replace('0x', ''), 16) + pid = int(dev[1].replace('0x', ''), 16) + printf('SN is ' + str(self.serial)) + self._cklink_vid = vid + self._cklink_pid = pid + self._inited = True + if not self.link: + self.link = cklink.CKLink(dlldir=cklink_dll, vid=(self._cklink_vid), pid=(self._cklink_pid), sn=serial, arch=2, cdi=0) + gol.obj_cklink = self.link + self.link.open() + if self.link.connected(): + self.link.reset(1) + return False + + def set_chip_type(self, chiptype): + self._chiptype = chiptype + + def set_rx_timeout(self, val): + self._rx_timeout = val * 1000 + + def halt_cpu(self): + return self.link.halt() + + def resume_cpu(self): + return self.link.resume() + + def reset_cpu(self): + return self.link.reset(1) + + def set_pc_msp(self): + self.halt_cpu() + if self._chiptype == 'bl602' or self._chiptype == 'bl702' or self._chiptype == 'bl702l': + addr = int(self._cklink_run_addr, 16) + self.link.write_cpu_reg(self._cklink_reg_pc, addr) + + def write(self, message): + self.if_raw_write(self._cklink_data_addr, message) + self.if_raw_write(self._cklink_shake_hand_addr, binascii.unhexlify('48524459')) + + def _raw_write(self, addr, data_send): + self.halt_cpu() + addr_int = int(addr, 16) + data_send = bytes(data_send) + self.link.write_memory(addr_int, data_send) + self.resume_cpu() + + def read(self, length): + start_time = time.time() * 1000 + while True: + self.halt_cpu() + ready = self.link.read_memory(int(self._cklink_shake_hand_addr, 16), 4) + if len(ready) >= 1: + ready = binascii.hexlify(ready).decode() + if ready == '5341434b': + self.resume_cpu() + break + elapsed = time.time() * 1000 - start_time + if elapsed >= self._rx_timeout: + return (0, 'waiting response time out'.encode('utf-8')) + else: + self.resume_cpu() + time.sleep(0.001) + + data = self._raw_read(self._cklink_data_addr, length) + if len(data) != length: + return (0, data) + return (1, data) + + def _raw_read(self, addr, data_len): + return self.if_raw_read8(addr, data_len) + + def _raw_read8(self, addr, data_len): + self.halt_cpu() + data = self.link.read_memory(int(addr, 16), data_len) + self.resume_cpu() + return bytearray(data) + + def if_shakehand(self): + self.if_write(bytearray(1)) + success, ack = self.read(2) + printf(binascii.hexlify(ack)) + if ack.find(b'O') != -1 or ack.find(b'K') != -1: + time.sleep(0.03) + return 'OK' + return 'FL' + + def deal_ack(self): + success, ack = self.read(2) + if success == 0: + printf('ack:' + str(binascii.hexlify(ack))) + return ack.decode('utf-8') + if ack.find(b'O') != -1 or ack.find(b'K') != -1: + return 'OK' + if ack.find(b'P') != -1 or ack.find(b'D') != -1: + return 'PD' + success, err_code = self.if_read(4) + if success == 0: + printf('err_code:' + str(binascii.hexlify(err_code))) + return 'FL' + err_code_str = str(binascii.hexlify(err_code[3:4] + err_code[2:3]).decode('utf-8')) + ack = 'FL' + try: + ret = ack + err_code_str + '(' + get_bflb_error_code(err_code_str) + ')' + except Exception: + ret = ack + err_code_str + ' unknown' + + printf(ret) + return ret + + def deal_response(self): + ack = self.deal_ack() + if ack == 'OK': + success, len_bytes = self.read(16) + if success == 0: + printf('Get length error') + printf(binascii.hexlify(len_bytes)) + return ( + 'Get length error', len_bytes) + tmp = bytearray_reverse(len_bytes[2:4]) + data_len = bytearray_to_int(tmp) + success, data_bytes = self.if_read(data_len + 4) + if success == 0: + printf('Read data error') + return ( + 'Read data error', data_bytes) + data_bytes = data_bytes[4:] + if len(data_bytes) != data_len: + printf('Not get excepted length') + return ( + 'Not get excepted length', data_bytes) + return (ack, data_bytes) + printf('Not ack OK') + printf(ack) + return ( + ack, None) + + +if __name__ == '__main__': + print(pylink_enumerate()) + ls = BLSerialUart('COM28', 2000000, '4201BFF0', '4201C000', 0, 'RISC-V', '22010000') + ls.set_dtr(0) + time.sleep(10) + ls.set_dtr(1) + ls.close() +# okay decompiling ./libs/base/bflb_serial.pyc diff --git a/libs/base/bl602/bootheader_cfg_keys.py b/libs/base/bl602/bootheader_cfg_keys.py new file mode 100644 index 0000000..8fe5ecb --- /dev/null +++ b/libs/base/bl602/bootheader_cfg_keys.py @@ -0,0 +1,331 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/bl602/bootheader_cfg_keys.py +bootheader_len = 176 +bootheader_cfg_keys = {'magic_code':{'offset':'0', + 'pos':'0', + 'bitlen':'32'}, + 'revision':{'offset':'4', + 'pos':'0', + 'bitlen':'32'}, + 'flashcfg_magic_code':{'offset':'8', + 'pos':'0', + 'bitlen':'32'}, + 'io_mode':{'offset':'12', + 'pos':'0', + 'bitlen':'8'}, + 'cont_read_support':{'offset':'12', + 'pos':'8', + 'bitlen':'8'}, + 'sfctrl_clk_delay':{'offset':'12', + 'pos':'16', + 'bitlen':'8'}, + 'sfctrl_clk_invert':{'offset':'12', + 'pos':'24', + 'bitlen':'8'}, + 'reset_en_cmd':{'offset':'16', + 'pos':'0', + 'bitlen':'8'}, + 'reset_cmd':{'offset':'16', + 'pos':'8', + 'bitlen':'8'}, + 'exit_contread_cmd':{'offset':'16', + 'pos':'16', + 'bitlen':'8'}, + 'exit_contread_cmd_size':{'offset':'16', + 'pos':'24', + 'bitlen':'8'}, + 'jedecid_cmd':{'offset':'20', + 'pos':'0', + 'bitlen':'8'}, + 'jedecid_cmd_dmy_clk':{'offset':'20', + 'pos':'8', + 'bitlen':'8'}, + 'qpi_jedecid_cmd':{'offset':'20', + 'pos':'16', + 'bitlen':'8'}, + 'qpi_jedecid_dmy_clk':{'offset':'20', + 'pos':'24', + 'bitlen':'8'}, + 'sector_size':{'offset':'24', + 'pos':'0', + 'bitlen':'8'}, + 'mfg_id':{'offset':'24', + 'pos':'8', + 'bitlen':'8'}, + 'page_size':{'offset':'24', + 'pos':'16', + 'bitlen':'16'}, + 'chip_erase_cmd':{'offset':'28', + 'pos':'0', + 'bitlen':'8'}, + 'sector_erase_cmd':{'offset':'28', + 'pos':'8', + 'bitlen':'8'}, + 'blk32k_erase_cmd':{'offset':'28', + 'pos':'16', + 'bitlen':'8'}, + 'blk64k_erase_cmd':{'offset':'28', + 'pos':'24', + 'bitlen':'8'}, + 'write_enable_cmd':{'offset':'32', + 'pos':'0', + 'bitlen':'8'}, + 'page_prog_cmd':{'offset':'32', + 'pos':'8', + 'bitlen':'8'}, + 'qpage_prog_cmd':{'offset':'32', + 'pos':'16', + 'bitlen':'8'}, + 'qual_page_prog_addr_mode':{'offset':'32', + 'pos':'24', + 'bitlen':'8'}, + 'fast_read_cmd':{'offset':'36', + 'pos':'0', + 'bitlen':'8'}, + 'fast_read_dmy_clk':{'offset':'36', + 'pos':'8', + 'bitlen':'8'}, + 'qpi_fast_read_cmd':{'offset':'36', + 'pos':'16', + 'bitlen':'8'}, + 'qpi_fast_read_dmy_clk':{'offset':'36', + 'pos':'24', + 'bitlen':'8'}, + 'fast_read_do_cmd':{'offset':'40', + 'pos':'0', + 'bitlen':'8'}, + 'fast_read_do_dmy_clk':{'offset':'40', + 'pos':'8', + 'bitlen':'8'}, + 'fast_read_dio_cmd':{'offset':'40', + 'pos':'16', + 'bitlen':'8'}, + 'fast_read_dio_dmy_clk':{'offset':'40', + 'pos':'24', + 'bitlen':'8'}, + 'fast_read_qo_cmd':{'offset':'44', + 'pos':'0', + 'bitlen':'8'}, + 'fast_read_qo_dmy_clk':{'offset':'44', + 'pos':'8', + 'bitlen':'8'}, + 'fast_read_qio_cmd':{'offset':'44', + 'pos':'16', + 'bitlen':'8'}, + 'fast_read_qio_dmy_clk':{'offset':'44', + 'pos':'24', + 'bitlen':'8'}, + 'qpi_fast_read_qio_cmd':{'offset':'48', + 'pos':'0', + 'bitlen':'8'}, + 'qpi_fast_read_qio_dmy_clk':{'offset':'48', + 'pos':'8', + 'bitlen':'8'}, + 'qpi_page_prog_cmd':{'offset':'48', + 'pos':'16', + 'bitlen':'8'}, + 'write_vreg_enable_cmd':{'offset':'48', + 'pos':'24', + 'bitlen':'8'}, + 'wel_reg_index':{'offset':'52', + 'pos':'0', + 'bitlen':'8'}, + 'qe_reg_index':{'offset':'52', + 'pos':'8', + 'bitlen':'8'}, + 'busy_reg_index':{'offset':'52', + 'pos':'16', + 'bitlen':'8'}, + 'wel_bit_pos':{'offset':'52', + 'pos':'24', + 'bitlen':'8'}, + 'qe_bit_pos':{'offset':'56', + 'pos':'0', + 'bitlen':'8'}, + 'busy_bit_pos':{'offset':'56', + 'pos':'8', + 'bitlen':'8'}, + 'wel_reg_write_len':{'offset':'56', + 'pos':'16', + 'bitlen':'8'}, + 'wel_reg_read_len':{'offset':'56', + 'pos':'24', + 'bitlen':'8'}, + 'qe_reg_write_len':{'offset':'60', + 'pos':'0', + 'bitlen':'8'}, + 'qe_reg_read_len':{'offset':'60', + 'pos':'8', + 'bitlen':'8'}, + 'release_power_down':{'offset':'60', + 'pos':'16', + 'bitlen':'8'}, + 'busy_reg_read_len':{'offset':'60', + 'pos':'24', + 'bitlen':'8'}, + 'reg_read_cmd0':{'offset':'64', + 'pos':'0', + 'bitlen':'8'}, + 'reg_read_cmd1':{'offset':'64', + 'pos':'8', + 'bitlen':'8'}, + 'reg_write_cmd0':{'offset':'68', + 'pos':'0', + 'bitlen':'8'}, + 'reg_write_cmd1':{'offset':'68', + 'pos':'8', + 'bitlen':'8'}, + 'enter_qpi_cmd':{'offset':'72', + 'pos':'0', + 'bitlen':'8'}, + 'exit_qpi_cmd':{'offset':'72', + 'pos':'8', + 'bitlen':'8'}, + 'cont_read_code':{'offset':'72', + 'pos':'16', + 'bitlen':'8'}, + 'cont_read_exit_code':{'offset':'72', + 'pos':'24', + 'bitlen':'8'}, + 'burst_wrap_cmd':{'offset':'76', + 'pos':'0', + 'bitlen':'8'}, + 'burst_wrap_dmy_clk':{'offset':'76', + 'pos':'8', + 'bitlen':'8'}, + 'burst_wrap_data_mode':{'offset':'76', + 'pos':'16', + 'bitlen':'8'}, + 'burst_wrap_code':{'offset':'76', + 'pos':'24', + 'bitlen':'8'}, + 'de_burst_wrap_cmd':{'offset':'80', + 'pos':'0', + 'bitlen':'8'}, + 'de_burst_wrap_cmd_dmy_clk':{'offset':'80', + 'pos':'8', + 'bitlen':'8'}, + 'de_burst_wrap_code_mode':{'offset':'80', + 'pos':'16', + 'bitlen':'8'}, + 'de_burst_wrap_code':{'offset':'80', + 'pos':'24', + 'bitlen':'8'}, + 'sector_erase_time':{'offset':'84', + 'pos':'0', + 'bitlen':'16'}, + 'blk32k_erase_time':{'offset':'84', + 'pos':'16', + 'bitlen':'16'}, + 'blk64k_erase_time':{'offset':'88', + 'pos':'0', + 'bitlen':'16'}, + 'page_prog_time':{'offset':'88', + 'pos':'16', + 'bitlen':'16'}, + 'chip_erase_time':{'offset':'92', + 'pos':'0', + 'bitlen':'16'}, + 'power_down_delay':{'offset':'92', + 'pos':'16', + 'bitlen':'8'}, + 'qe_data':{'offset':'92', + 'pos':'24', + 'bitlen':'8'}, + 'flashcfg_crc32':{'offset':'96', + 'pos':'0', + 'bitlen':'32'}, + 'clkcfg_magic_code':{'offset':'100', + 'pos':'0', + 'bitlen':'32'}, + 'xtal_type':{'offset':'104', + 'pos':'0', + 'bitlen':'8'}, + 'pll_clk':{'offset':'104', + 'pos':'8', + 'bitlen':'8'}, + 'hclk_div':{'offset':'104', + 'pos':'16', + 'bitlen':'8'}, + 'bclk_div':{'offset':'104', + 'pos':'24', + 'bitlen':'8'}, + 'flash_clk_type':{'offset':'108', + 'pos':'0', + 'bitlen':'8'}, + 'flash_clk_div':{'offset':'108', + 'pos':'8', + 'bitlen':'8'}, + 'clkcfg_crc32':{'offset':'112', + 'pos':'0', + 'bitlen':'32'}, + 'sign':{'offset':'116', + 'pos':'0', + 'bitlen':'2'}, + 'encrypt_type':{'offset':'116', + 'pos':'2', + 'bitlen':'2'}, + 'key_sel':{'offset':'116', + 'pos':'4', + 'bitlen':'2'}, + 'no_segment':{'offset':'116', + 'pos':'8', + 'bitlen':'1'}, + 'cache_enable':{'offset':'116', + 'pos':'9', + 'bitlen':'1'}, + 'notload_in_bootrom':{'offset':'116', + 'pos':'10', + 'bitlen':'1'}, + 'aes_region_lock':{'offset':'116', + 'pos':'11', + 'bitlen':'1'}, + 'cache_way_disable':{'offset':'116', + 'pos':'12', + 'bitlen':'4'}, + 'crc_ignore':{'offset':'116', + 'pos':'16', + 'bitlen':'1'}, + 'hash_ignore':{'offset':'116', + 'pos':'17', + 'bitlen':'1'}, + 'img_len':{'offset':'120', + 'pos':'0', + 'bitlen':'32'}, + 'bootentry':{'offset':'124', + 'pos':'0', + 'bitlen':'32'}, + 'img_start':{'offset':'128', + 'pos':'0', + 'bitlen':'32'}, + 'hash_0':{'offset':'132', + 'pos':'0', + 'bitlen':'32'}, + 'hash_1':{'offset':'136', + 'pos':'0', + 'bitlen':'32'}, + 'hash_2':{'offset':'140', + 'pos':'0', + 'bitlen':'32'}, + 'hash_3':{'offset':'144', + 'pos':'0', + 'bitlen':'32'}, + 'hash_4':{'offset':'148', + 'pos':'0', + 'bitlen':'32'}, + 'hash_5':{'offset':'152', + 'pos':'0', + 'bitlen':'32'}, + 'hash_6':{'offset':'156', + 'pos':'0', + 'bitlen':'32'}, + 'hash_7':{'offset':'160', + 'pos':'0', + 'bitlen':'32'}, + 'crc32':{'offset':'172', + 'pos':'0', + 'bitlen':'32'}} +# okay decompiling ./libs/base/bl602/bootheader_cfg_keys.pyc diff --git a/libs/base/bl602/cklink_load_cfg.py b/libs/base/bl602/cklink_load_cfg.py new file mode 100644 index 0000000..fc402c6 --- /dev/null +++ b/libs/base/bl602/cklink_load_cfg.py @@ -0,0 +1,12 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/bl602/cklink_load_cfg.py +cklink_shake_hand_addr = '4201BFF0' +cklink_data_addr = '4201C000' +cklink_load_addr = '22010000' +cklink_core_type = 'RISC-V' +cklink_set_tif = 0 +cklink_run_addr = '22010000' +# okay decompiling ./libs/base/bl602/cklink_load_cfg.pyc diff --git a/libs/base/bl602/flash_select_do.py b/libs/base/bl602/flash_select_do.py new file mode 100644 index 0000000..64e00c5 --- /dev/null +++ b/libs/base/bl602/flash_select_do.py @@ -0,0 +1,64 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/bl602/flash_select_do.py +import os, config as gol +from libs import bflb_utils +from libs.bflb_utils import app_path, conf_sign +from libs.bflb_configobj import BFConfigParser + +def get_suitable_file_name(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: + bflb_utils.printf('Flash id duplicate and alternative is:') + for i in range(len(conf_files)): + tmp = conf_files[i].split('.')[0] + bflb_utils.printf('%d:%s' % (i + 1, tmp)) + + return conf_files[i] + if len(conf_files) == 1: + return conf_files[0] + return '' + + +def update_flash_cfg_do(chipname, chiptype, flash_id, file=None, create=False, section=None): + if conf_sign: + cfg_dir = app_path + '/utils/flash/' + chipname + '/' + else: + cfg_dir = app_path + '/utils/flash/' + gol.flash_dict[chipname] + '/' + conf_name = get_suitable_file_name(cfg_dir, flash_id) + value_key = [] + if os.path.isfile(cfg_dir + conf_name) is False: + return False + fp = open(cfg_dir + conf_name, 'r') + for line in fp.readlines(): + value = line.split('=')[0].strip() + if value == '[FLASH_CFG]': + continue + else: + value_key.append(value) + + cfg1 = BFConfigParser() + cfg1.read(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]): + if cfg2.has_option(section, value_key[i]): + tmp_value = cfg1.get('FLASH_CFG', value_key[i]) + bflb_utils.update_cfg(cfg2, section, value_key[i], tmp_value) + + cfg2.write(file, 'w+') + bflb_utils.printf('Update flash cfg finished') + + +def get_supported_flash_do(): + flash_type = [] + return flash_type +# okay decompiling ./libs/base/bl602/flash_select_do.pyc diff --git a/libs/base/bl602/img_create_do.py b/libs/base/bl602/img_create_do.py new file mode 100644 index 0000000..751d358 --- /dev/null +++ b/libs/base/bl602/img_create_do.py @@ -0,0 +1,524 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/bl602/img_create_do.py +import hashlib, binascii, ecdsa +from libs import bflb_utils +from libs.bflb_utils import open_file, img_create_sha256_data, img_create_encrypt_data +from libs.bflb_configobj import BFConfigParser +from libs.base.bl602.bootheader_cfg_keys import bootheader_len as header_len +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 + +def img_update_efuse(cfg, sign, pk_hash, flash_encryp_type, flash_key, sec_eng_key_sel, sec_eng_key, security=False): + efuse_data = bytearray(128) + efuse_mask_data = bytearray(128) + if cfg != None: + 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] |= 128 + efuse_data[0] |= 48 + efuse_mask_data[0] |= 255 + rw_lock = 0 + if pk_hash is not 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 is not None: + if flash_encryp_type == 1: + efuse_data[keyslot2:keyslot3] = flash_key[0:16] + efuse_mask_data[keyslot2:keyslot3] = mask_4bytes * 4 + else: + if flash_encryp_type == 2: + efuse_data[keyslot2:keyslot4] = flash_key + efuse_mask_data[keyslot2:keyslot4] = mask_4bytes * 8 + rw_lock |= 1 << wr_lock_key_slot_3 + rw_lock |= 1 << rd_lock_key_slot_3 + else: + if flash_encryp_type == 3: + efuse_data[keyslot2:keyslot4] = flash_key + efuse_mask_data[keyslot2:keyslot4] = mask_4bytes * 8 + rw_lock |= 1 << wr_lock_key_slot_3 + rw_lock |= 1 << rd_lock_key_slot_3 + rw_lock |= 1 << wr_lock_key_slot_2 + rw_lock |= 1 << rd_lock_key_slot_2 + if sec_eng_key is not None: + if flash_encryp_type == 0: + if sec_eng_key_sel == 0: + efuse_data[keyslot3:keyslot4] = sec_eng_key[0:16] + efuse_mask_data[keyslot3:keyslot4] = mask_4bytes * 4 + rw_lock |= 1 << wr_lock_key_slot_3 + rw_lock |= 1 << rd_lock_key_slot_3 + if sec_eng_key_sel == 1: + efuse_data[keyslot2:keyslot3] = sec_eng_key[0:16] + efuse_mask_data[keyslot2:keyslot3] = mask_4bytes * 4 + rw_lock |= 1 << wr_lock_key_slot_2 + rw_lock |= 1 << rd_lock_key_slot_2 + 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 + efuse_data[124:128] = bflb_utils.int_to_4bytearray_l(rw_lock) + efuse_mask_data[124:128] = bflb_utils.int_to_4bytearray_l(rw_lock) + if cfg != None: + if security is True: + bflb_utils.printf('Encrypt efuse data') + security_key, security_iv = bflb_utils.get_security_key() + efuse_data = img_create_encrypt_data(efuse_data, security_key, security_iv, 0) + efuse_data = bytearray(4096) + efuse_data + 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() + return efuse_data + + +def img_create_get_sign_encrypt_info(bootheader_data): + sign = bootheader_data[116] & 3 + encrypt = bootheader_data[116] >> 2 & 3 + key_sel = bootheader_data[116] >> 4 & 3 + return ( + sign, encrypt, key_sel) + + +def img_create_get_hash_ignore(bootheader_data): + return bootheader_data[118] >> 1 & 1 + + +def img_create_get_crc_ignore(bootheader_data): + return bootheader_data[118] & 1 + + +def img_create_update_bootheader_if(bootheader_data, hash, seg_cnt): + bootheader_data[120:124] = bflb_utils.int_to_4bytearray_l(seg_cnt) + sign = bootheader_data[116] & 3 + encrypt = bootheader_data[116] >> 2 & 3 + key_sel = bootheader_data[116] >> 4 & 3 + if bootheader_data[118] >> 1 & 1 == 1 and sign == 0: + bflb_utils.printf('Hash ignored') + else: + bootheader_data[132:164] = hash + if bootheader_data[118] & 1 == 1: + bflb_utils.printf('Header crc ignored') + else: + hd_crcarray = bflb_utils.get_crc32_bytearray(bootheader_data[0:header_len - 4]) + bootheader_data[header_len - 4:header_len] = hd_crcarray + bflb_utils.printf('Header crc: ', binascii.hexlify(hd_crcarray)) + return bootheader_data + + +def img_create_update_bootheader(bootheader_data, hash, seg_cnt): + bootheader_data[120:124] = bflb_utils.int_to_4bytearray_l(seg_cnt) + sign, encrypt, key_sel = img_create_get_sign_encrypt_info(bootheader_data) + if img_create_get_hash_ignore(bootheader_data) == 1 and sign == 0: + bflb_utils.printf('Hash ignored') + else: + bootheader_data[132:164] = hash + if img_create_get_crc_ignore(bootheader_data) == 1: + bflb_utils.printf('Header crc ignored') + else: + hd_crcarray = bflb_utils.get_crc32_bytearray(bootheader_data[0:header_len - 4]) + bootheader_data[header_len - 4:header_len] = hd_crcarray + bflb_utils.printf('Header crc: ', binascii.hexlify(hd_crcarray)) + return bootheader_data[0:header_len] + + +def img_create_update_segheader(segheader, segdatalen, segdatacrc): + segheader[4:8] = segdatalen + segheader[8:12] = segdatacrc + return segheader + + +def img_create_sign_data(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() + bflb_utils.printf('Private key: ', binascii.hexlify(sk.to_string())) + bflb_utils.printf('Public key: ', binascii.hexlify(pk_data)) + pk_hash = img_create_sha256_data(pk_data) + bflb_utils.printf('Public key hash=', binascii.hexlify(pk_hash)) + signature = sk.sign(data_bytearray, hashfunc=(hashlib.sha256), sigencode=(ecdsa.util.sigencode_string)) + bflb_utils.printf('Signature=', binascii.hexlify(signature)) + len_array = bflb_utils.int_to_4bytearray_l(len(signature)) + sig_field = len_array + signature + crcarray = bflb_utils.get_crc32_bytearray(sig_field) + return ( + pk_data, pk_hash, sig_field + crcarray) + + +def img_create_read_file_append_crc(file, crc): + fp = open(file, 'rb') + read_data = bytearray(fp.read()) + crcarray = bytearray(0) + if crc: + crcarray = bflb_utils.get_crc32_bytearray(read_data) + fp.close() + return read_data + crcarray + + +def encrypt_loader_bin_do(file, sign, encrypt, temp_encrypt_key, temp_encrypt_iv, publickey_file, privatekey_file): + if encrypt != 0 or sign != 0: + encrypt_key = bytearray(0) + encrypt_iv = bytearray(0) + load_helper_bin_header = bytearray(0) + load_helper_bin_body = bytearray(0) + offset = 116 + sign_pos = 0 + encrypt_type_pos = 2 + key_sel_pos = 4 + pk_data = bytearray(0) + signature = bytearray(0) + aesiv_data = bytearray(0) + data_tohash = bytearray(0) + with open(file, 'rb') as fp: + load_helper_bin = fp.read() + load_helper_bin_header = load_helper_bin[0:header_len] + load_helper_bin_body = load_helper_bin[header_len:] + if load_helper_bin_header != bytearray(0): + if load_helper_bin_body != bytearray(0): + load_helper_bin_body = bflb_utils.add_to_16(load_helper_bin_body) + if encrypt != 0: + encrypt_key = bflb_utils.hexstr_to_bytearray(temp_encrypt_key) + encrypt_iv = bflb_utils.hexstr_to_bytearray(temp_encrypt_iv) + iv_crcarray = bflb_utils.get_crc32_bytearray(encrypt_iv) + aesiv_data = encrypt_iv + iv_crcarray + data_tohash = data_tohash + aesiv_data + load_helper_bin_body_encrypt = bflb_utils.img_create_encrypt_data(load_helper_bin_body, encrypt_key, encrypt_iv, 0) + else: + load_helper_bin_body_encrypt = load_helper_bin_body + data = bytearray(load_helper_bin_header) + oldval = bflb_utils.bytearray_to_int(bflb_utils.bytearray_reverse(data[offset:offset + 4])) + newval = oldval + if encrypt != 0: + newval = newval | 1 << encrypt_type_pos + newval = newval | 0 << key_sel_pos + if sign != 0: + newval = newval | 1 << sign_pos + data_tohash += load_helper_bin_body_encrypt + pk_data, pk_hash, signature = img_create_sign_data(data_tohash, privatekey_file, publickey_file) + pk_data = pk_data + bflb_utils.get_crc32_bytearray(pk_data) + data[offset:offset + 4] = bflb_utils.int_to_4bytearray_l(newval) + load_helper_bin_header = data + load_helper_bin_encrypt = load_helper_bin_header + pk_data + signature + aesiv_data + load_helper_bin_body_encrypt + hash = img_create_sha256_data(data_tohash) + bflb_utils.printf('Image hash is ', binascii.hexlify(hash)) + load_helper_bin_data = bytearray(load_helper_bin_encrypt) + load_helper_bin_encrypt = img_create_update_bootheader_if(load_helper_bin_data, hash, 1) + return ( + True, load_helper_bin_encrypt) + return (False, None) + + +def create_encryptandsign_flash_data(data, offset, key, iv, publickey, privatekey): + encrypt = 0 + encrypt_type = 0 + sign = 0 + data_len = len(data) + aesiv_data = bytearray(0) + pk_data = bytearray(0) + data_tohash = bytearray(0) + efuse_data = bytearray(128) + bootheader_data = data[0:176] + img_len = bflb_utils.bytearray_to_int(data[120:121]) + (bflb_utils.bytearray_to_int(data[121:122]) << 8) + (bflb_utils.bytearray_to_int(data[122:123]) << 16) + (bflb_utils.bytearray_to_int(data[123:124]) << 24) + img_data = data[offset:offset + img_len] + if key: + if iv: + encrypt = 1 + if len(key) == 32: + encrypt_type = 1 + else: + if len(key) == 64: + encrypt_type = 2 + else: + if len(key) == 48: + encrypt_type = 3 + bootheader_data[116] |= encrypt_type + if publickey: + if privatekey: + sign = 1 + bootheader_data[116] |= 4 + if encrypt: + encrypt_key = bflb_utils.hexstr_to_bytearray(key) + encrypt_iv = bflb_utils.hexstr_to_bytearray(iv) + iv_crcarray = bflb_utils.get_crc32_bytearray(encrypt_iv) + aesiv_data = encrypt_iv + iv_crcarray + data_tohash = data_tohash + aesiv_data + mfgBin = False + if img_data[img_len - 16:img_len - 12] == bytearray('0mfg'.encode('utf-8')): + bflb_utils.printf('mfg bin') + mfgBin = True + data_toencrypt = bytearray(0) + if mfgBin: + data_toencrypt += img_data[:img_len - 16] + else: + data_toencrypt += img_data + if encrypt: + data_toencrypt = img_create_encrypt_data(data_toencrypt, encrypt_key, encrypt_iv, 1) + if mfgBin: + data_toencrypt += img_data[img_len - 16:img_len] + fw_data = bytearray(0) + data_tohash += data_toencrypt + fw_data = data_toencrypt + seg_cnt = len(data_toencrypt) + hash = img_create_sha256_data(data_tohash) + bflb_utils.printf('Image hash is ', binascii.hexlify(hash)) + bootheader_data = img_create_update_bootheader(bootheader_data, hash, seg_cnt) + signature = bytearray(0) + pk_hash = None + if sign: + pk_data, pk_hash, signature = img_create_sign_data(data_tohash, privatekey, publickey) + pk_data = pk_data + bflb_utils.get_crc32_bytearray(pk_data) + bflb_utils.printf('Write flash img') + bootinfo = bootheader_data + pk_data + signature + aesiv_data + output_data = bytearray(data_len) + for i in range(data_len): + output_data[i] = 255 + + output_data[0:len(bootinfo)] = bootinfo + output_data[offset:offset + seg_cnt] = fw_data + if encrypt != 0: + if encrypt_type == 1: + efuse_data = img_update_efuse(None, sign, pk_hash, 1, encrypt_key + bytearray(32 - len(encrypt_key)), 0, encrypt_key + bytearray(32 - len(encrypt_key))) + if encrypt_type == 2: + efuse_data = img_update_efuse(None, sign, pk_hash, 3, encrypt_key + bytearray(32 - len(encrypt_key)), 0, encrypt_key + bytearray(32 - len(encrypt_key))) + if encrypt_type == 3: + efuse_data = img_update_efuse(None, sign, pk_hash, 2, encrypt_key + bytearray(32 - len(encrypt_key)), 0, encrypt_key + bytearray(32 - len(encrypt_key))) + return ( + output_data, efuse_data, seg_cnt) + + +def img_creat_process(flash_img, cfg, security=False): + encrypt_blk_size = 16 + padding = bytearray(encrypt_blk_size) + data_tohash = bytearray(0) + cfg_section = 'Img_Cfg' + 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 + + boot_header_file = cfg.get(cfg_section, 'boot_header_file') + bootheader_data = img_create_read_file_append_crc(boot_header_file, 0) + encrypt = 0 + sign, encrypt, key_sel = img_create_get_sign_encrypt_info(bootheader_data) + aesiv_data = bytearray(0) + pk_data = bytearray(0) + if sign != 0: + bflb_utils.printf('Image need sign') + publickey_file = cfg.get(cfg_section, 'publickey_file') + privatekey_file_uecc = cfg.get(cfg_section, 'privatekey_file_uecc') + if encrypt != 0: + bflb_utils.printf('Image need encrypt ', encrypt) + encrypt_key_org = bflb_utils.hexstr_to_bytearray(cfg.get(cfg_section, 'aes_key_org')) + if encrypt == 1: + encrypt_key = encrypt_key_org[0:16] + else: + if encrypt == 2: + encrypt_key = encrypt_key_org[0:32] + else: + if encrypt == 3: + encrypt_key = encrypt_key_org[0:24] + bflb_utils.printf('Key= ', binascii.hexlify(encrypt_key)) + encrypt_iv = bflb_utils.hexstr_to_bytearray(cfg.get(cfg_section, 'aes_iv')) + iv_crcarray = bflb_utils.get_crc32_bytearray(encrypt_iv) + aesiv_data = encrypt_iv + iv_crcarray + data_tohash = data_tohash + aesiv_data + seg_cnt = len(segheader_file) + if flash_img == 0: + if seg_cnt != len(segdata_file): + bflb_utils.printf('Segheader count and segdata count not match') + return ( + 'FAIL', data_tohash) + mfgBin = False + data_toencrypt = bytearray(0) + if flash_img == 0: + i = 0 + seg_header_list = [] + seg_data_list = [] + while i < seg_cnt: + seg_data = 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] + else: + segdata_crcarray = bflb_utils.get_crc32_bytearray(seg_data) + seg_data_list.append(seg_data) + seg_header = img_create_read_file_append_crc(segheader_file[i], 0) + seg_header = img_create_update_segheader(seg_header, bflb_utils.int_to_4bytearray_l(len(seg_data)), segdata_crcarray) + segheader_crcarray = bflb_utils.get_crc32_bytearray(seg_header) + seg_header = seg_header + segheader_crcarray + seg_header_list.append(seg_header) + i = i + 1 + + i = 0 + while i < seg_cnt: + data_toencrypt += seg_header_list[i] + data_toencrypt += seg_data_list[i] + i += 1 + + else: + seg_data = 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] + if seg_data[len(seg_data) - 16:len(seg_data) - 12] == bytearray('0mfg'.encode('utf-8')): + mfgBin = True + if mfgBin: + data_toencrypt += seg_data[:len(seg_data) - 16] + else: + data_toencrypt += seg_data + seg_cnt = len(data_toencrypt) + if mfgBin: + seg_cnt += 16 + if encrypt != 0: + data_toencrypt = img_create_encrypt_data(data_toencrypt, encrypt_key, encrypt_iv, flash_img) + if mfgBin: + data_toencrypt += seg_data[len(seg_data) - 16:len(seg_data)] + fw_data = bytearray(0) + data_tohash += data_toencrypt + fw_data = data_toencrypt + hash = img_create_sha256_data(data_tohash) + bflb_utils.printf('Image hash is ', binascii.hexlify(hash)) + bootheader_data = img_create_update_bootheader(bootheader_data, hash, seg_cnt) + 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 + bflb_utils.get_crc32_bytearray(pk_data) + if flash_img == 1: + bflb_utils.printf('Write flash img') + 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() + fw_data_hash = img_create_sha256_data(fw_data) + fp = open(fw_file_name.replace('.bin', '_withhash.bin'), 'wb+') + fp.write(fw_data + fw_data_hash) + fp.close() + if encrypt != 0: + if encrypt == 1: + img_update_efuse(cfg, sign, pk_hash, 1, encrypt_key + bytearray(32 - len(encrypt_key)), key_sel, encrypt_key + bytearray(32 - len(encrypt_key)), security) + if encrypt == 2: + img_update_efuse(cfg, sign, pk_hash, 3, encrypt_key + bytearray(32 - len(encrypt_key)), key_sel, encrypt_key + bytearray(32 - len(encrypt_key)), security) + if encrypt == 3: + img_update_efuse(cfg, sign, pk_hash, 2, encrypt_key + bytearray(32 - len(encrypt_key)), key_sel, encrypt_key + bytearray(32 - len(encrypt_key)), security) + else: + img_update_efuse(cfg, sign, pk_hash, encrypt, None, key_sel, None, security) + else: + bflb_utils.printf('Write if img') + 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() + if encrypt != 0: + if encrypt == 1: + img_update_efuse(cfg, sign, pk_hash, 1, None, key_sel, encrypt_key + bytearray(32 - len(encrypt_key)), security) + if encrypt == 2: + img_update_efuse(cfg, sign, pk_hash, 3, None, key_sel, encrypt_key + bytearray(32 - len(encrypt_key)), security) + if encrypt == 3: + img_update_efuse(cfg, sign, pk_hash, 2, None, key_sel, encrypt_key + bytearray(32 - len(encrypt_key)), security) + else: + img_update_efuse(cfg, sign, pk_hash, 0, None, key_sel, bytearray(32), security) + return ( + 'OK', data_tohash) + + +def img_create_do(args, img_dir_path=None, config_file=None): + bflb_utils.printf('Image create path: ', img_dir_path) + if config_file is None: + config_file = img_dir_path + '/img_create_cfg.ini' + bflb_utils.printf('Config file: ', config_file) + cfg = BFConfigParser() + cfg.read(config_file) + img_type = 'media' + signer = 'none' + security = False + data_tohash = bytearray(0) + try: + if args.image: + img_type = args.image + if args.signer: + signer = args.signer + if args.security: + security = args.security == 'efuse' + except Exception as e: + try: + bflb_utils.printf(e) + finally: + e = None + del e + + if img_type == 'media': + flash_img = 1 + else: + flash_img = 0 + ret, data_tohash = img_creat_process(flash_img, cfg, security) + if ret != 'OK': + bflb_utils.printf('Fail to create images!') + + +def create_sp_media_image(config, cpu_type=None, security=False): + bflb_utils.printf('========= sp image create =========') + cfg = BFConfigParser() + cfg.read(config) + img_creat_process(1, cfg, security) +# okay decompiling ./libs/base/bl602/img_create_do.pyc diff --git a/libs/base/bl602/jlink_load_cfg.py b/libs/base/bl602/jlink_load_cfg.py new file mode 100644 index 0000000..9e760e4 --- /dev/null +++ b/libs/base/bl602/jlink_load_cfg.py @@ -0,0 +1,12 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/bl602/jlink_load_cfg.py +jlink_shake_hand_addr = '4201BFF0' +jlink_data_addr = '4201C000' +jlink_load_addr = '22010000' +jlink_core_type = 'RISC-V' +jlink_set_tif = 0 +jlink_run_addr = '22010000' +# okay decompiling ./libs/base/bl602/jlink_load_cfg.pyc diff --git a/libs/base/bl602/openocd_load_cfg.py b/libs/base/bl602/openocd_load_cfg.py new file mode 100644 index 0000000..41a6947 --- /dev/null +++ b/libs/base/bl602/openocd_load_cfg.py @@ -0,0 +1,12 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/bl602/openocd_load_cfg.py +openocd_shake_hand_addr = '4201BFF0' +openocd_data_addr = '4201C000' +openocd_load_addr = '22010000' +openocd_core_type = 'RISC-V' +openocd_set_tif = 0 +openocd_run_addr = '22010000' +# okay decompiling ./libs/base/bl602/openocd_load_cfg.pyc diff --git a/libs/base/bl616/bootheader_cfg_keys.py b/libs/base/bl616/bootheader_cfg_keys.py new file mode 100644 index 0000000..b847d66 --- /dev/null +++ b/libs/base/bl616/bootheader_cfg_keys.py @@ -0,0 +1,482 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/bl616/bootheader_cfg_keys.py +clock_start_pos = 100 +bootcfg_start_pos = 120 +bootcfg_len = 48 +bootcpucfg_start_pos = bootcfg_start_pos + bootcfg_len +bootcpucfg_len = 16 +bootcpucfg_m0_index = 0 +bootcpucfg_d0_index = 1 +bootcpucfg_lp_index = 2 +boot2_start_pos = bootcpucfg_start_pos + bootcpucfg_len * (bootcpucfg_m0_index + 1) +boot2_len = 8 +flashcfg_table_start_pos = boot2_start_pos + boot2_len +flashcfg_table_len = 8 +patch_on_read_start_pos = flashcfg_table_start_pos + flashcfg_table_len +patch_on_read_len = 24 +patch_on_jump_start_pos = patch_on_read_start_pos + patch_on_read_len +patch_on_jump_len = 24 +rsvd_start_pos = patch_on_jump_start_pos + patch_on_jump_len +rsvd_len = 4 +crc32_start_pos = rsvd_start_pos + rsvd_len +bootheader_len = crc32_start_pos + 4 +bootheader_cfg_keys = {'magic_code':{'offset':'0', + 'pos':'0', + 'bitlen':'32'}, + 'revision':{'offset':'4', + 'pos':'0', + 'bitlen':'32'}, + 'flashcfg_magic_code':{'offset':'8', + 'pos':'0', + 'bitlen':'32'}, + 'io_mode':{'offset':'12', + 'pos':'0', + 'bitlen':'8'}, + 'cont_read_support':{'offset':'12', + 'pos':'8', + 'bitlen':'8'}, + 'sfctrl_clk_delay':{'offset':'12', + 'pos':'16', + 'bitlen':'8'}, + 'sfctrl_clk_invert':{'offset':'12', + 'pos':'24', + 'bitlen':'8'}, + 'reset_en_cmd':{'offset':'16', + 'pos':'0', + 'bitlen':'8'}, + 'reset_cmd':{'offset':'16', + 'pos':'8', + 'bitlen':'8'}, + 'exit_contread_cmd':{'offset':'16', + 'pos':'16', + 'bitlen':'8'}, + 'exit_contread_cmd_size':{'offset':'16', + 'pos':'24', + 'bitlen':'8'}, + 'jedecid_cmd':{'offset':'20', + 'pos':'0', + 'bitlen':'8'}, + 'jedecid_cmd_dmy_clk':{'offset':'20', + 'pos':'8', + 'bitlen':'8'}, + 'enter_32bits_addr_cmd':{'offset':'20', + 'pos':'16', + 'bitlen':'8'}, + 'exit_32bits_addr_clk':{'offset':'20', + 'pos':'24', + 'bitlen':'8'}, + 'sector_size':{'offset':'24', + 'pos':'0', + 'bitlen':'8'}, + 'mfg_id':{'offset':'24', + 'pos':'8', + 'bitlen':'8'}, + 'page_size':{'offset':'24', + 'pos':'16', + 'bitlen':'16'}, + 'chip_erase_cmd':{'offset':'28', + 'pos':'0', + 'bitlen':'8'}, + 'sector_erase_cmd':{'offset':'28', + 'pos':'8', + 'bitlen':'8'}, + 'blk32k_erase_cmd':{'offset':'28', + 'pos':'16', + 'bitlen':'8'}, + 'blk64k_erase_cmd':{'offset':'28', + 'pos':'24', + 'bitlen':'8'}, + 'write_enable_cmd':{'offset':'32', + 'pos':'0', + 'bitlen':'8'}, + 'page_prog_cmd':{'offset':'32', + 'pos':'8', + 'bitlen':'8'}, + 'qpage_prog_cmd':{'offset':'32', + 'pos':'16', + 'bitlen':'8'}, + 'qual_page_prog_addr_mode':{'offset':'32', + 'pos':'24', + 'bitlen':'8'}, + 'fast_read_cmd':{'offset':'36', + 'pos':'0', + 'bitlen':'8'}, + 'fast_read_dmy_clk':{'offset':'36', + 'pos':'8', + 'bitlen':'8'}, + 'qpi_fast_read_cmd':{'offset':'36', + 'pos':'16', + 'bitlen':'8'}, + 'qpi_fast_read_dmy_clk':{'offset':'36', + 'pos':'24', + 'bitlen':'8'}, + 'fast_read_do_cmd':{'offset':'40', + 'pos':'0', + 'bitlen':'8'}, + 'fast_read_do_dmy_clk':{'offset':'40', + 'pos':'8', + 'bitlen':'8'}, + 'fast_read_dio_cmd':{'offset':'40', + 'pos':'16', + 'bitlen':'8'}, + 'fast_read_dio_dmy_clk':{'offset':'40', + 'pos':'24', + 'bitlen':'8'}, + 'fast_read_qo_cmd':{'offset':'44', + 'pos':'0', + 'bitlen':'8'}, + 'fast_read_qo_dmy_clk':{'offset':'44', + 'pos':'8', + 'bitlen':'8'}, + 'fast_read_qio_cmd':{'offset':'44', + 'pos':'16', + 'bitlen':'8'}, + 'fast_read_qio_dmy_clk':{'offset':'44', + 'pos':'24', + 'bitlen':'8'}, + 'qpi_fast_read_qio_cmd':{'offset':'48', + 'pos':'0', + 'bitlen':'8'}, + 'qpi_fast_read_qio_dmy_clk':{'offset':'48', + 'pos':'8', + 'bitlen':'8'}, + 'qpi_page_prog_cmd':{'offset':'48', + 'pos':'16', + 'bitlen':'8'}, + 'write_vreg_enable_cmd':{'offset':'48', + 'pos':'24', + 'bitlen':'8'}, + 'wel_reg_index':{'offset':'52', + 'pos':'0', + 'bitlen':'8'}, + 'qe_reg_index':{'offset':'52', + 'pos':'8', + 'bitlen':'8'}, + 'busy_reg_index':{'offset':'52', + 'pos':'16', + 'bitlen':'8'}, + 'wel_bit_pos':{'offset':'52', + 'pos':'24', + 'bitlen':'8'}, + 'qe_bit_pos':{'offset':'56', + 'pos':'0', + 'bitlen':'8'}, + 'busy_bit_pos':{'offset':'56', + 'pos':'8', + 'bitlen':'8'}, + 'wel_reg_write_len':{'offset':'56', + 'pos':'16', + 'bitlen':'8'}, + 'wel_reg_read_len':{'offset':'56', + 'pos':'24', + 'bitlen':'8'}, + 'qe_reg_write_len':{'offset':'60', + 'pos':'0', + 'bitlen':'8'}, + 'qe_reg_read_len':{'offset':'60', + 'pos':'8', + 'bitlen':'8'}, + 'release_power_down':{'offset':'60', + 'pos':'16', + 'bitlen':'8'}, + 'busy_reg_read_len':{'offset':'60', + 'pos':'24', + 'bitlen':'8'}, + 'reg_read_cmd0':{'offset':'64', + 'pos':'0', + 'bitlen':'8'}, + 'reg_read_cmd1':{'offset':'64', + 'pos':'8', + 'bitlen':'8'}, + 'reg_write_cmd0':{'offset':'68', + 'pos':'0', + 'bitlen':'8'}, + 'reg_write_cmd1':{'offset':'68', + 'pos':'8', + 'bitlen':'8'}, + 'enter_qpi_cmd':{'offset':'72', + 'pos':'0', + 'bitlen':'8'}, + 'exit_qpi_cmd':{'offset':'72', + 'pos':'8', + 'bitlen':'8'}, + 'cont_read_code':{'offset':'72', + 'pos':'16', + 'bitlen':'8'}, + 'cont_read_exit_code':{'offset':'72', + 'pos':'24', + 'bitlen':'8'}, + 'burst_wrap_cmd':{'offset':'76', + 'pos':'0', + 'bitlen':'8'}, + 'burst_wrap_dmy_clk':{'offset':'76', + 'pos':'8', + 'bitlen':'8'}, + 'burst_wrap_data_mode':{'offset':'76', + 'pos':'16', + 'bitlen':'8'}, + 'burst_wrap_code':{'offset':'76', + 'pos':'24', + 'bitlen':'8'}, + 'de_burst_wrap_cmd':{'offset':'80', + 'pos':'0', + 'bitlen':'8'}, + 'de_burst_wrap_cmd_dmy_clk':{'offset':'80', + 'pos':'8', + 'bitlen':'8'}, + 'de_burst_wrap_code_mode':{'offset':'80', + 'pos':'16', + 'bitlen':'8'}, + 'de_burst_wrap_code':{'offset':'80', + 'pos':'24', + 'bitlen':'8'}, + 'sector_erase_time':{'offset':'84', + 'pos':'0', + 'bitlen':'16'}, + 'blk32k_erase_time':{'offset':'84', + 'pos':'16', + 'bitlen':'16'}, + 'blk64k_erase_time':{'offset':'88', + 'pos':'0', + 'bitlen':'16'}, + 'page_prog_time':{'offset':'88', + 'pos':'16', + 'bitlen':'16'}, + 'chip_erase_time':{'offset':'92', + 'pos':'0', + 'bitlen':'16'}, + 'power_down_delay':{'offset':'92', + 'pos':'16', + 'bitlen':'8'}, + 'qe_data':{'offset':'92', + 'pos':'24', + 'bitlen':'8'}, + 'flashcfg_crc32':{'offset':'96', + 'pos':'0', + 'bitlen':'32'}, + 'clkcfg_magic_code':{'offset':str(int(clock_start_pos) + 0), + 'pos':'0', + 'bitlen':'32'}, + 'xtal_type':{'offset':str(int(clock_start_pos) + 4), + 'pos':'0', + 'bitlen':'8'}, + 'mcu_clk':{'offset':str(int(clock_start_pos) + 4), + 'pos':'8', + 'bitlen':'8'}, + 'mcu_clk_div':{'offset':str(int(clock_start_pos) + 4), + 'pos':'16', + 'bitlen':'8'}, + 'mcu_bclk_div':{'offset':str(int(clock_start_pos) + 4), + 'pos':'24', + 'bitlen':'8'}, + 'mcu_pbclk_div':{'offset':str(int(clock_start_pos) + 8), + 'pos':'0', + 'bitlen':'8'}, + 'emi_clk':{'offset':str(int(clock_start_pos) + 8), + 'pos':'8', + 'bitlen':'8'}, + 'emi_clk_div':{'offset':str(int(clock_start_pos) + 8), + 'pos':'16', + 'bitlen':'8'}, + 'flash_clk_type':{'offset':str(int(clock_start_pos) + 8), + 'pos':'24', + 'bitlen':'8'}, + 'flash_clk_div':{'offset':str(int(clock_start_pos) + 12), + 'pos':'0', + 'bitlen':'8'}, + 'wifipll_pu':{'offset':str(int(clock_start_pos) + 12), + 'pos':'8', + 'bitlen':'8'}, + 'aupll_pu':{'offset':str(int(clock_start_pos) + 12), + 'pos':'16', + 'bitlen':'8'}, + 'rsvd0':{'offset':str(int(clock_start_pos) + 12), + 'pos':'24', + 'bitlen':'8'}, + 'clkcfg_crc32':{'offset':str(int(clock_start_pos) + 16), + 'pos':'0', + 'bitlen':'32'}, + 'sign':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'0', + 'bitlen':'2'}, + 'encrypt_type':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'2', + 'bitlen':'2'}, + 'key_sel':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'4', + 'bitlen':'2'}, + 'xts_mode':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'6', + 'bitlen':'1'}, + 'aes_region_lock':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'7', + 'bitlen':'1'}, + 'no_segment':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'8', + 'bitlen':'1'}, + 'boot2_enable':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'9', + 'bitlen':'1'}, + 'boot2_rollback':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'10', + 'bitlen':'1'}, + 'cpu_master_id':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'11', + 'bitlen':'4'}, + 'notload_in_bootrom':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'15', + 'bitlen':'1'}, + 'crc_ignore':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'16', + 'bitlen':'1'}, + 'hash_ignore':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'17', + 'bitlen':'1'}, + 'power_on_mm':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'18', + 'bitlen':'1'}, + 'em_sel':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'19', + 'bitlen':'3'}, + 'cmds_en':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'22', + 'bitlen':'1'}, + 'cmds_wrap_mode':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'23', + 'bitlen':'2'}, + 'cmds_wrap_len':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'25', + 'bitlen':'4'}, + 'icache_invalid':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'29', + 'bitlen':'1'}, + 'dcache_invalid':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'30', + 'bitlen':'1'}, + 'fpga_halt_release':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'31', + 'bitlen':'1'}, + 'group_image_offset':{'offset':str(int(bootcfg_start_pos) + 4), + 'pos':'0', + 'bitlen':'32'}, + 'aes_region_len':{'offset':str(int(bootcfg_start_pos) + 8), + 'pos':'0', + 'bitlen':'32'}, + 'img_len_cnt':{'offset':str(int(bootcfg_start_pos) + 12), + 'pos':'0', + 'bitlen':'32'}, + 'hash_0':{'offset':str(int(bootcfg_start_pos) + 16), + 'pos':'0', + 'bitlen':'32'}, + 'hash_1':{'offset':str(int(bootcfg_start_pos) + 20), + 'pos':'0', + 'bitlen':'32'}, + 'hash_2':{'offset':str(int(bootcfg_start_pos) + 24), + 'pos':'0', + 'bitlen':'32'}, + 'hash_3':{'offset':str(int(bootcfg_start_pos) + 28), + 'pos':'0', + 'bitlen':'32'}, + 'hash_4':{'offset':str(int(bootcfg_start_pos) + 32), + 'pos':'0', + 'bitlen':'32'}, + 'hash_5':{'offset':str(int(bootcfg_start_pos) + 36), + 'pos':'0', + 'bitlen':'32'}, + 'hash_6':{'offset':str(int(bootcfg_start_pos) + 40), + 'pos':'0', + 'bitlen':'32'}, + 'hash_7':{'offset':str(int(bootcfg_start_pos) + 44), + 'pos':'0', + 'bitlen':'32'}, + 'm0_config_enable':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_m0_index) + 0), + 'pos':'0', + 'bitlen':'8'}, + 'm0_halt_cpu':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_m0_index) + 0), + 'pos':'8', + 'bitlen':'8'}, + 'm0_cache_enable':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_m0_index) + 0), + 'pos':'16', + 'bitlen':'1'}, + 'm0_cache_wa':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_m0_index) + 0), + 'pos':'17', + 'bitlen':'1'}, + 'm0_cache_wb':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_m0_index) + 0), + 'pos':'18', + 'bitlen':'1'}, + 'm0_cache_wt':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_m0_index) + 0), + 'pos':'19', + 'bitlen':'1'}, + 'm0_cache_way_dis':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_m0_index) + 0), + 'pos':'20', + 'bitlen':'4'}, + 'm0_reserved':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_m0_index) + 0), + 'pos':'24', + 'bitlen':'8'}, + 'm0_image_address_offset':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_m0_index) + 4), + 'pos':'0', + 'bitlen':'32'}, + 'm0_boot_entry':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_m0_index) + 8), + 'pos':'0', + 'bitlen':'32'}, + 'm0_msp_val':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_m0_index) + 12), + 'pos':'0', + 'bitlen':'32'}, + 'boot2_pt_table_0':{'offset':str(int(boot2_start_pos) + 0), + 'pos':'0', + 'bitlen':'32'}, + 'boot2_pt_table_1':{'offset':str(int(boot2_start_pos) + 4), + 'pos':'0', + 'bitlen':'32'}, + 'flashCfgTableAddr':{'offset':str(int(flashcfg_table_start_pos) + 0), + 'pos':'0', + 'bitlen':'32'}, + 'flashCfgTableLen':{'offset':str(int(flashcfg_table_start_pos) + 4), + 'pos':'0', + 'bitlen':'32'}, + 'patch_read_addr0':{'offset':str(int(patch_on_read_start_pos) + 0), + 'pos':'0', + 'bitlen':'32'}, + 'patch_read_value0':{'offset':str(int(patch_on_read_start_pos) + 4), + 'pos':'0', + 'bitlen':'32'}, + 'patch_read_addr1':{'offset':str(int(patch_on_read_start_pos) + 8), + 'pos':'0', + 'bitlen':'32'}, + 'patch_read_value1':{'offset':str(int(patch_on_read_start_pos) + 12), + 'pos':'0', + 'bitlen':'32'}, + 'patch_read_addr2':{'offset':str(int(patch_on_read_start_pos) + 16), + 'pos':'0', + 'bitlen':'32'}, + 'patch_read_value2':{'offset':str(int(patch_on_read_start_pos) + 20), + 'pos':'0', + 'bitlen':'32'}, + 'patch_jump_addr0':{'offset':str(int(patch_on_jump_start_pos) + 0), + 'pos':'0', + 'bitlen':'32'}, + 'patch_jump_value0':{'offset':str(int(patch_on_jump_start_pos) + 4), + 'pos':'0', + 'bitlen':'32'}, + 'patch_jump_addr1':{'offset':str(int(patch_on_jump_start_pos) + 8), + 'pos':'0', + 'bitlen':'32'}, + 'patch_jump_value1':{'offset':str(int(patch_on_jump_start_pos) + 12), + 'pos':'0', + 'bitlen':'32'}, + 'patch_jump_addr2':{'offset':str(int(patch_on_jump_start_pos) + 16), + 'pos':'0', + 'bitlen':'32'}, + 'patch_jump_value2':{'offset':str(int(patch_on_jump_start_pos) + 20), + 'pos':'0', + 'bitlen':'32'}, + 'reserved':{'offset':str(int(rsvd_start_pos) + 0), + 'pos':'0', + 'bitlen':'32'}, + 'crc32':{'offset':str(int(crc32_start_pos) + 0), + 'pos':'0', + 'bitlen':'32'}} +# okay decompiling ./libs/base/bl616/bootheader_cfg_keys.pyc diff --git a/libs/base/bl616/chiptype_patch.py b/libs/base/bl616/chiptype_patch.py new file mode 100644 index 0000000..454745e --- /dev/null +++ b/libs/base/bl616/chiptype_patch.py @@ -0,0 +1,10 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/bl616/chiptype_patch.py + + +def img_load_create_predata_before_run_img(): + return bytearray(0) +# okay decompiling ./libs/base/bl616/chiptype_patch.pyc diff --git a/libs/base/bl616/cklink_load_cfg.py b/libs/base/bl616/cklink_load_cfg.py new file mode 100644 index 0000000..071ef25 --- /dev/null +++ b/libs/base/bl616/cklink_load_cfg.py @@ -0,0 +1,12 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/bl616/cklink_load_cfg.py +cklink_shake_hand_addr = '2204BBEC' +cklink_data_addr = '2204CC88' +cklink_load_addr = '22010000' +cklink_core_type = 'RISC-V' +cklink_set_tif = 0 +cklink_run_addr = '22010000' +# okay decompiling ./libs/base/bl616/cklink_load_cfg.pyc diff --git a/libs/base/bl616/flash_select_do.py b/libs/base/bl616/flash_select_do.py new file mode 100644 index 0000000..ba17c64 --- /dev/null +++ b/libs/base/bl616/flash_select_do.py @@ -0,0 +1,147 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/bl616/flash_select_do.py +import os, csv +from re import I +import config as gol +from libs import bflb_utils +from libs.bflb_utils import app_path, conf_sign +from libs.bflb_configobj import BFConfigParser +from libs.base.bl616.bootheader_cfg_keys import bootheader_cfg_keys as flash_cfg_keys + +def get_suitable_file_name(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: + bflb_utils.printf('Flash id duplicate and alternative is:') + for i in range(len(conf_files)): + tmp = conf_files[i].split('.')[0] + bflb_utils.printf('%d:%s' % (i + 1, tmp)) + + return conf_files[i] + if len(conf_files) == 1: + return conf_files[0] + return '' + + +def update_flash_cfg_do(chipname, chiptype, flash_id, file=None, create=False, section=None): + if conf_sign: + cfg_dir = app_path + '/utils/flash/' + chipname + '/' + else: + cfg_dir = app_path + '/utils/flash/' + gol.flash_dict[chipname] + '/' + conf_name = get_suitable_file_name(cfg_dir, flash_id) + value_key = [] + if os.path.isfile(cfg_dir + conf_name) is False: + return False + fp = open(cfg_dir + conf_name, 'r') + for line in fp.readlines(): + value = line.split('=')[0].strip() + if value == '[FLASH_CFG]': + continue + else: + value_key.append(value) + + cfg1 = BFConfigParser() + cfg1.read(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]): + if cfg2.has_option(section, value_key[i]): + tmp_value = cfg1.get('FLASH_CFG', value_key[i]) + bflb_utils.update_cfg(cfg2, section, value_key[i], tmp_value) + + cfg2.write(file, 'w+') + bflb_utils.printf('Update flash cfg finished') + + +def get_supported_flash_do(): + flash_type = [] + return flash_type + + +def get_int_mask(pos, length): + ones = '11111111111111111111111111111111' + zeros = '00000000000000000000000000000000' + mask = ones[0:32 - pos - length] + zeros[0:length] + ones[0:pos] + return int(mask, 2) + + +def create_flashcfg_data_from_cfg(cfg_len, cfgfile): + section = 'FLASH_CFG' + cfg = BFConfigParser() + cfg.read(cfgfile) + data = bytearray(cfg_len) + minOffset = int(flash_cfg_keys.get('io_mode')['offset'], 10) + for key in cfg.options(section): + if flash_cfg_keys.get(key) == None: + bflb_utils.printf(key + ' not exist') + continue + else: + val = cfg.get(section, key) + if val.startswith('0x'): + val = int(val, 16) + else: + val = int(val, 10) + offset = int(flash_cfg_keys.get(key)['offset'], 10) - minOffset + pos = int(flash_cfg_keys.get(key)['pos'], 10) + bitlen = int(flash_cfg_keys.get(key)['bitlen'], 10) + oldval = bflb_utils.bytearray_to_int(bflb_utils.bytearray_reverse(data[offset:offset + 4])) + newval = (oldval & get_int_mask(pos, bitlen)) + (val << pos) + data[offset:offset + 4] = bflb_utils.int_to_4bytearray_l(newval) + + crcarray = bflb_utils.get_crc32_bytearray(data) + data = bflb_utils.int_to_4bytearray_l(1195787078) + data + crcarray + return data + + +def create_flashcfg_table(start_addr): + single_flashcfg_len = 92 + flash_table_list = bytearray(0) + flash_table_data = bytearray(0) + table_file = os.path.join(app_path, 'utils', 'flash', 'bl616', 'flashcfg_list.csv') + with open(table_file, 'r', encoding='utf-8-sig') as csvfile: + table_list = [] + cfgfile_list = [] + reader = csv.DictReader(csvfile) + cnt = 0 + for row in reader: + row_dict = {} + row_dict['jid'] = row.get('flashJedecID', '') + row_dict['cfgfile'] = row.get('configFile', '') + if row_dict['cfgfile'] not in cfgfile_list: + cfgfile_list.append(row_dict['cfgfile']) + else: + table_list.append(row_dict) + cnt += 1 + + table_list_len = 4 + cnt * 8 + 4 + for cfgfile in cfgfile_list: + cfgfile = os.path.join(app_path, 'utils', 'flash', 'bl616', cfgfile) + data = create_flashcfg_data_from_cfg(single_flashcfg_len - 8, cfgfile) + flash_table_data += data + + for dict in table_list: + flash_table_list += bflb_utils.int_to_4bytearray_b(int(dict['jid'] + '00', 16)) + i = 0 + offset = 0 + for cfgfile in cfgfile_list: + if cfgfile == dict['cfgfile']: + offset = start_addr + table_list_len + single_flashcfg_len * i + break + else: + i += 1 + + flash_table_list += bflb_utils.int_to_4bytearray_l(offset) + + crcarray = bflb_utils.get_crc32_bytearray(flash_table_list) + flash_table_list = bflb_utils.int_to_4bytearray_l(1196704582) + flash_table_list + crcarray + return ( + flash_table_list, flash_table_data, len(flash_table_list)) +# okay decompiling ./libs/base/bl616/flash_select_do.pyc diff --git a/libs/base/bl616/img_create_do.py b/libs/base/bl616/img_create_do.py new file mode 100644 index 0000000..8430188 --- /dev/null +++ b/libs/base/bl616/img_create_do.py @@ -0,0 +1,753 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/bl616/img_create_do.py +import os, sys, hashlib, binascii, codecs, ecdsa +from CryptoPlus.Cipher import AES as AES_XTS +from libs import bflb_utils +from libs.bflb_utils import img_create_sha256_data, img_create_encrypt_data +from libs.bflb_configobj import BFConfigParser +from libs.base.bl616.flash_select_do import create_flashcfg_table +from libs.base.bl616.bootheader_cfg_keys import flashcfg_table_start_pos as flashcfg_table_start +from libs.base.bl616.bootheader_cfg_keys import bootcpucfg_start_pos as bootcpucfg_start +from libs.base.bl616.bootheader_cfg_keys import bootcpucfg_len as bootcpucfg_length +from libs.base.bl616.bootheader_cfg_keys import bootcpucfg_m0_index as bootcpucfg_m0_index_number +from libs.base.bl616.bootheader_cfg_keys import bootcpucfg_d0_index as bootcpucfg_d0_index_number +from libs.base.bl616.bootheader_cfg_keys import bootcpucfg_lp_index as bootcpucfg_lp_index_number +from libs.base.bl616.bootheader_cfg_keys import bootcfg_start_pos as bootcfg_start +from libs.base.bl616.bootheader_cfg_keys import bootheader_len as header_len +keyslot0 = 28 +keyslot1 = keyslot0 + 16 +keyslot2 = keyslot1 + 16 +keyslot3 = keyslot2 + 16 +keyslot3_end = keyslot3 + 16 +keyslot4 = 128 +keyslot5 = keyslot4 + 16 +keyslot6 = keyslot5 + 16 +keyslot7 = keyslot6 + 16 +keyslot8 = keyslot7 + 16 +keyslot9 = keyslot8 + 16 +keyslot10 = keyslot9 + 16 +keyslot10_end = keyslot10 + 16 +keyslot11 = keyslot3_end + 16 +keyslot11_end = keyslot11 + 16 +wr_lock_boot_mode = 14 +wr_lock_dbg_pwd = 15 +wr_lock_wifi_mac = 16 +wr_lock_key_slot_0 = 17 +wr_lock_key_slot_1 = 18 +wr_lock_key_slot_2 = 19 +wr_lock_key_slot_3 = 20 +wr_lock_sw_usage_0 = 21 +wr_lock_sw_usage_1 = 22 +wr_lock_sw_usage_2 = 23 +wr_lock_sw_usage_3 = 24 +wr_lock_key_slot_11 = 25 +rd_lock_dbg_pwd = 26 +rd_lock_key_slot_0 = 27 +rd_lock_key_slot_1 = 28 +rd_lock_key_slot_2 = 29 +rd_lock_key_slot_3 = 30 +rd_lock_key_slot_11 = 31 +wr_lock_key_slot_4 = 15 +wr_lock_key_slot_5 = 16 +wr_lock_key_slot_6 = 17 +wr_lock_key_slot_7 = 18 +wr_lock_key_slot_8 = 19 +wr_lock_key_slot_9 = 20 +wr_lock_key_slot_10 = 21 +rd_lock_key_slot_4 = 25 +rd_lock_key_slot_5 = 26 +rd_lock_key_slot_6 = 27 +rd_lock_key_slot_7 = 28 +rd_lock_key_slot_8 = 29 +rd_lock_key_slot_9 = 30 +rd_lock_key_slot_10 = 31 + +def bytearray_data_merge(data1, data2, len): + for i in range(len): + data1[i] |= data2[i] + + return data1 + + +def img_update_efuse_group0(cfg, sign, pk_hash, flash_encryp_type, flash_key, sec_eng_key_sel, sec_eng_key, security=False): + fp = open(cfg.get('Img_Group0_Cfg', 'efuse_file'), 'rb') + efuse_data = bytearray(fp.read()) + bytearray(0) + fp.close() + fp = open(cfg.get('Img_Group0_Cfg', 'efuse_mask_file'), 'rb') + efuse_mask_data = bytearray(fp.read()) + bytearray(0) + fp.close() + mask_4bytes = bytearray.fromhex('FFFFFFFF') + if flash_encryp_type >= 3: + efuse_data[0] |= 3 + else: + efuse_data[0] |= flash_encryp_type + if sign > 0: + efuse_data[92] |= sign << 7 + efuse_mask_data[92] |= 255 + if flash_encryp_type > 0: + efuse_data[0] |= 48 + efuse_mask_data[0] |= 255 + rw_lock0 = 0 + rw_lock1 = 0 + if pk_hash is not None: + efuse_data[keyslot0:keyslot2] = pk_hash + efuse_mask_data[keyslot0:keyslot2] = mask_4bytes * 8 + rw_lock0 |= 1 << wr_lock_key_slot_0 + rw_lock0 |= 1 << wr_lock_key_slot_1 + if flash_key is not None: + if flash_encryp_type == 1: + efuse_data[keyslot2:keyslot3] = flash_key[0:16] + efuse_mask_data[keyslot2:keyslot3] = mask_4bytes * 4 + else: + if flash_encryp_type == 2: + efuse_data[keyslot2:keyslot3_end] = flash_key + efuse_mask_data[keyslot2:keyslot3_end] = mask_4bytes * 8 + rw_lock0 |= 1 << wr_lock_key_slot_3 + rw_lock0 |= 1 << rd_lock_key_slot_3 + else: + if flash_encryp_type == 3: + efuse_data[keyslot2:keyslot3_end] = flash_key + efuse_mask_data[keyslot2:keyslot3_end] = mask_4bytes * 8 + rw_lock0 |= 1 << wr_lock_key_slot_3 + rw_lock0 |= 1 << rd_lock_key_slot_3 + else: + if flash_encryp_type == 4 or flash_encryp_type == 5 or flash_encryp_type == 6: + efuse_data[keyslot2:keyslot3_end] = flash_key + efuse_mask_data[keyslot2:keyslot3_end] = mask_4bytes * 8 + rw_lock0 |= 1 << wr_lock_key_slot_3 + rw_lock0 |= 1 << rd_lock_key_slot_3 + rw_lock0 |= 1 << wr_lock_key_slot_2 + rw_lock0 |= 1 << rd_lock_key_slot_2 + if sec_eng_key is not None: + if flash_encryp_type == 0: + if sec_eng_key_sel == 0: + efuse_data[keyslot2:keyslot3] = sec_eng_key[16:32] + efuse_data[keyslot3:keyslot3_end] = sec_eng_key[0:16] + efuse_mask_data[keyslot2:keyslot3_end] = mask_4bytes * 8 + rw_lock0 |= 1 << wr_lock_key_slot_2 + rw_lock0 |= 1 << wr_lock_key_slot_3 + rw_lock0 |= 1 << rd_lock_key_slot_2 + rw_lock0 |= 1 << rd_lock_key_slot_3 + if sec_eng_key_sel == 1: + efuse_data[keyslot3:keyslot3_end] = sec_eng_key[16:32] + efuse_data[keyslot4:keyslot5] = sec_eng_key[0:16] + efuse_mask_data[keyslot3:keyslot3_end] = mask_4bytes * 4 + efuse_mask_data[keyslot4:keyslot5] = mask_4bytes * 4 + rw_lock0 |= 1 << wr_lock_key_slot_3 + rw_lock1 |= 1 << wr_lock_key_slot_4 + rw_lock0 |= 1 << rd_lock_key_slot_3 + rw_lock1 |= 1 << rd_lock_key_slot_4 + if sec_eng_key_sel == 2: + efuse_data[keyslot4:keyslot5] = sec_eng_key[16:32] + efuse_data[keyslot2:keyslot3] = sec_eng_key[0:16] + efuse_mask_data[keyslot3:keyslot5] = mask_4bytes * 8 + rw_lock1 |= 1 << wr_lock_key_slot_4 + rw_lock0 |= 1 << wr_lock_key_slot_2 + rw_lock1 |= 1 << rd_lock_key_slot_4 + rw_lock0 |= 1 << rd_lock_key_slot_2 + if sec_eng_key_sel == 3: + efuse_data[keyslot4:keyslot5] = sec_eng_key[16:32] + efuse_data[keyslot2:keyslot3] = sec_eng_key[0:16] + efuse_mask_data[keyslot3:keyslot5] = mask_4bytes * 8 + rw_lock1 |= 1 << wr_lock_key_slot_4 + rw_lock0 |= 1 << wr_lock_key_slot_2 + rw_lock1 |= 1 << rd_lock_key_slot_4 + rw_lock0 |= 1 << rd_lock_key_slot_2 + if flash_encryp_type == 1: + if sec_eng_key_sel == 0: + efuse_data[keyslot5:keyslot6] = sec_eng_key[0:16] + efuse_mask_data[keyslot5:keyslot6] = mask_4bytes * 4 + rw_lock1 |= 1 << wr_lock_key_slot_5 + rw_lock1 |= 1 << rd_lock_key_slot_5 + if sec_eng_key_sel == 1: + efuse_data[keyslot4:keyslot5] = sec_eng_key[0:16] + efuse_mask_data[keyslot4:keyslot5] = mask_4bytes * 4 + rw_lock1 |= 1 << wr_lock_key_slot_4 + rw_lock1 |= 1 << rd_lock_key_slot_4 + if sec_eng_key_sel == 2: + if flash_key is not None: + pass + else: + efuse_data[keyslot3:keyslot3_end] = sec_eng_key[0:16] + efuse_mask_data[keyslot3:keyslot3_end] = mask_4bytes * 4 + rw_lock0 |= 1 << wr_lock_key_slot_3 + rw_lock0 |= 1 << rd_lock_key_slot_3 + if sec_eng_key_sel == 3: + if flash_key is not None: + pass + else: + efuse_data[keyslot2:keyslot3] = sec_eng_key[0:16] + efuse_mask_data[keyslot2:keyslot3] = mask_4bytes * 4 + rw_lock0 |= 1 << wr_lock_key_slot_2 + rw_lock0 |= 1 << rd_lock_key_slot_2 + if flash_encryp_type == 2 or flash_encryp_type == 3 or flash_encryp_type == 4 or flash_encryp_type == 5 or flash_encryp_type == 6: + if sec_eng_key_sel == 0: + efuse_data[keyslot6:keyslot7] = sec_eng_key[16:32] + efuse_data[keyslot10:keyslot10_end] = sec_eng_key[0:16] + efuse_mask_data[keyslot6:keyslot7] = mask_4bytes * 4 + efuse_mask_data[keyslot10:keyslot10_end] = mask_4bytes * 4 + rw_lock1 |= 1 << wr_lock_key_slot_6 + rw_lock1 |= 1 << wr_lock_key_slot_10 + rw_lock1 |= 1 << rd_lock_key_slot_6 + rw_lock1 |= 1 << rd_lock_key_slot_10 + if sec_eng_key_sel == 1: + efuse_data[keyslot10:keyslot10_end] = sec_eng_key[16:32] + efuse_data[keyslot6:keyslot7] = sec_eng_key[0:16] + efuse_mask_data[keyslot6:keyslot7] = mask_4bytes * 4 + efuse_mask_data[keyslot10:keyslot10_end] = mask_4bytes * 4 + rw_lock1 |= 1 << wr_lock_key_slot_6 + rw_lock1 |= 1 << wr_lock_key_slot_10 + rw_lock1 |= 1 << rd_lock_key_slot_6 + rw_lock1 |= 1 << rd_lock_key_slot_10 + if sec_eng_key_sel == 2: + if flash_key is not None: + pass + else: + efuse_data[keyslot2:keyslot3] = sec_eng_key[16:32] + efuse_data[keyslot3:keyslot3_end] = sec_eng_key[0:16] + efuse_mask_data[keyslot2:keyslot3_end] = mask_4bytes * 8 + rw_lock0 |= 1 << wr_lock_key_slot_2 + rw_lock0 |= 1 << rd_lock_key_slot_2 + rw_lock0 |= 1 << wr_lock_key_slot_3 + rw_lock0 |= 1 << rd_lock_key_slot_3 + if sec_eng_key_sel == 3: + if flash_key is not None: + pass + else: + efuse_data[keyslot2:keyslot3_end] = sec_eng_key + efuse_mask_data[keyslot2:keyslot3_end] = mask_4bytes * 8 + rw_lock0 |= 1 << wr_lock_key_slot_2 + rw_lock0 |= 1 << rd_lock_key_slot_2 + rw_lock0 |= 1 << wr_lock_key_slot_3 + rw_lock0 |= 1 << rd_lock_key_slot_3 + efuse_data[124:128] = bytearray_data_merge(efuse_data[124:128], bflb_utils.int_to_4bytearray_l(rw_lock0), 4) + efuse_mask_data[124:128] = bytearray_data_merge(efuse_mask_data[124:128], bflb_utils.int_to_4bytearray_l(rw_lock0), 4) + efuse_data[252:256] = bytearray_data_merge(efuse_data[252:256], bflb_utils.int_to_4bytearray_l(rw_lock1), 4) + efuse_mask_data[252:256] = bytearray_data_merge(efuse_mask_data[252:256], bflb_utils.int_to_4bytearray_l(rw_lock1), 4) + if security is True: + bflb_utils.printf('Encrypt efuse data') + security_key, security_iv = bflb_utils.get_security_key() + efuse_data = img_create_encrypt_data(efuse_data, security_key, security_iv, 0) + efuse_data = bytearray(4096) + efuse_data + fp = open(cfg.get('Img_Group0_Cfg', 'efuse_file'), 'wb+') + fp.write(efuse_data) + fp.close() + fp = open(cfg.get('Img_Group0_Cfg', 'efuse_mask_file'), 'wb+') + fp.write(efuse_mask_data) + fp.close() + + +def img_create_get_sign_encrypt_info(bootheader_data): + sign = bootheader_data[bootcfg_start] & 3 + encrypt = bootheader_data[bootcfg_start] >> 2 & 3 + key_sel = bootheader_data[bootcfg_start] >> 4 & 3 + xts_mode = bootheader_data[bootcfg_start] >> 6 & 1 + return ( + sign, encrypt, key_sel, xts_mode) + + +def img_create_get_img_start_addr(bootheader_data): + bootentry = [] + bootentry.append(bflb_utils.bytearray_to_int(bflb_utils.bytearray_reverse(bootheader_data[bootcpucfg_start + bootcpucfg_length * bootcpucfg_m0_index_number + 16:bootcpucfg_start + bootcpucfg_length * bootcpucfg_m0_index_number + 16 + 4]))) + return bootentry + + +def img_create_flash_default_data(length): + datas = bytearray(length) + for i in range(length): + datas[i] = 255 + + return datas + + +def img_get_file_data(files): + datas = [] + for file in files: + if file == 'UNUSED': + datas.append(bytearray(0)) + continue + else: + with open(file, 'rb') as fp: + data = fp.read() + datas.append(data) + + return datas + + +def img_get_largest_addr(addrs, files): + min = 67108863 + maxlen = 0 + datalen = 0 + for i in range(len(addrs)): + if files[i] == 'UNUSED': + continue + else: + addr = addrs[i] & 67108863 + if addr >= maxlen: + maxlen = addr + datalen = os.path.getsize(files[i]) + if addr <= min: + min = addr + + if maxlen == 0: + if datalen == 0: + return (0, 0) + return ( + maxlen + datalen - min, min) + + +def img_get_one_group_img(d_addrs, d_files): + whole_img_len, min = img_get_largest_addr(d_addrs, d_files) + whole_img_len &= 67108863 + whole_img_data = img_create_flash_default_data(whole_img_len) + filedatas = img_get_file_data(d_files) + for i in range(len(d_addrs)): + if d_files[i] == 'UNUSED': + continue + else: + start_addr = d_addrs[i] + start_addr &= 67108863 + start_addr -= min + whole_img_data[start_addr:start_addr + len(filedatas[i])] = filedatas[i] + + return whole_img_data + + +def img_create_get_hash_ignore(bootheader_data): + return bootheader_data[bootcfg_start + 2] >> 1 & 1 + + +def img_create_get_crc_ignore(bootheader_data): + return bootheader_data[bootcfg_start + 2] & 1 + + +def img_create_update_bootheader_if(bootheader_data, hash, seg_cnt): + bootheader_data[bootcfg_start + 12:bootcfg_start + 12 + 4] = bflb_utils.int_to_4bytearray_l(seg_cnt) + sign = bootheader_data[bootcfg_start] & 3 + encrypt = bootheader_data[bootcfg_start] >> 2 & 3 + key_sel = bootheader_data[bootcfg_start] >> 4 & 3 + xts_mode = bootheader_data[bootcfg_start] >> 6 & 1 + if bootheader_data[bootcfg_start + 2] >> 1 & 1 == 1 and sign == 0: + bflb_utils.printf('Hash ignored') + else: + bootheader_data[bootcfg_start + 16:bootcfg_start + 16 + 32] = hash + if bootheader_data[bootcfg_start + 2] & 1 == 1: + bflb_utils.printf('Header crc ignored') + else: + hd_crcarray = bflb_utils.get_crc32_bytearray(bootheader_data[0:header_len - 4]) + bootheader_data[header_len - 4:header_len] = hd_crcarray + bflb_utils.printf('Header crc: ', binascii.hexlify(hd_crcarray)) + return bootheader_data + + +def img_create_update_bootheader(bootheader_data, hash, seg_cnt, flashcfg_table_addr, flashcfg_table_len): + bootheader_data[flashcfg_table_start:flashcfg_table_start + 4] = bflb_utils.int_to_4bytearray_l(flashcfg_table_addr) + bootheader_data[flashcfg_table_start + 4:flashcfg_table_start + 8] = bflb_utils.int_to_4bytearray_l(flashcfg_table_len) + bootheader_data[bootcfg_start + 12:bootcfg_start + 12 + 4] = bflb_utils.int_to_4bytearray_l(seg_cnt) + sign, encrypt, key_sel, xts_mode = img_create_get_sign_encrypt_info(bootheader_data) + if img_create_get_hash_ignore(bootheader_data) == 1 and sign == 0: + bflb_utils.printf('Hash ignored') + else: + bootheader_data[bootcfg_start + 16:bootcfg_start + 16 + 32] = hash + if img_create_get_crc_ignore(bootheader_data) == 1: + bflb_utils.printf('Header crc ignored') + else: + hd_crcarray = bflb_utils.get_crc32_bytearray(bootheader_data[0:header_len - 4]) + bootheader_data[header_len - 4:header_len] = hd_crcarray + bflb_utils.printf('Header crc: ', binascii.hexlify(hd_crcarray)) + return bootheader_data[0:header_len] + + +def img_create_update_segheader(segheader, segdatalen, segdatacrc): + segheader[4:8] = segdatalen + segheader[8:12] = segdatacrc + return segheader + + +def reverse_str_data_unit_number(str_data_unit_number): + """ + high position low data + data unit number:00000280 + storage format: 80020000 + """ + reverse_str = '' + if len(str_data_unit_number) == 8: + str_part1 = str_data_unit_number[0:2] + str_part2 = str_data_unit_number[2:4] + str_part3 = str_data_unit_number[4:6] + str_part4 = str_data_unit_number[6:8] + reverse_str = str_part4 + str_part3 + str_part2 + str_part1 + return reverse_str + + +def reverse_iv(need_reverse_iv_bytearray): + temp_reverse_iv_bytearray = binascii.hexlify(need_reverse_iv_bytearray).decode() + if temp_reverse_iv_bytearray[24:32] != '00000000': + bflb_utils.printf('The lower 4 bytes of IV should be set 0, if set IV is less than 16 bytes, make up 0 for the low 4 bytes of IV ') + sys.exit() + reverse_iv_bytearray = '00000000' + temp_reverse_iv_bytearray[0:24] + return reverse_iv_bytearray + + +def img_create_encrypt_data_xts(data_bytearray, key_bytearray, iv_bytearray, encrypt): + counter = binascii.hexlify(iv_bytearray[4:16]).decode() + data_unit_number = 0 + key = ( + key_bytearray[0:16], key_bytearray[16:32]) + if encrypt == 2 or encrypt == 3: + key = ( + key_bytearray, key_bytearray) + cipher = AES_XTS.new(key, AES_XTS.MODE_XTS) + total_len = len(data_bytearray) + ciphertext = bytearray(0) + deal_len = 0 + while deal_len < total_len: + data_unit_number = str(hex(data_unit_number)).replace('0x', '') + data_unit_number_to_str = str(data_unit_number) + right_justify_str = data_unit_number_to_str.rjust(8, '0') + reverse_data_unit_number_str = reverse_str_data_unit_number(right_justify_str) + tweak = reverse_data_unit_number_str + counter + tweak = bflb_utils.hexstr_to_bytearray('0' * (32 - len(tweak)) + tweak) + if 32 + deal_len <= total_len: + cur_block = data_bytearray[0 + deal_len:32 + deal_len] + ciphertext += cipher.encrypt(cur_block, tweak) + else: + cur_block = data_bytearray[0 + deal_len:16 + deal_len] + bytearray(16) + ciphertext += cipher.encrypt(cur_block, tweak)[0:16] + deal_len += 32 + data_unit_number = int(data_unit_number, 16) + data_unit_number += 1 + + return ciphertext + + +def img_create_sign_data(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() + bflb_utils.printf('Private key: ', binascii.hexlify(sk.to_string())) + bflb_utils.printf('Public key: ', binascii.hexlify(pk_data)) + pk_hash = img_create_sha256_data(pk_data) + bflb_utils.printf('Public key hash=', binascii.hexlify(pk_hash)) + signature = sk.sign(data_bytearray, hashfunc=(hashlib.sha256), sigencode=(ecdsa.util.sigencode_string)) + bflb_utils.printf('Signature=', binascii.hexlify(signature)) + len_array = bflb_utils.int_to_4bytearray_l(len(signature)) + sig_field = len_array + signature + crcarray = bflb_utils.get_crc32_bytearray(sig_field) + return ( + pk_data, pk_hash, sig_field + crcarray) + + +def img_create_read_file_append_crc(file, crc): + fp = open(file, 'rb') + read_data = bytearray(fp.read()) + crcarray = bytearray(0) + if crc: + crcarray = bflb_utils.get_crc32_bytearray(read_data) + fp.close() + return read_data + crcarray + + +def encrypt_loader_bin_do(file, sign, encrypt, temp_encrypt_key, temp_encrypt_iv, publickey_file, privatekey_file): + if encrypt != 0 or sign != 0: + encrypt_key = bytearray(0) + encrypt_iv = bytearray(0) + load_helper_bin_header = bytearray(0) + load_helper_bin_body = bytearray(0) + offset = bootcfg_start + sign_pos = 0 + encrypt_type_pos = 2 + pk_data = bytearray(0) + signature = bytearray(0) + aesiv_data = bytearray(0) + data_tohash = bytearray(0) + with open(file, 'rb') as fp: + load_helper_bin = fp.read() + load_helper_bin_header = load_helper_bin[0:header_len] + load_helper_bin_body = load_helper_bin[header_len:] + if load_helper_bin_header != bytearray(0): + if load_helper_bin_body != bytearray(0): + load_helper_bin_body = bflb_utils.add_to_16(load_helper_bin_body) + if encrypt != 0: + encrypt_key = bflb_utils.hexstr_to_bytearray(temp_encrypt_key) + encrypt_iv = bflb_utils.hexstr_to_bytearray(temp_encrypt_iv) + iv_crcarray = bflb_utils.get_crc32_bytearray(encrypt_iv) + aesiv_data = encrypt_iv + iv_crcarray + data_tohash = data_tohash + aesiv_data + load_helper_bin_body_encrypt = bflb_utils.img_create_encrypt_data(load_helper_bin_body, encrypt_key, encrypt_iv, 0) + else: + load_helper_bin_body_encrypt = load_helper_bin_body + data = bytearray(load_helper_bin_header) + oldval = bflb_utils.bytearray_to_int(bflb_utils.bytearray_reverse(data[offset:offset + 4])) + newval = oldval + if encrypt != 0: + newval = newval | 1 << encrypt_type_pos + if sign != 0: + newval = newval | 1 << sign_pos + data_tohash += load_helper_bin_body_encrypt + pk_data, pk_hash, signature = img_create_sign_data(data_tohash, privatekey_file, publickey_file) + pk_data = pk_data + bflb_utils.get_crc32_bytearray(pk_data) + data[offset:offset + 4] = bflb_utils.int_to_4bytearray_l(newval) + load_helper_bin_header = data + load_helper_bin_encrypt = load_helper_bin_header + pk_data + signature + aesiv_data + load_helper_bin_body_encrypt + hashfun = hashlib.sha256() + hashfun.update(load_helper_bin_body_encrypt) + hash = bflb_utils.hexstr_to_bytearray(hashfun.hexdigest()) + load_helper_bin_data = bytearray(load_helper_bin_encrypt) + load_helper_bin_encrypt = img_create_update_bootheader_if(load_helper_bin_data, hash, 1) + return ( + True, load_helper_bin_encrypt) + return (False, None) + + +def img_creat_process(group_type, flash_img, cfg, security=False): + encrypt_blk_size = 16 + padding = bytearray(encrypt_blk_size) + data_tohash = bytearray(0) + cfg_section = '' + img_update_efuse_fun = img_update_efuse_group0 + cfg_section = 'Img_Group0_Cfg' + 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('|'): + if files: + segdata_file.append(str(files)) + + boot_header_file = cfg.get(cfg_section, 'boot_header_file') + bootheader_data = img_create_read_file_append_crc(boot_header_file, 0) + encrypt = 0 + sign, encrypt, key_sel, xts_mode = img_create_get_sign_encrypt_info(bootheader_data) + boot_entry = img_create_get_img_start_addr(bootheader_data) + aesiv_data = bytearray(0) + pk_data = bytearray(0) + publickey_file = '' + privatekey_file_uecc = '' + if sign != 0: + bflb_utils.printf('Image need sign') + publickey_file = cfg.get(cfg_section, 'publickey_file') + privatekey_file_uecc = cfg.get(cfg_section, 'privatekey_file_uecc') + if encrypt != 0: + bflb_utils.printf('Image need encrypt ', encrypt) + if xts_mode == 1: + bflb_utils.printf('Enable xts mode') + encrypt_key_org = bflb_utils.hexstr_to_bytearray(cfg.get(cfg_section, 'aes_key_org')) + if encrypt == 1: + if xts_mode == 1: + encrypt_key = encrypt_key_org[0:32] + else: + encrypt_key = encrypt_key_org[0:16] + else: + if encrypt == 2: + if xts_mode == 1: + encrypt_key = encrypt_key_org[0:32] + else: + encrypt_key = encrypt_key_org[0:32] + else: + if encrypt == 3: + if xts_mode == 1: + encrypt_key = encrypt_key_org[0:24] + else: + encrypt_key = encrypt_key_org[0:24] + bflb_utils.printf('Key= ', binascii.hexlify(encrypt_key)) + iv_value = cfg.get(cfg_section, 'aes_iv') + if xts_mode == 1: + iv_value = iv_value[24:32] + iv_value[:24] + encrypt_iv = bflb_utils.hexstr_to_bytearray(iv_value) + iv_crcarray = bflb_utils.get_crc32_bytearray(encrypt_iv) + aesiv_data = encrypt_iv + iv_crcarray + data_tohash = data_tohash + aesiv_data + seg_cnt = len(segheader_file) + segdata_cnt = len(segdata_file) + if flash_img == 0: + if seg_cnt != segdata_cnt: + bflb_utils.printf('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: + seg_data = bytearray(0) + if segdata_file[i] != 'UNUSED': + seg_data = img_create_read_file_append_crc(segdata_file[i], 0) + else: + 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 = bflb_utils.get_crc32_bytearray(seg_data) + seg_data_list.append(seg_data) + seg_header = img_create_read_file_append_crc(segheader_file[i], 0) + seg_header = img_create_update_segheader(seg_header, bflb_utils.int_to_4bytearray_l(len(seg_data)), segdata_crcarray) + segheader_crcarray = bflb_utils.get_crc32_bytearray(seg_header) + seg_header = seg_header + segheader_crcarray + seg_header_list.append(seg_header) + i = i + 1 + + i = 0 + cnt = 0 + while i < seg_cnt: + if seg_header_list[i][4:8] != bytearray(4): + data_toencrypt += seg_header_list[i] + data_toencrypt += seg_data_list[i] + cnt += 1 + else: + i += 1 + + seg_cnt = cnt + else: + seg_data = img_get_one_group_img(boot_entry, segdata_file) + 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) + if encrypt != 0: + unencrypt_mfg_data = bytearray(0) + if seg_cnt >= 8192: + if data_toencrypt[4096:4100] == bytearray('0mfg'.encode('utf-8')): + unencrypt_mfg_data = data_toencrypt[4096:8192] + if xts_mode != 0: + data_toencrypt = img_create_encrypt_data_xts(data_toencrypt, encrypt_key, encrypt_iv, encrypt) + else: + data_toencrypt = img_create_encrypt_data(data_toencrypt, encrypt_key, encrypt_iv, flash_img) + if unencrypt_mfg_data != bytearray(0): + data_toencrypt = data_toencrypt[0:4096] + unencrypt_mfg_data + data_toencrypt[8192:] + fw_data = bytearray(0) + data_tohash += data_toencrypt + fw_data = data_toencrypt + hash = img_create_sha256_data(data_tohash) + bflb_utils.printf('Image hash is ', binascii.hexlify(hash)) + 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 + bflb_utils.get_crc32_bytearray(pk_data) + flashCfgAddr = len(bootheader_data + pk_data + signature + aesiv_data) + flashCfgListLen = 0 + flashCfgList = bytearray(0) + flashCfgTable = bytearray(0) + if flash_img == 1: + if bootheader_data[25:26] == b'\xff': + flashCfgList, flashCfgTable, flashCfgListLen = create_flashcfg_table(flashCfgAddr) + bootheader_data = img_create_update_bootheader(bootheader_data, hash, seg_cnt, flashCfgAddr, flashCfgListLen) + if flash_img == 1: + bflb_utils.printf('Write flash img') + bootinfo_file_name = cfg.get(cfg_section, 'bootinfo_file') + fp = open(bootinfo_file_name, 'wb+') + bootinfo = bootheader_data + pk_data + signature + aesiv_data + flashCfgList + flashCfgTable + 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() + fw_data_hash = img_create_sha256_data(fw_data) + fp = open(fw_file_name.replace('.bin', '_withhash.bin'), 'wb+') + fp.write(fw_data + fw_data_hash) + fp.close() + if encrypt != 0: + flash_encrypt_type = 0 + if encrypt == 1: + flash_encrypt_type = 1 + if encrypt == 2: + flash_encrypt_type = 3 + if encrypt == 3: + flash_encrypt_type = 2 + if xts_mode == 1: + flash_encrypt_type += 3 + img_update_efuse_fun(cfg, sign, pk_hash, flash_encrypt_type, encrypt_key + bytearray(32 - len(encrypt_key)), key_sel, None, security) + else: + img_update_efuse_fun(cfg, sign, pk_hash, encrypt, None, key_sel, None, security) + else: + bflb_utils.printf('Write if img') + 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() + if encrypt != 0: + if_encrypt_type = 0 + if encrypt == 1: + if_encrypt_type = 1 + if encrypt == 2: + if_encrypt_type = 3 + if encrypt == 3: + if_encrypt_type = 2 + if xts_mode == 1: + if_encrypt_type += 3 + img_update_efuse_fun(cfg, sign, pk_hash, if_encrypt_type, None, key_sel, encrypt_key + bytearray(32 - len(encrypt_key)), security) + else: + img_update_efuse_fun(cfg, sign, pk_hash, 0, None, key_sel, bytearray(32), security) + return ( + 'OK', data_tohash) + + +def img_create_do(args, img_dir_path=None, config_file=None): + bflb_utils.printf('Image create path: ', img_dir_path) + if config_file is None: + config_file = img_dir_path + '/img_create_cfg.ini' + bflb_utils.printf('Config file: ', config_file) + cfg = BFConfigParser() + cfg.read(config_file) + group_type = 'all' + img_type = 'media' + signer = 'none' + security = False + data_tohash = bytearray(0) + try: + if args.image: + img_type = args.image + if args.group: + group_type = args.group + if args.signer: + signer = args.signer + if args.security: + security = args.security == 'efuse' + except Exception as e: + try: + bflb_utils.printf(e) + finally: + e = None + del e + + if img_type == 'media': + flash_img = 1 + else: + flash_img = 0 + ret0 = ret1 = 'OK' + if group_type == 'group0' or group_type == 'all': + ret0, data_tohash0 = img_creat_process('group0', flash_img, cfg, security) + else: + img_creat_process('', flash_img, cfg, security) + if ret0 != 'OK': + bflb_utils.printf('Fail to create group0 images!') + return + if ret1 != 'OK': + bflb_utils.printf('Fail to create group1 images!') + + +def create_sp_media_image(config, cpu_type=None, security=False): + bflb_utils.printf('========= sp image create =========') + cfg = BFConfigParser() + cfg.read(config) + img_creat_process('group0', 1, cfg, security) + + +if __name__ == '__main__': + data_bytearray = codecs.decode('42464E500100000046434647040101036699FF039F00B7E904EF0001C72052D8060232000B010B013B01BB006B01EB02EB02025000010001010002010101AB01053500000131000038FF20FF77030240770302F02C01B004B0040500FFFF030036C3DD9E5043464704040001010105000101050000010101A612AC86000144650020000000000000503100007A6345494BCABEC7307FD8F8396729EB67DDC8C63B7AD69B797B08564E982A8701000000000000000000000000000000000000D80000000000010000000000000000000000200100000001D80000000000010000000000000000000000200200000002580000000000010000000000000000000000200300000003580000000000010000D0C57503C09E750300200400000004580000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000935F92BB', 'hex') + key_bytearray = codecs.decode('fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0000102030405060708090a0b0c0d0e0f', 'hex') + need_reverse_iv_bytearray = codecs.decode('01000000000000000000000000000000', 'hex') + iv_bytearray = codecs.decode(reverse_iv(need_reverse_iv_bytearray), 'hex') + img_create_encrypt_data_xts(data_bytearray, key_bytearray, iv_bytearray, 0) +# okay decompiling ./libs/base/bl616/img_create_do.pyc diff --git a/libs/base/bl616/jlink_load_cfg.py b/libs/base/bl616/jlink_load_cfg.py new file mode 100644 index 0000000..99b133f --- /dev/null +++ b/libs/base/bl616/jlink_load_cfg.py @@ -0,0 +1,12 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/bl616/jlink_load_cfg.py +jlink_shake_hand_addr = '4201BFF0' +jlink_data_addr = '4201C000' +jlink_load_addr = '22010000' +jlink_core_type = 'RISC-V' +jlink_set_tif = 0 +jlink_run_addr = '22010000' +# okay decompiling ./libs/base/bl616/jlink_load_cfg.pyc diff --git a/libs/base/bl616/openocd_load_cfg.py b/libs/base/bl616/openocd_load_cfg.py new file mode 100644 index 0000000..e46ddf0 --- /dev/null +++ b/libs/base/bl616/openocd_load_cfg.py @@ -0,0 +1,12 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/bl616/openocd_load_cfg.py +openocd_shake_hand_addr = '4201BFF0' +openocd_data_addr = '4201C000' +openocd_load_addr = '22010000' +openocd_core_type = 'RISC-V' +openocd_set_tif = 0 +openocd_run_addr = '22010000' +# okay decompiling ./libs/base/bl616/openocd_load_cfg.pyc diff --git a/libs/base/bl702/bootheader_cfg_keys.py b/libs/base/bl702/bootheader_cfg_keys.py new file mode 100644 index 0000000..395032b --- /dev/null +++ b/libs/base/bl702/bootheader_cfg_keys.py @@ -0,0 +1,343 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/bl702/bootheader_cfg_keys.py +bootheader_len = 176 +bootheader_cfg_keys = {'magic_code':{'offset':'0', + 'pos':'0', + 'bitlen':'32'}, + 'revision':{'offset':'4', + 'pos':'0', + 'bitlen':'32'}, + 'flashcfg_magic_code':{'offset':'8', + 'pos':'0', + 'bitlen':'32'}, + 'io_mode':{'offset':'12', + 'pos':'0', + 'bitlen':'8'}, + 'cont_read_support':{'offset':'12', + 'pos':'8', + 'bitlen':'8'}, + 'sfctrl_clk_delay':{'offset':'12', + 'pos':'16', + 'bitlen':'8'}, + 'sfctrl_clk_invert':{'offset':'12', + 'pos':'24', + 'bitlen':'8'}, + 'reset_en_cmd':{'offset':'16', + 'pos':'0', + 'bitlen':'8'}, + 'reset_cmd':{'offset':'16', + 'pos':'8', + 'bitlen':'8'}, + 'exit_contread_cmd':{'offset':'16', + 'pos':'16', + 'bitlen':'8'}, + 'exit_contread_cmd_size':{'offset':'16', + 'pos':'24', + 'bitlen':'8'}, + 'jedecid_cmd':{'offset':'20', + 'pos':'0', + 'bitlen':'8'}, + 'jedecid_cmd_dmy_clk':{'offset':'20', + 'pos':'8', + 'bitlen':'8'}, + 'qpi_jedecid_cmd':{'offset':'20', + 'pos':'16', + 'bitlen':'8'}, + 'qpi_jedecid_dmy_clk':{'offset':'20', + 'pos':'24', + 'bitlen':'8'}, + 'sector_size':{'offset':'24', + 'pos':'0', + 'bitlen':'8'}, + 'mfg_id':{'offset':'24', + 'pos':'8', + 'bitlen':'8'}, + 'page_size':{'offset':'24', + 'pos':'16', + 'bitlen':'16'}, + 'chip_erase_cmd':{'offset':'28', + 'pos':'0', + 'bitlen':'8'}, + 'sector_erase_cmd':{'offset':'28', + 'pos':'8', + 'bitlen':'8'}, + 'blk32k_erase_cmd':{'offset':'28', + 'pos':'16', + 'bitlen':'8'}, + 'blk64k_erase_cmd':{'offset':'28', + 'pos':'24', + 'bitlen':'8'}, + 'write_enable_cmd':{'offset':'32', + 'pos':'0', + 'bitlen':'8'}, + 'page_prog_cmd':{'offset':'32', + 'pos':'8', + 'bitlen':'8'}, + 'qpage_prog_cmd':{'offset':'32', + 'pos':'16', + 'bitlen':'8'}, + 'qual_page_prog_addr_mode':{'offset':'32', + 'pos':'24', + 'bitlen':'8'}, + 'fast_read_cmd':{'offset':'36', + 'pos':'0', + 'bitlen':'8'}, + 'fast_read_dmy_clk':{'offset':'36', + 'pos':'8', + 'bitlen':'8'}, + 'qpi_fast_read_cmd':{'offset':'36', + 'pos':'16', + 'bitlen':'8'}, + 'qpi_fast_read_dmy_clk':{'offset':'36', + 'pos':'24', + 'bitlen':'8'}, + 'fast_read_do_cmd':{'offset':'40', + 'pos':'0', + 'bitlen':'8'}, + 'fast_read_do_dmy_clk':{'offset':'40', + 'pos':'8', + 'bitlen':'8'}, + 'fast_read_dio_cmd':{'offset':'40', + 'pos':'16', + 'bitlen':'8'}, + 'fast_read_dio_dmy_clk':{'offset':'40', + 'pos':'24', + 'bitlen':'8'}, + 'fast_read_qo_cmd':{'offset':'44', + 'pos':'0', + 'bitlen':'8'}, + 'fast_read_qo_dmy_clk':{'offset':'44', + 'pos':'8', + 'bitlen':'8'}, + 'fast_read_qio_cmd':{'offset':'44', + 'pos':'16', + 'bitlen':'8'}, + 'fast_read_qio_dmy_clk':{'offset':'44', + 'pos':'24', + 'bitlen':'8'}, + 'qpi_fast_read_qio_cmd':{'offset':'48', + 'pos':'0', + 'bitlen':'8'}, + 'qpi_fast_read_qio_dmy_clk':{'offset':'48', + 'pos':'8', + 'bitlen':'8'}, + 'qpi_page_prog_cmd':{'offset':'48', + 'pos':'16', + 'bitlen':'8'}, + 'write_vreg_enable_cmd':{'offset':'48', + 'pos':'24', + 'bitlen':'8'}, + 'wel_reg_index':{'offset':'52', + 'pos':'0', + 'bitlen':'8'}, + 'qe_reg_index':{'offset':'52', + 'pos':'8', + 'bitlen':'8'}, + 'busy_reg_index':{'offset':'52', + 'pos':'16', + 'bitlen':'8'}, + 'wel_bit_pos':{'offset':'52', + 'pos':'24', + 'bitlen':'8'}, + 'qe_bit_pos':{'offset':'56', + 'pos':'0', + 'bitlen':'8'}, + 'busy_bit_pos':{'offset':'56', + 'pos':'8', + 'bitlen':'8'}, + 'wel_reg_write_len':{'offset':'56', + 'pos':'16', + 'bitlen':'8'}, + 'wel_reg_read_len':{'offset':'56', + 'pos':'24', + 'bitlen':'8'}, + 'qe_reg_write_len':{'offset':'60', + 'pos':'0', + 'bitlen':'8'}, + 'qe_reg_read_len':{'offset':'60', + 'pos':'8', + 'bitlen':'8'}, + 'release_power_down':{'offset':'60', + 'pos':'16', + 'bitlen':'8'}, + 'busy_reg_read_len':{'offset':'60', + 'pos':'24', + 'bitlen':'8'}, + 'reg_read_cmd0':{'offset':'64', + 'pos':'0', + 'bitlen':'8'}, + 'reg_read_cmd1':{'offset':'64', + 'pos':'8', + 'bitlen':'8'}, + 'reg_write_cmd0':{'offset':'68', + 'pos':'0', + 'bitlen':'8'}, + 'reg_write_cmd1':{'offset':'68', + 'pos':'8', + 'bitlen':'8'}, + 'enter_qpi_cmd':{'offset':'72', + 'pos':'0', + 'bitlen':'8'}, + 'exit_qpi_cmd':{'offset':'72', + 'pos':'8', + 'bitlen':'8'}, + 'cont_read_code':{'offset':'72', + 'pos':'16', + 'bitlen':'8'}, + 'cont_read_exit_code':{'offset':'72', + 'pos':'24', + 'bitlen':'8'}, + 'burst_wrap_cmd':{'offset':'76', + 'pos':'0', + 'bitlen':'8'}, + 'burst_wrap_dmy_clk':{'offset':'76', + 'pos':'8', + 'bitlen':'8'}, + 'burst_wrap_data_mode':{'offset':'76', + 'pos':'16', + 'bitlen':'8'}, + 'burst_wrap_code':{'offset':'76', + 'pos':'24', + 'bitlen':'8'}, + 'de_burst_wrap_cmd':{'offset':'80', + 'pos':'0', + 'bitlen':'8'}, + 'de_burst_wrap_cmd_dmy_clk':{'offset':'80', + 'pos':'8', + 'bitlen':'8'}, + 'de_burst_wrap_code_mode':{'offset':'80', + 'pos':'16', + 'bitlen':'8'}, + 'de_burst_wrap_code':{'offset':'80', + 'pos':'24', + 'bitlen':'8'}, + 'sector_erase_time':{'offset':'84', + 'pos':'0', + 'bitlen':'16'}, + 'blk32k_erase_time':{'offset':'84', + 'pos':'16', + 'bitlen':'16'}, + 'blk64k_erase_time':{'offset':'88', + 'pos':'0', + 'bitlen':'16'}, + 'page_prog_time':{'offset':'88', + 'pos':'16', + 'bitlen':'16'}, + 'chip_erase_time':{'offset':'92', + 'pos':'0', + 'bitlen':'16'}, + 'power_down_delay':{'offset':'92', + 'pos':'16', + 'bitlen':'8'}, + 'qe_data':{'offset':'92', + 'pos':'24', + 'bitlen':'8'}, + 'flashcfg_crc32':{'offset':'96', + 'pos':'0', + 'bitlen':'32'}, + 'clkcfg_magic_code':{'offset':'100', + 'pos':'0', + 'bitlen':'32'}, + 'xtal_type':{'offset':'104', + 'pos':'0', + 'bitlen':'8'}, + 'pll_clk':{'offset':'104', + 'pos':'8', + 'bitlen':'8'}, + 'hclk_div':{'offset':'104', + 'pos':'16', + 'bitlen':'8'}, + 'bclk_div':{'offset':'104', + 'pos':'24', + 'bitlen':'8'}, + 'flash_clk_type':{'offset':'108', + 'pos':'0', + 'bitlen':'8'}, + 'flash_clk_div':{'offset':'108', + 'pos':'8', + 'bitlen':'8'}, + 'clkcfg_crc32':{'offset':'112', + 'pos':'0', + 'bitlen':'32'}, + 'sign':{'offset':'116', + 'pos':'0', + 'bitlen':'2'}, + 'encrypt_type':{'offset':'116', + 'pos':'2', + 'bitlen':'2'}, + 'key_sel':{'offset':'116', + 'pos':'4', + 'bitlen':'2'}, + 'no_segment':{'offset':'116', + 'pos':'8', + 'bitlen':'1'}, + 'cache_enable':{'offset':'116', + 'pos':'9', + 'bitlen':'1'}, + 'notload_in_bootrom':{'offset':'116', + 'pos':'10', + 'bitlen':'1'}, + 'aes_region_lock':{'offset':'116', + 'pos':'11', + 'bitlen':'1'}, + 'cache_way_disable':{'offset':'116', + 'pos':'12', + 'bitlen':'4'}, + 'crc_ignore':{'offset':'116', + 'pos':'16', + 'bitlen':'1'}, + 'hash_ignore':{'offset':'116', + 'pos':'17', + 'bitlen':'1'}, + 'boot2_enable':{'offset':'116', + 'pos':'19', + 'bitlen':'1'}, + 'boot2_rollback':{'offset':'116', + 'pos':'20', + 'bitlen':'1'}, + 'img_len':{'offset':'120', + 'pos':'0', + 'bitlen':'32'}, + 'bootentry':{'offset':'124', + 'pos':'0', + 'bitlen':'32'}, + 'img_start':{'offset':'128', + 'pos':'0', + 'bitlen':'32'}, + 'hash_0':{'offset':'132', + 'pos':'0', + 'bitlen':'32'}, + 'hash_1':{'offset':'136', + 'pos':'0', + 'bitlen':'32'}, + 'hash_2':{'offset':'140', + 'pos':'0', + 'bitlen':'32'}, + 'hash_3':{'offset':'144', + 'pos':'0', + 'bitlen':'32'}, + 'hash_4':{'offset':'148', + 'pos':'0', + 'bitlen':'32'}, + 'hash_5':{'offset':'152', + 'pos':'0', + 'bitlen':'32'}, + 'hash_6':{'offset':'156', + 'pos':'0', + 'bitlen':'32'}, + 'hash_7':{'offset':'160', + 'pos':'0', + 'bitlen':'32'}, + 'boot2_pt_table_0':{'offset':'164', + 'pos':'0', + 'bitlen':'32'}, + 'boot2_pt_table_1':{'offset':'168', + 'pos':'0', + 'bitlen':'32'}, + 'crc32':{'offset':'172', + 'pos':'0', + 'bitlen':'32'}} +# okay decompiling ./libs/base/bl702/bootheader_cfg_keys.pyc diff --git a/libs/base/bl702/chiptype_patch.py b/libs/base/bl702/chiptype_patch.py new file mode 100644 index 0000000..09ea6da --- /dev/null +++ b/libs/base/bl702/chiptype_patch.py @@ -0,0 +1,62 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/bl702/chiptype_patch.py + + +def img_load_create_predata_before_run_img(): + pre_data = bytearray(12) + pre_data[0] = 80 + pre_data[1] = 0 + pre_data[2] = 8 + pre_data[3] = 0 + pre_data[4] = 0 + pre_data[5] = 241 + pre_data[6] = 0 + pre_data[7] = 64 + pre_data[8] = 69 + pre_data[9] = 72 + pre_data[10] = 66 + pre_data[11] = 78 + pre_data2 = bytearray(12) + pre_data2[0] = 80 + pre_data2[1] = 0 + pre_data2[2] = 8 + pre_data2[3] = 0 + pre_data2[4] = 4 + pre_data2[5] = 241 + pre_data2[6] = 0 + pre_data2[7] = 64 + pre_data2[8] = 0 + pre_data2[9] = 0 + pre_data2[10] = 1 + pre_data2[11] = 34 + pre_data3 = bytearray(12) + pre_data3[0] = 80 + pre_data3[1] = 0 + pre_data3[2] = 8 + pre_data3[3] = 0 + pre_data3[4] = 24 + pre_data3[5] = 0 + pre_data3[6] = 0 + pre_data3[7] = 64 + pre_data3[8] = 0 + pre_data3[9] = 0 + pre_data3[10] = 0 + pre_data3[11] = 0 + pre_data4 = bytearray(12) + pre_data4[0] = 80 + pre_data4[1] = 0 + pre_data4[2] = 8 + pre_data4[3] = 0 + pre_data4[4] = 24 + pre_data4[5] = 0 + pre_data4[6] = 0 + pre_data4[7] = 64 + pre_data4[8] = 2 + pre_data4[9] = 0 + pre_data4[10] = 0 + pre_data4[11] = 0 + return pre_data + pre_data2 + pre_data3 + pre_data4 +# okay decompiling ./libs/base/bl702/chiptype_patch.pyc diff --git a/libs/base/bl702/cklink_load_cfg.py b/libs/base/bl702/cklink_load_cfg.py new file mode 100644 index 0000000..6fd0d38 --- /dev/null +++ b/libs/base/bl702/cklink_load_cfg.py @@ -0,0 +1,12 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/bl702/cklink_load_cfg.py +cklink_shake_hand_addr = '4202BFF0' +cklink_data_addr = '4202C000' +cklink_load_addr = '22010000' +cklink_core_type = 'RISC-V' +cklink_set_tif = 0 +cklink_run_addr = '22010000' +# okay decompiling ./libs/base/bl702/cklink_load_cfg.pyc diff --git a/libs/base/bl702/flash_select_do.py b/libs/base/bl702/flash_select_do.py new file mode 100644 index 0000000..bd7cf8d --- /dev/null +++ b/libs/base/bl702/flash_select_do.py @@ -0,0 +1,64 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/bl702/flash_select_do.py +import os, config as gol +from libs import bflb_utils +from libs.bflb_utils import app_path, conf_sign +from libs.bflb_configobj import BFConfigParser + +def get_suitable_file_name(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: + bflb_utils.printf('Flash id duplicate and alternative is:') + for i in range(len(conf_files)): + tmp = conf_files[i].split('.')[0] + bflb_utils.printf('%d:%s' % (i + 1, tmp)) + + return conf_files[i] + if len(conf_files) == 1: + return conf_files[0] + return '' + + +def update_flash_cfg_do(chipname, chiptype, flash_id, file=None, create=False, section=None): + if conf_sign: + cfg_dir = app_path + '/utils/flash/' + chipname + '/' + else: + cfg_dir = app_path + '/utils/flash/' + gol.flash_dict[chipname] + '/' + conf_name = get_suitable_file_name(cfg_dir, flash_id) + value_key = [] + if os.path.isfile(cfg_dir + conf_name) is False: + return False + fp = open(cfg_dir + conf_name, 'r') + for line in fp.readlines(): + value = line.split('=')[0].strip() + if value == '[FLASH_CFG]': + continue + else: + value_key.append(value) + + cfg1 = BFConfigParser() + cfg1.read(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]): + if cfg2.has_option(section, value_key[i]): + tmp_value = cfg1.get('FLASH_CFG', value_key[i]) + bflb_utils.update_cfg(cfg2, section, value_key[i], tmp_value) + + cfg2.write(file, 'w+') + bflb_utils.printf('Update flash cfg finished') + + +def get_supported_flash_do(): + flash_type = [] + return flash_type +# okay decompiling ./libs/base/bl702/flash_select_do.pyc diff --git a/libs/base/bl702/img_create_do.py b/libs/base/bl702/img_create_do.py new file mode 100644 index 0000000..3fa087c --- /dev/null +++ b/libs/base/bl702/img_create_do.py @@ -0,0 +1,428 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/bl702/img_create_do.py +import hashlib, binascii, ecdsa +from libs import bflb_utils +from libs.bflb_utils import img_create_sha256_data, img_create_encrypt_data +from libs.bflb_configobj import BFConfigParser +from libs.base.bl702.bootheader_cfg_keys import bootheader_len as header_len +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 + +def img_update_efuse(cfg, sign, pk_hash, flash_encryp_type, flash_key, sec_eng_key_sel, sec_eng_key, security=False): + 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] |= 128 + efuse_data[0] |= 48 + efuse_mask_data[0] |= 255 + rw_lock = 0 + if pk_hash is not 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 is not None: + if flash_encryp_type == 1: + efuse_data[keyslot2:keyslot3] = flash_key[0:16] + efuse_mask_data[keyslot2:keyslot3] = mask_4bytes * 4 + else: + if flash_encryp_type == 2: + efuse_data[keyslot2:keyslot4] = flash_key + efuse_mask_data[keyslot2:keyslot4] = mask_4bytes * 8 + rw_lock |= 1 << wr_lock_key_slot_3 + rw_lock |= 1 << rd_lock_key_slot_3 + else: + if flash_encryp_type == 3: + efuse_data[keyslot2:keyslot4] = flash_key + efuse_mask_data[keyslot2:keyslot4] = mask_4bytes * 8 + rw_lock |= 1 << wr_lock_key_slot_3 + rw_lock |= 1 << rd_lock_key_slot_3 + rw_lock |= 1 << wr_lock_key_slot_2 + rw_lock |= 1 << rd_lock_key_slot_2 + if sec_eng_key is not None: + if flash_encryp_type == 0: + if sec_eng_key_sel == 0: + efuse_data[keyslot3:keyslot4] = sec_eng_key[0:16] + efuse_mask_data[keyslot3:keyslot4] = mask_4bytes * 4 + rw_lock |= 1 << wr_lock_key_slot_3 + rw_lock |= 1 << rd_lock_key_slot_3 + if sec_eng_key_sel == 1: + efuse_data[keyslot2:keyslot3] = sec_eng_key[0:16] + efuse_mask_data[keyslot2:keyslot3] = mask_4bytes * 4 + rw_lock |= 1 << wr_lock_key_slot_2 + rw_lock |= 1 << rd_lock_key_slot_2 + if flash_encryp_type == 1: + if sec_eng_key_sel == 0: + efuse_data[keyslot5:keyslot6] = sec_eng_key[0:16] + efuse_mask_data[keyslot5:keyslot6] = mask_4bytes * 4 + rw_lock |= 1 << wr_lock_key_slot_5_l + rw_lock |= 1 << wr_lock_key_slot_5_h + rw_lock |= 1 << rd_lock_key_slot_5 + 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 + efuse_data[124:128] = bflb_utils.int_to_4bytearray_l(rw_lock) + efuse_mask_data[124:128] = bflb_utils.int_to_4bytearray_l(rw_lock) + if security is True: + bflb_utils.printf('Encrypt efuse data') + security_key, security_iv = bflb_utils.get_security_key() + efuse_data = img_create_encrypt_data(efuse_data, security_key, security_iv, 0) + efuse_data = bytearray(4096) + efuse_data + 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() + + +def img_create_get_sign_encrypt_info(bootheader_data): + sign = bootheader_data[116] & 3 + encrypt = bootheader_data[116] >> 2 & 3 + key_sel = bootheader_data[116] >> 4 & 3 + return ( + sign, encrypt, key_sel) + + +def img_create_get_hash_ignore(bootheader_data): + return bootheader_data[118] >> 1 & 1 + + +def img_create_get_crc_ignore(bootheader_data): + return bootheader_data[118] & 1 + + +def img_create_update_bootheader_if(bootheader_data, hash, seg_cnt): + bootheader_data[120:124] = bflb_utils.int_to_4bytearray_l(seg_cnt) + sign = bootheader_data[116] & 3 + encrypt = bootheader_data[116] >> 2 & 3 + key_sel = bootheader_data[116] >> 4 & 3 + if bootheader_data[118] >> 1 & 1 == 1 and sign == 0: + bflb_utils.printf('Hash ignored') + else: + bootheader_data[132:164] = hash + if bootheader_data[118] & 1 == 1: + bflb_utils.printf('Header crc ignored') + else: + hd_crcarray = bflb_utils.get_crc32_bytearray(bootheader_data[0:header_len - 4]) + bootheader_data[header_len - 4:header_len] = hd_crcarray + bflb_utils.printf('Header crc: ', binascii.hexlify(hd_crcarray)) + return bootheader_data + + +def img_create_update_bootheader(bootheader_data, hash, seg_cnt): + bootheader_data[120:124] = bflb_utils.int_to_4bytearray_l(seg_cnt) + sign, encrypt, key_sel = img_create_get_sign_encrypt_info(bootheader_data) + if img_create_get_hash_ignore(bootheader_data) == 1 and sign == 0: + bflb_utils.printf('Hash ignored') + else: + bootheader_data[132:164] = hash + if img_create_get_crc_ignore(bootheader_data) == 1: + bflb_utils.printf('Header crc ignored') + else: + hd_crcarray = bflb_utils.get_crc32_bytearray(bootheader_data[0:header_len - 4]) + bootheader_data[header_len - 4:header_len] = hd_crcarray + bflb_utils.printf('Header crc: ', binascii.hexlify(hd_crcarray)) + return bootheader_data[0:header_len] + + +def img_create_update_segheader(segheader, segdatalen, segdatacrc): + segheader[4:8] = segdatalen + segheader[8:12] = segdatacrc + return segheader + + +def img_create_sign_data(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() + bflb_utils.printf('Private key: ', binascii.hexlify(sk.to_string())) + bflb_utils.printf('Public key: ', binascii.hexlify(pk_data)) + pk_hash = img_create_sha256_data(pk_data) + bflb_utils.printf('Public key hash=', binascii.hexlify(pk_hash)) + signature = sk.sign(data_bytearray, hashfunc=(hashlib.sha256), sigencode=(ecdsa.util.sigencode_string)) + bflb_utils.printf('Signature=', binascii.hexlify(signature)) + len_array = bflb_utils.int_to_4bytearray_l(len(signature)) + sig_field = len_array + signature + crcarray = bflb_utils.get_crc32_bytearray(sig_field) + return ( + pk_data, pk_hash, sig_field + crcarray) + + +def img_create_read_file_append_crc(file, crc): + fp = open(file, 'rb') + read_data = bytearray(fp.read()) + crcarray = bytearray(0) + if crc: + crcarray = bflb_utils.get_crc32_bytearray(read_data) + fp.close() + return read_data + crcarray + + +def encrypt_loader_bin_do(file, sign, encrypt, temp_encrypt_key, temp_encrypt_iv, publickey_file, privatekey_file): + if encrypt != 0 or sign != 0: + encrypt_key = bytearray(0) + encrypt_iv = bytearray(0) + load_helper_bin_header = bytearray(0) + load_helper_bin_body = bytearray(0) + offset = 116 + sign_pos = 0 + encrypt_type_pos = 2 + key_sel_pos = 4 + pk_data = bytearray(0) + signature = bytearray(0) + aesiv_data = bytearray(0) + data_tohash = bytearray(0) + with open(file, 'rb') as fp: + load_helper_bin = fp.read() + load_helper_bin_header = load_helper_bin[0:header_len] + load_helper_bin_body = load_helper_bin[header_len:] + if load_helper_bin_header != bytearray(0): + if load_helper_bin_body != bytearray(0): + load_helper_bin_body = bflb_utils.add_to_16(load_helper_bin_body) + if encrypt != 0: + encrypt_key = bflb_utils.hexstr_to_bytearray(temp_encrypt_key) + encrypt_iv = bflb_utils.hexstr_to_bytearray(temp_encrypt_iv) + iv_crcarray = bflb_utils.get_crc32_bytearray(encrypt_iv) + aesiv_data = encrypt_iv + iv_crcarray + data_tohash = data_tohash + aesiv_data + load_helper_bin_body_encrypt = bflb_utils.img_create_encrypt_data(load_helper_bin_body, encrypt_key, encrypt_iv, 0) + else: + load_helper_bin_body_encrypt = load_helper_bin_body + data = bytearray(load_helper_bin_header) + oldval = bflb_utils.bytearray_to_int(bflb_utils.bytearray_reverse(data[offset:offset + 4])) + newval = oldval + if encrypt != 0: + newval = newval | 1 << encrypt_type_pos + newval = newval | 1 << key_sel_pos + if sign != 0: + newval = newval | 1 << sign_pos + data_tohash += load_helper_bin_body_encrypt + pk_data, pk_hash, signature = img_create_sign_data(data_tohash, privatekey_file, publickey_file) + pk_data = pk_data + bflb_utils.get_crc32_bytearray(pk_data) + data[offset:offset + 4] = bflb_utils.int_to_4bytearray_l(newval) + load_helper_bin_header = data + load_helper_bin_encrypt = load_helper_bin_header + pk_data + signature + aesiv_data + load_helper_bin_body_encrypt + hashfun = hashlib.sha256() + hashfun.update(data_tohash) + hash = bflb_utils.hexstr_to_bytearray(hashfun.hexdigest()) + load_helper_bin_data = bytearray(load_helper_bin_encrypt) + load_helper_bin_encrypt = img_create_update_bootheader_if(load_helper_bin_data, hash, 1) + return ( + True, load_helper_bin_encrypt) + return (False, None) + + +def img_creat_process(flash_img, cfg, security=False): + encrypt_blk_size = 16 + padding = bytearray(encrypt_blk_size) + data_tohash = bytearray(0) + cfg_section = 'Img_Cfg' + 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 + + boot_header_file = cfg.get(cfg_section, 'boot_header_file') + bootheader_data = img_create_read_file_append_crc(boot_header_file, 0) + encrypt = 0 + sign, encrypt, key_sel = img_create_get_sign_encrypt_info(bootheader_data) + aesiv_data = bytearray(0) + pk_data = bytearray(0) + if sign != 0: + bflb_utils.printf('Image need sign') + publickey_file = cfg.get(cfg_section, 'publickey_file') + privatekey_file_uecc = cfg.get(cfg_section, 'privatekey_file_uecc') + if encrypt != 0: + bflb_utils.printf('Image need encrypt ', encrypt) + encrypt_key_org = bflb_utils.hexstr_to_bytearray(cfg.get(cfg_section, 'aes_key_org')) + if encrypt == 1: + encrypt_key = encrypt_key_org[0:16] + else: + if encrypt == 2: + encrypt_key = encrypt_key_org[0:32] + else: + if encrypt == 3: + encrypt_key = encrypt_key_org[0:24] + bflb_utils.printf('Key= ', binascii.hexlify(encrypt_key)) + encrypt_iv = bflb_utils.hexstr_to_bytearray(cfg.get(cfg_section, 'aes_iv')) + iv_crcarray = bflb_utils.get_crc32_bytearray(encrypt_iv) + aesiv_data = encrypt_iv + iv_crcarray + data_tohash = data_tohash + aesiv_data + seg_cnt = len(segheader_file) + if flash_img == 0: + if seg_cnt != len(segdata_file): + bflb_utils.printf('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: + seg_data = 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] + else: + segdata_crcarray = bflb_utils.get_crc32_bytearray(seg_data) + seg_data_list.append(seg_data) + seg_header = img_create_read_file_append_crc(segheader_file[i], 0) + seg_header = img_create_update_segheader(seg_header, bflb_utils.int_to_4bytearray_l(len(seg_data)), segdata_crcarray) + segheader_crcarray = bflb_utils.get_crc32_bytearray(seg_header) + seg_header = seg_header + segheader_crcarray + seg_header_list.append(seg_header) + i = i + 1 + + i = 0 + while i < seg_cnt: + data_toencrypt += seg_header_list[i] + data_toencrypt += seg_data_list[i] + i += 1 + + else: + seg_data = 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) + if encrypt != 0: + data_toencrypt = img_create_encrypt_data(data_toencrypt, encrypt_key, encrypt_iv, flash_img) + fw_data = bytearray(0) + data_tohash += data_toencrypt + fw_data = data_toencrypt + hash = img_create_sha256_data(data_tohash) + bflb_utils.printf('Image hash is ', binascii.hexlify(hash)) + bootheader_data = img_create_update_bootheader(bootheader_data, hash, seg_cnt) + 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 + bflb_utils.get_crc32_bytearray(pk_data) + if flash_img == 1: + bflb_utils.printf('Write flash img') + 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() + if encrypt != 0: + if encrypt == 1: + img_update_efuse(cfg, sign, pk_hash, 1, encrypt_key + bytearray(32 - len(encrypt_key)), key_sel, encrypt_key + bytearray(32 - len(encrypt_key)), security) + if encrypt == 2: + img_update_efuse(cfg, sign, pk_hash, 3, encrypt_key + bytearray(32 - len(encrypt_key)), key_sel, encrypt_key + bytearray(32 - len(encrypt_key)), security) + if encrypt == 3: + img_update_efuse(cfg, sign, pk_hash, 2, encrypt_key + bytearray(32 - len(encrypt_key)), key_sel, encrypt_key + bytearray(32 - len(encrypt_key)), security) + else: + img_update_efuse(cfg, sign, pk_hash, encrypt, None, key_sel, None, security) + else: + bflb_utils.printf('Write if img') + 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() + if encrypt != 0: + if encrypt == 1: + img_update_efuse(cfg, sign, pk_hash, 1, None, key_sel, encrypt_key + bytearray(32 - len(encrypt_key)), security) + if encrypt == 2: + img_update_efuse(cfg, sign, pk_hash, 3, None, key_sel, encrypt_key + bytearray(32 - len(encrypt_key)), security) + if encrypt == 3: + img_update_efuse(cfg, sign, pk_hash, 2, None, key_sel, encrypt_key + bytearray(32 - len(encrypt_key)), security) + else: + img_update_efuse(cfg, sign, pk_hash, 0, None, key_sel, bytearray(32), security) + return ( + 'OK', data_tohash) + + +def img_create_do(args, img_dir_path=None, config_file=None): + bflb_utils.printf('Image create path: ', img_dir_path) + if config_file is None: + config_file = img_dir_path + '/img_create_cfg.ini' + bflb_utils.printf('Config file: ', config_file) + cfg = BFConfigParser() + cfg.read(config_file) + img_type = 'media' + signer = 'none' + security = False + data_tohash = bytearray(0) + try: + if args.image: + img_type = args.image + if args.signer: + signer = args.signer + if args.security: + security = args.security == 'efuse' + except Exception as e: + try: + bflb_utils.printf(e) + finally: + e = None + del e + + if img_type == 'media': + flash_img = 1 + else: + flash_img = 0 + ret, data_tohash = img_creat_process(flash_img, cfg, security) + if ret != 'OK': + bflb_utils.printf('Fail to create images!') + + +def create_sp_media_image(config, cpu_type=None, security=False): + bflb_utils.printf('========= sp image create =========') + cfg = BFConfigParser() + cfg.read(config) + img_creat_process(1, cfg, security) +# okay decompiling ./libs/base/bl702/img_create_do.pyc diff --git a/libs/base/bl702/jlink_load_cfg.py b/libs/base/bl702/jlink_load_cfg.py new file mode 100644 index 0000000..ca15755 --- /dev/null +++ b/libs/base/bl702/jlink_load_cfg.py @@ -0,0 +1,12 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/bl702/jlink_load_cfg.py +jlink_shake_hand_addr = '4202BFF0' +jlink_data_addr = '4202C000' +jlink_load_addr = '22010000' +jlink_core_type = 'RISC-V' +jlink_set_tif = 0 +jlink_run_addr = '22010000' +# okay decompiling ./libs/base/bl702/jlink_load_cfg.pyc diff --git a/libs/base/bl702/openocd_load_cfg.py b/libs/base/bl702/openocd_load_cfg.py new file mode 100644 index 0000000..f3d5062 --- /dev/null +++ b/libs/base/bl702/openocd_load_cfg.py @@ -0,0 +1,12 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/bl702/openocd_load_cfg.py +openocd_shake_hand_addr = '4202BFF0' +openocd_data_addr = '4202C000' +openocd_load_addr = '22010000' +openocd_core_type = 'RISC-V' +openocd_set_tif = 0 +openocd_run_addr = '22010000' +# okay decompiling ./libs/base/bl702/openocd_load_cfg.pyc diff --git a/libs/base/bl702l/bootheader_cfg_keys.py b/libs/base/bl702l/bootheader_cfg_keys.py new file mode 100644 index 0000000..0ec727f --- /dev/null +++ b/libs/base/bl702l/bootheader_cfg_keys.py @@ -0,0 +1,391 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/bl702l/bootheader_cfg_keys.py +bootheader_len = 240 +bootheader_cfg_keys = {'magic_code':{'offset':'0', + 'pos':'0', + 'bitlen':'32'}, + 'revision':{'offset':'4', + 'pos':'0', + 'bitlen':'32'}, + 'flashcfg_magic_code':{'offset':'8', + 'pos':'0', + 'bitlen':'32'}, + 'io_mode':{'offset':'12', + 'pos':'0', + 'bitlen':'8'}, + 'cont_read_support':{'offset':'12', + 'pos':'8', + 'bitlen':'8'}, + 'sfctrl_clk_delay':{'offset':'12', + 'pos':'16', + 'bitlen':'8'}, + 'sfctrl_clk_invert':{'offset':'12', + 'pos':'24', + 'bitlen':'8'}, + 'reset_en_cmd':{'offset':'16', + 'pos':'0', + 'bitlen':'8'}, + 'reset_cmd':{'offset':'16', + 'pos':'8', + 'bitlen':'8'}, + 'exit_contread_cmd':{'offset':'16', + 'pos':'16', + 'bitlen':'8'}, + 'exit_contread_cmd_size':{'offset':'16', + 'pos':'24', + 'bitlen':'8'}, + 'jedecid_cmd':{'offset':'20', + 'pos':'0', + 'bitlen':'8'}, + 'jedecid_cmd_dmy_clk':{'offset':'20', + 'pos':'8', + 'bitlen':'8'}, + 'qpi_jedecid_cmd':{'offset':'20', + 'pos':'16', + 'bitlen':'8'}, + 'qpi_jedecid_dmy_clk':{'offset':'20', + 'pos':'24', + 'bitlen':'8'}, + 'sector_size':{'offset':'24', + 'pos':'0', + 'bitlen':'8'}, + 'mfg_id':{'offset':'24', + 'pos':'8', + 'bitlen':'8'}, + 'page_size':{'offset':'24', + 'pos':'16', + 'bitlen':'16'}, + 'chip_erase_cmd':{'offset':'28', + 'pos':'0', + 'bitlen':'8'}, + 'sector_erase_cmd':{'offset':'28', + 'pos':'8', + 'bitlen':'8'}, + 'blk32k_erase_cmd':{'offset':'28', + 'pos':'16', + 'bitlen':'8'}, + 'blk64k_erase_cmd':{'offset':'28', + 'pos':'24', + 'bitlen':'8'}, + 'write_enable_cmd':{'offset':'32', + 'pos':'0', + 'bitlen':'8'}, + 'page_prog_cmd':{'offset':'32', + 'pos':'8', + 'bitlen':'8'}, + 'qpage_prog_cmd':{'offset':'32', + 'pos':'16', + 'bitlen':'8'}, + 'qual_page_prog_addr_mode':{'offset':'32', + 'pos':'24', + 'bitlen':'8'}, + 'fast_read_cmd':{'offset':'36', + 'pos':'0', + 'bitlen':'8'}, + 'fast_read_dmy_clk':{'offset':'36', + 'pos':'8', + 'bitlen':'8'}, + 'qpi_fast_read_cmd':{'offset':'36', + 'pos':'16', + 'bitlen':'8'}, + 'qpi_fast_read_dmy_clk':{'offset':'36', + 'pos':'24', + 'bitlen':'8'}, + 'fast_read_do_cmd':{'offset':'40', + 'pos':'0', + 'bitlen':'8'}, + 'fast_read_do_dmy_clk':{'offset':'40', + 'pos':'8', + 'bitlen':'8'}, + 'fast_read_dio_cmd':{'offset':'40', + 'pos':'16', + 'bitlen':'8'}, + 'fast_read_dio_dmy_clk':{'offset':'40', + 'pos':'24', + 'bitlen':'8'}, + 'fast_read_qo_cmd':{'offset':'44', + 'pos':'0', + 'bitlen':'8'}, + 'fast_read_qo_dmy_clk':{'offset':'44', + 'pos':'8', + 'bitlen':'8'}, + 'fast_read_qio_cmd':{'offset':'44', + 'pos':'16', + 'bitlen':'8'}, + 'fast_read_qio_dmy_clk':{'offset':'44', + 'pos':'24', + 'bitlen':'8'}, + 'qpi_fast_read_qio_cmd':{'offset':'48', + 'pos':'0', + 'bitlen':'8'}, + 'qpi_fast_read_qio_dmy_clk':{'offset':'48', + 'pos':'8', + 'bitlen':'8'}, + 'qpi_page_prog_cmd':{'offset':'48', + 'pos':'16', + 'bitlen':'8'}, + 'write_vreg_enable_cmd':{'offset':'48', + 'pos':'24', + 'bitlen':'8'}, + 'wel_reg_index':{'offset':'52', + 'pos':'0', + 'bitlen':'8'}, + 'qe_reg_index':{'offset':'52', + 'pos':'8', + 'bitlen':'8'}, + 'busy_reg_index':{'offset':'52', + 'pos':'16', + 'bitlen':'8'}, + 'wel_bit_pos':{'offset':'52', + 'pos':'24', + 'bitlen':'8'}, + 'qe_bit_pos':{'offset':'56', + 'pos':'0', + 'bitlen':'8'}, + 'busy_bit_pos':{'offset':'56', + 'pos':'8', + 'bitlen':'8'}, + 'wel_reg_write_len':{'offset':'56', + 'pos':'16', + 'bitlen':'8'}, + 'wel_reg_read_len':{'offset':'56', + 'pos':'24', + 'bitlen':'8'}, + 'qe_reg_write_len':{'offset':'60', + 'pos':'0', + 'bitlen':'8'}, + 'qe_reg_read_len':{'offset':'60', + 'pos':'8', + 'bitlen':'8'}, + 'release_power_down':{'offset':'60', + 'pos':'16', + 'bitlen':'8'}, + 'busy_reg_read_len':{'offset':'60', + 'pos':'24', + 'bitlen':'8'}, + 'reg_read_cmd0':{'offset':'64', + 'pos':'0', + 'bitlen':'8'}, + 'reg_read_cmd1':{'offset':'64', + 'pos':'8', + 'bitlen':'8'}, + 'reg_write_cmd0':{'offset':'68', + 'pos':'0', + 'bitlen':'8'}, + 'reg_write_cmd1':{'offset':'68', + 'pos':'8', + 'bitlen':'8'}, + 'enter_qpi_cmd':{'offset':'72', + 'pos':'0', + 'bitlen':'8'}, + 'exit_qpi_cmd':{'offset':'72', + 'pos':'8', + 'bitlen':'8'}, + 'cont_read_code':{'offset':'72', + 'pos':'16', + 'bitlen':'8'}, + 'cont_read_exit_code':{'offset':'72', + 'pos':'24', + 'bitlen':'8'}, + 'burst_wrap_cmd':{'offset':'76', + 'pos':'0', + 'bitlen':'8'}, + 'burst_wrap_dmy_clk':{'offset':'76', + 'pos':'8', + 'bitlen':'8'}, + 'burst_wrap_data_mode':{'offset':'76', + 'pos':'16', + 'bitlen':'8'}, + 'burst_wrap_code':{'offset':'76', + 'pos':'24', + 'bitlen':'8'}, + 'de_burst_wrap_cmd':{'offset':'80', + 'pos':'0', + 'bitlen':'8'}, + 'de_burst_wrap_cmd_dmy_clk':{'offset':'80', + 'pos':'8', + 'bitlen':'8'}, + 'de_burst_wrap_code_mode':{'offset':'80', + 'pos':'16', + 'bitlen':'8'}, + 'de_burst_wrap_code':{'offset':'80', + 'pos':'24', + 'bitlen':'8'}, + 'sector_erase_time':{'offset':'84', + 'pos':'0', + 'bitlen':'16'}, + 'blk32k_erase_time':{'offset':'84', + 'pos':'16', + 'bitlen':'16'}, + 'blk64k_erase_time':{'offset':'88', + 'pos':'0', + 'bitlen':'16'}, + 'page_prog_time':{'offset':'88', + 'pos':'16', + 'bitlen':'16'}, + 'chip_erase_time':{'offset':'92', + 'pos':'0', + 'bitlen':'16'}, + 'power_down_delay':{'offset':'92', + 'pos':'16', + 'bitlen':'8'}, + 'qe_data':{'offset':'92', + 'pos':'24', + 'bitlen':'8'}, + 'flashcfg_crc32':{'offset':'96', + 'pos':'0', + 'bitlen':'32'}, + 'clkcfg_magic_code':{'offset':'100', + 'pos':'0', + 'bitlen':'32'}, + 'xtal_type':{'offset':'104', + 'pos':'0', + 'bitlen':'8'}, + 'pll_clk':{'offset':'104', + 'pos':'8', + 'bitlen':'8'}, + 'hclk_div':{'offset':'104', + 'pos':'16', + 'bitlen':'8'}, + 'bclk_div':{'offset':'104', + 'pos':'24', + 'bitlen':'8'}, + 'flash_clk_type':{'offset':'108', + 'pos':'0', + 'bitlen':'8'}, + 'flash_clk_div':{'offset':'108', + 'pos':'8', + 'bitlen':'8'}, + 'clkcfg_crc32':{'offset':'112', + 'pos':'0', + 'bitlen':'32'}, + 'sign':{'offset':'116', + 'pos':'0', + 'bitlen':'2'}, + 'encrypt_type':{'offset':'116', + 'pos':'2', + 'bitlen':'2'}, + 'key_sel':{'offset':'116', + 'pos':'4', + 'bitlen':'2'}, + 'no_segment':{'offset':'116', + 'pos':'8', + 'bitlen':'1'}, + 'cache_enable':{'offset':'116', + 'pos':'9', + 'bitlen':'1'}, + 'notload_in_bootrom':{'offset':'116', + 'pos':'10', + 'bitlen':'1'}, + 'aes_region_lock':{'offset':'116', + 'pos':'11', + 'bitlen':'1'}, + 'cache_way_disable':{'offset':'116', + 'pos':'12', + 'bitlen':'4'}, + 'crc_ignore':{'offset':'116', + 'pos':'16', + 'bitlen':'1'}, + 'hash_ignore':{'offset':'116', + 'pos':'17', + 'bitlen':'1'}, + 'boot2_enable':{'offset':'116', + 'pos':'19', + 'bitlen':'1'}, + 'boot2_rollback':{'offset':'116', + 'pos':'20', + 'bitlen':'1'}, + 'img_len':{'offset':'120', + 'pos':'0', + 'bitlen':'32'}, + 'bootentry':{'offset':'124', + 'pos':'0', + 'bitlen':'32'}, + 'img_start':{'offset':'128', + 'pos':'0', + 'bitlen':'32'}, + 'hash_0':{'offset':'132', + 'pos':'0', + 'bitlen':'32'}, + 'hash_1':{'offset':'136', + 'pos':'0', + 'bitlen':'32'}, + 'hash_2':{'offset':'140', + 'pos':'0', + 'bitlen':'32'}, + 'hash_3':{'offset':'144', + 'pos':'0', + 'bitlen':'32'}, + 'hash_4':{'offset':'148', + 'pos':'0', + 'bitlen':'32'}, + 'hash_5':{'offset':'152', + 'pos':'0', + 'bitlen':'32'}, + 'hash_6':{'offset':'156', + 'pos':'0', + 'bitlen':'32'}, + 'hash_7':{'offset':'160', + 'pos':'0', + 'bitlen':'32'}, + 'boot2_pt_table_0':{'offset':'164', + 'pos':'0', + 'bitlen':'32'}, + 'boot2_pt_table_1':{'offset':'168', + 'pos':'0', + 'bitlen':'32'}, + 'flashCfgTableAddr':{'offset':'172', + 'pos':'0', + 'bitlen':'32'}, + 'flashCfgTableLen':{'offset':'176', + 'pos':'0', + 'bitlen':'32'}, + 'patch_read_addr0':{'offset':'180', + 'pos':'0', + 'bitlen':'32'}, + 'patch_read_value0':{'offset':'184', + 'pos':'0', + 'bitlen':'32'}, + 'patch_read_addr1':{'offset':'188', + 'pos':'0', + 'bitlen':'32'}, + 'patch_read_value1':{'offset':'192', + 'pos':'0', + 'bitlen':'32'}, + 'patch_read_addr2':{'offset':'196', + 'pos':'0', + 'bitlen':'32'}, + 'patch_read_value2':{'offset':'200', + 'pos':'0', + 'bitlen':'32'}, + 'patch_jump_addr0':{'offset':'204', + 'pos':'0', + 'bitlen':'32'}, + 'patch_jump_value0':{'offset':'208', + 'pos':'0', + 'bitlen':'32'}, + 'patch_jump_addr1':{'offset':'212', + 'pos':'0', + 'bitlen':'32'}, + 'patch_jump_value1':{'offset':'216', + 'pos':'0', + 'bitlen':'32'}, + 'patch_jump_addr2':{'offset':'220', + 'pos':'0', + 'bitlen':'32'}, + 'patch_jump_value2':{'offset':'224', + 'pos':'0', + 'bitlen':'32'}, + 'reserved1':{'offset':'228', + 'pos':'0', + 'bitlen':'32'}, + 'reserved2':{'offset':'232', + 'pos':'0', + 'bitlen':'32'}, + 'crc32':{'offset':'236', + 'pos':'0', + 'bitlen':'32'}} +# okay decompiling ./libs/base/bl702l/bootheader_cfg_keys.pyc diff --git a/libs/base/bl702l/chiptype_patch.py b/libs/base/bl702l/chiptype_patch.py new file mode 100644 index 0000000..aa8f89c --- /dev/null +++ b/libs/base/bl702l/chiptype_patch.py @@ -0,0 +1,62 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/bl702l/chiptype_patch.py + + +def img_load_create_predata_before_run_img(): + pre_data = bytearray(12) + pre_data[0] = 80 + pre_data[1] = 0 + pre_data[2] = 8 + pre_data[3] = 0 + pre_data[4] = 0 + pre_data[5] = 241 + pre_data[6] = 0 + pre_data[7] = 64 + pre_data[8] = 69 + pre_data[9] = 72 + pre_data[10] = 66 + pre_data[11] = 78 + pre_data2 = bytearray(12) + pre_data2[0] = 80 + pre_data2[1] = 0 + pre_data2[2] = 8 + pre_data2[3] = 0 + pre_data2[4] = 4 + pre_data2[5] = 241 + pre_data2[6] = 0 + pre_data2[7] = 64 + pre_data2[8] = 0 + pre_data2[9] = 0 + pre_data2[10] = 1 + pre_data2[11] = 34 + pre_data3 = bytearray(12) + pre_data3[0] = 80 + pre_data3[1] = 0 + pre_data3[2] = 8 + pre_data3[3] = 0 + pre_data3[4] = 24 + pre_data3[5] = 0 + pre_data3[6] = 0 + pre_data3[7] = 64 + pre_data3[8] = 0 + pre_data3[9] = 0 + pre_data3[10] = 0 + pre_data3[11] = 0 + pre_data4 = bytearray(12) + pre_data4[0] = 80 + pre_data4[1] = 0 + pre_data4[2] = 8 + pre_data4[3] = 0 + pre_data4[4] = 24 + pre_data4[5] = 0 + pre_data4[6] = 0 + pre_data4[7] = 64 + pre_data4[8] = 2 + pre_data4[9] = 0 + pre_data4[10] = 0 + pre_data4[11] = 0 + return pre_data + pre_data2 + pre_data3 + pre_data4 +# okay decompiling ./libs/base/bl702l/chiptype_patch.pyc diff --git a/libs/base/bl702l/cklink_load_cfg.py b/libs/base/bl702l/cklink_load_cfg.py new file mode 100644 index 0000000..907e5f7 --- /dev/null +++ b/libs/base/bl702l/cklink_load_cfg.py @@ -0,0 +1,12 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/bl702l/cklink_load_cfg.py +cklink_shake_hand_addr = '4202BFF0' +cklink_data_addr = '4202C000' +cklink_load_addr = '22010000' +cklink_core_type = 'RISC-V' +cklink_set_tif = 0 +cklink_run_addr = '22010000' +# okay decompiling ./libs/base/bl702l/cklink_load_cfg.pyc diff --git a/libs/base/bl702l/flash_select_do.py b/libs/base/bl702l/flash_select_do.py new file mode 100644 index 0000000..2360ac8 --- /dev/null +++ b/libs/base/bl702l/flash_select_do.py @@ -0,0 +1,151 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/bl702l/flash_select_do.py +import os, csv, config as gol +from libs import bflb_utils +from libs.bflb_utils import app_path, conf_sign +from libs.bflb_configobj import BFConfigParser +from libs.base.bl702l.bootheader_cfg_keys import bootheader_cfg_keys as flash_cfg_keys + +def get_suitable_file_name(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: + bflb_utils.printf('Flash id duplicate and alternative is:') + for i in range(len(conf_files)): + tmp = conf_files[i].split('.')[0] + bflb_utils.printf('%d:%s' % (i + 1, tmp)) + + return conf_files[i] + if len(conf_files) == 1: + return conf_files[0] + return '' + + +def update_flash_cfg_do(chipname, chiptype, flash_id, file=None, create=False, section=None): + if conf_sign: + cfg_dir = app_path + '/utils/flash/' + chipname + '/' + else: + cfg_dir = app_path + '/utils/flash/' + gol.flash_dict[chipname] + '/' + conf_name = get_suitable_file_name(cfg_dir, flash_id) + value_key = [] + if os.path.isfile(cfg_dir + conf_name) is False: + return False + fp = open(cfg_dir + conf_name, 'r') + for line in fp.readlines(): + value = line.split('=')[0].strip() + if value == '[FLASH_CFG]': + continue + else: + value_key.append(value) + + cfg1 = BFConfigParser() + cfg1.read(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]): + if cfg2.has_option(section, value_key[i]): + tmp_value = cfg1.get('FLASH_CFG', value_key[i]) + bflb_utils.update_cfg(cfg2, section, value_key[i], tmp_value) + + cfg2.write(file, 'w+') + bflb_utils.printf('Update flash cfg finished') + + +def get_supported_flash_do(): + flash_type = [] + return flash_type + + +def get_int_mask(pos, length): + ones = '11111111111111111111111111111111' + zeros = '00000000000000000000000000000000' + mask = ones[0:32 - pos - length] + zeros[0:length] + ones[0:pos] + return int(mask, 2) + + +def create_flashcfg_data_from_cfg(cfg_len, cfgfile): + section = 'FLASH_CFG' + cfg = BFConfigParser() + cfg.read(cfgfile) + data = bytearray(cfg_len) + minOffset = int(flash_cfg_keys.get('io_mode')['offset'], 10) + for key in cfg.options(section): + if flash_cfg_keys.get(key) == None: + bflb_utils.printf(key + ' not exist') + continue + else: + val = cfg.get(section, key) + if val.startswith('0x'): + val = int(val, 16) + else: + val = int(val, 10) + offset = int(flash_cfg_keys.get(key)['offset'], 10) - minOffset + pos = int(flash_cfg_keys.get(key)['pos'], 10) + bitlen = int(flash_cfg_keys.get(key)['bitlen'], 10) + oldval = bflb_utils.bytearray_to_int(bflb_utils.bytearray_reverse(data[offset:offset + 4])) + newval = (oldval & get_int_mask(pos, bitlen)) + (val << pos) + data[offset:offset + 4] = bflb_utils.int_to_4bytearray_l(newval) + + crcarray = bflb_utils.get_crc32_bytearray(data) + data = bflb_utils.int_to_4bytearray_l(1195787078) + data + crcarray + return data + + +def create_flashcfg_table(start_addr): + single_flashcfg_len = 92 + flash_table_list = bytearray(0) + flash_table_data = bytearray(0) + if conf_sign: + table_file = os.path.join(app_path, 'utils', 'flash', 'bl702l', 'flashcfg_list.csv') + else: + table_file = os.path.join(app_path, 'utils', 'flash', 'bl702l', 'flashcfg_list.csv') + with open(table_file, 'r', encoding='utf-8-sig') as csvfile: + table_list = [] + cfgfile_list = [] + reader = csv.DictReader(csvfile) + cnt = 0 + for row in reader: + row_dict = {} + row_dict['jid'] = row.get('flashJedecID', '') + row_dict['cfgfile'] = row.get('configFile', '') + if row_dict['cfgfile'] not in cfgfile_list: + cfgfile_list.append(row_dict['cfgfile']) + else: + table_list.append(row_dict) + cnt += 1 + + table_list_len = 4 + cnt * 8 + 4 + for cfgfile in cfgfile_list: + if conf_sign: + cfgfile = os.path.join(app_path, 'utils', 'flash', 'bl702l', cfgfile) + else: + cfgfile = os.path.join(app_path, 'utils', 'flash', 'bl702l', cfgfile) + data = create_flashcfg_data_from_cfg(single_flashcfg_len - 8, cfgfile) + flash_table_data += data + + for dict in table_list: + flash_table_list += bflb_utils.int_to_4bytearray_b(int(dict['jid'] + '00', 16)) + i = 0 + offset = 0 + for cfgfile in cfgfile_list: + if cfgfile == dict['cfgfile']: + offset = start_addr + table_list_len + single_flashcfg_len * i + break + else: + i += 1 + + flash_table_list += bflb_utils.int_to_4bytearray_l(offset) + + crcarray = bflb_utils.get_crc32_bytearray(flash_table_list) + flash_table_list = bflb_utils.int_to_4bytearray_l(1196704582) + flash_table_list + crcarray + return ( + flash_table_list, flash_table_data, len(flash_table_list)) +# okay decompiling ./libs/base/bl702l/flash_select_do.pyc diff --git a/libs/base/bl702l/img_create_do.py b/libs/base/bl702l/img_create_do.py new file mode 100644 index 0000000..7924b3e --- /dev/null +++ b/libs/base/bl702l/img_create_do.py @@ -0,0 +1,438 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/bl702l/img_create_do.py +import hashlib, binascii, ecdsa +from libs import bflb_utils +from libs.bflb_utils import img_create_sha256_data, img_create_encrypt_data +from libs.bflb_configobj import BFConfigParser +from libs.base.bl702l.flash_select_do import create_flashcfg_table +from libs.base.bl702l.bootheader_cfg_keys import bootheader_len as header_len +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 + +def img_update_efuse(cfg, sign, pk_hash, flash_encryp_type, flash_key, sec_eng_key_sel, sec_eng_key, security=False): + 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] |= 128 + efuse_data[0] |= 48 + efuse_mask_data[0] |= 255 + rw_lock = 0 + if pk_hash is not 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 is not None: + if flash_encryp_type == 1: + efuse_data[keyslot2:keyslot3] = flash_key[0:16] + efuse_mask_data[keyslot2:keyslot3] = mask_4bytes * 4 + else: + if flash_encryp_type == 2: + efuse_data[keyslot2:keyslot4] = flash_key + efuse_mask_data[keyslot2:keyslot4] = mask_4bytes * 8 + rw_lock |= 1 << wr_lock_key_slot_3 + rw_lock |= 1 << rd_lock_key_slot_3 + else: + if flash_encryp_type == 3: + efuse_data[keyslot2:keyslot4] = flash_key + efuse_mask_data[keyslot2:keyslot4] = mask_4bytes * 8 + rw_lock |= 1 << wr_lock_key_slot_3 + rw_lock |= 1 << rd_lock_key_slot_3 + rw_lock |= 1 << wr_lock_key_slot_2 + rw_lock |= 1 << rd_lock_key_slot_2 + if sec_eng_key is not None: + if flash_encryp_type == 0: + if sec_eng_key_sel == 0: + efuse_data[keyslot3:keyslot4] = sec_eng_key[0:16] + efuse_mask_data[keyslot3:keyslot4] = mask_4bytes * 4 + rw_lock |= 1 << wr_lock_key_slot_3 + rw_lock |= 1 << rd_lock_key_slot_3 + if sec_eng_key_sel == 1: + efuse_data[keyslot2:keyslot3] = sec_eng_key[0:16] + efuse_mask_data[keyslot2:keyslot3] = mask_4bytes * 4 + rw_lock |= 1 << wr_lock_key_slot_2 + rw_lock |= 1 << rd_lock_key_slot_2 + if flash_encryp_type == 1: + if sec_eng_key_sel == 0: + efuse_data[keyslot5:keyslot6] = sec_eng_key[0:16] + efuse_mask_data[keyslot5:keyslot6] = mask_4bytes * 4 + rw_lock |= 1 << wr_lock_key_slot_5_l + rw_lock |= 1 << wr_lock_key_slot_5_h + rw_lock |= 1 << rd_lock_key_slot_5 + 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 + efuse_data[124:128] = bflb_utils.int_to_4bytearray_l(rw_lock) + efuse_mask_data[124:128] = bflb_utils.int_to_4bytearray_l(rw_lock) + if security is True: + bflb_utils.printf('Encrypt efuse data') + security_key, security_iv = bflb_utils.get_security_key() + efuse_data = img_create_encrypt_data(efuse_data, security_key, security_iv, 0) + efuse_data = bytearray(4096) + efuse_data + 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() + + +def img_create_get_sign_encrypt_info(bootheader_data): + sign = bootheader_data[116] & 3 + encrypt = bootheader_data[116] >> 2 & 3 + key_sel = bootheader_data[116] >> 4 & 3 + return ( + sign, encrypt, key_sel) + + +def img_create_get_hash_ignore(bootheader_data): + return bootheader_data[118] >> 1 & 1 + + +def img_create_get_crc_ignore(bootheader_data): + return bootheader_data[118] & 1 + + +def img_create_update_bootheader_if(bootheader_data, hash, seg_cnt): + bootheader_data[120:124] = bflb_utils.int_to_4bytearray_l(seg_cnt) + sign = bootheader_data[116] & 3 + encrypt = bootheader_data[116] >> 2 & 3 + key_sel = bootheader_data[116] >> 4 & 3 + if bootheader_data[118] >> 1 & 1 == 1 and sign == 0: + bflb_utils.printf('Hash ignored') + else: + bootheader_data[132:164] = hash + if bootheader_data[118] & 1 == 1: + bflb_utils.printf('Header crc ignored') + else: + hd_crcarray = bflb_utils.get_crc32_bytearray(bootheader_data[0:header_len - 4]) + bootheader_data[header_len - 4:header_len] = hd_crcarray + bflb_utils.printf('Header crc: ', binascii.hexlify(hd_crcarray)) + return bootheader_data + + +def img_create_update_bootheader(bootheader_data, hash, seg_cnt, flashcfg_table_addr, flashcfg_table_len): + bootheader_data[172:176] = bflb_utils.int_to_4bytearray_l(flashcfg_table_addr) + bootheader_data[176:180] = bflb_utils.int_to_4bytearray_l(flashcfg_table_len) + bootheader_data[120:124] = bflb_utils.int_to_4bytearray_l(seg_cnt) + sign, encrypt, key_sel = img_create_get_sign_encrypt_info(bootheader_data) + if img_create_get_hash_ignore(bootheader_data) == 1 and sign == 0: + bflb_utils.printf('Hash ignored') + else: + bootheader_data[132:164] = hash + if img_create_get_crc_ignore(bootheader_data) == 1: + bflb_utils.printf('Header crc ignored') + else: + hd_crcarray = bflb_utils.get_crc32_bytearray(bootheader_data[0:header_len - 4]) + bootheader_data[header_len - 4:header_len] = hd_crcarray + bflb_utils.printf('Header crc: ', binascii.hexlify(hd_crcarray)) + return bootheader_data[0:header_len] + + +def img_create_update_segheader(segheader, segdatalen, segdatacrc): + segheader[4:8] = segdatalen + segheader[8:12] = segdatacrc + return segheader + + +def img_create_sign_data(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() + bflb_utils.printf('Private key: ', binascii.hexlify(sk.to_string())) + bflb_utils.printf('Public key: ', binascii.hexlify(pk_data)) + pk_hash = img_create_sha256_data(pk_data) + bflb_utils.printf('Public key hash=', binascii.hexlify(pk_hash)) + signature = sk.sign(data_bytearray, hashfunc=(hashlib.sha256), sigencode=(ecdsa.util.sigencode_string)) + bflb_utils.printf('Signature=', binascii.hexlify(signature)) + len_array = bflb_utils.int_to_4bytearray_l(len(signature)) + sig_field = len_array + signature + crcarray = bflb_utils.get_crc32_bytearray(sig_field) + return ( + pk_data, pk_hash, sig_field + crcarray) + + +def img_create_read_file_append_crc(file, crc): + fp = open(file, 'rb') + read_data = bytearray(fp.read()) + crcarray = bytearray(0) + if crc: + crcarray = bflb_utils.get_crc32_bytearray(read_data) + fp.close() + return read_data + crcarray + + +def encrypt_loader_bin_do(file, sign, encrypt, temp_encrypt_key, temp_encrypt_iv, publickey_file, privatekey_file): + if encrypt != 0 or sign != 0: + encrypt_key = bytearray(0) + encrypt_iv = bytearray(0) + load_helper_bin_header = bytearray(0) + load_helper_bin_body = bytearray(0) + offset = 116 + sign_pos = 0 + encrypt_type_pos = 2 + key_sel_pos = 4 + pk_data = bytearray(0) + signature = bytearray(0) + aesiv_data = bytearray(0) + data_tohash = bytearray(0) + with open(file, 'rb') as fp: + load_helper_bin = fp.read() + load_helper_bin_header = load_helper_bin[0:header_len] + load_helper_bin_body = load_helper_bin[header_len:] + if load_helper_bin_header != bytearray(0): + if load_helper_bin_body != bytearray(0): + load_helper_bin_body = bflb_utils.add_to_16(load_helper_bin_body) + if encrypt != 0: + encrypt_key = bflb_utils.hexstr_to_bytearray(temp_encrypt_key) + encrypt_iv = bflb_utils.hexstr_to_bytearray(temp_encrypt_iv) + iv_crcarray = bflb_utils.get_crc32_bytearray(encrypt_iv) + aesiv_data = encrypt_iv + iv_crcarray + data_tohash = data_tohash + aesiv_data + load_helper_bin_body_encrypt = bflb_utils.img_create_encrypt_data(load_helper_bin_body, encrypt_key, encrypt_iv, 0) + else: + load_helper_bin_body_encrypt = load_helper_bin_body + data = bytearray(load_helper_bin_header) + oldval = bflb_utils.bytearray_to_int(bflb_utils.bytearray_reverse(data[offset:offset + 4])) + newval = oldval + if encrypt != 0: + newval = newval | 1 << encrypt_type_pos + newval = newval | 1 << key_sel_pos + if sign != 0: + newval = newval | 1 << sign_pos + data_tohash += load_helper_bin_body_encrypt + pk_data, pk_hash, signature = img_create_sign_data(data_tohash, privatekey_file, publickey_file) + pk_data = pk_data + bflb_utils.get_crc32_bytearray(pk_data) + data[offset:offset + 4] = bflb_utils.int_to_4bytearray_l(newval) + load_helper_bin_header = data + load_helper_bin_encrypt = load_helper_bin_header + pk_data + signature + aesiv_data + load_helper_bin_body_encrypt + hashfun = hashlib.sha256() + hashfun.update(data_tohash) + hash = bflb_utils.hexstr_to_bytearray(hashfun.hexdigest()) + load_helper_bin_data = bytearray(load_helper_bin_encrypt) + load_helper_bin_encrypt = img_create_update_bootheader_if(load_helper_bin_data, hash, 1) + return ( + True, load_helper_bin_encrypt) + return (False, None) + + +def img_creat_process(flash_img, cfg, security=False): + encrypt_blk_size = 16 + padding = bytearray(encrypt_blk_size) + data_tohash = bytearray(0) + cfg_section = 'Img_Cfg' + 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 + + boot_header_file = cfg.get(cfg_section, 'boot_header_file') + bootheader_data = img_create_read_file_append_crc(boot_header_file, 0) + encrypt = 0 + sign, encrypt, key_sel = img_create_get_sign_encrypt_info(bootheader_data) + aesiv_data = bytearray(0) + pk_data = bytearray(0) + if sign != 0: + bflb_utils.printf('Image need sign') + publickey_file = cfg.get(cfg_section, 'publickey_file') + privatekey_file_uecc = cfg.get(cfg_section, 'privatekey_file_uecc') + if encrypt != 0: + bflb_utils.printf('Image need encrypt ', encrypt) + encrypt_key_org = bflb_utils.hexstr_to_bytearray(cfg.get(cfg_section, 'aes_key_org')) + if encrypt == 1: + encrypt_key = encrypt_key_org[0:16] + else: + if encrypt == 2: + encrypt_key = encrypt_key_org[0:32] + else: + if encrypt == 3: + encrypt_key = encrypt_key_org[0:24] + bflb_utils.printf('Key= ', binascii.hexlify(encrypt_key)) + encrypt_iv = bflb_utils.hexstr_to_bytearray(cfg.get(cfg_section, 'aes_iv')) + iv_crcarray = bflb_utils.get_crc32_bytearray(encrypt_iv) + aesiv_data = encrypt_iv + iv_crcarray + data_tohash = data_tohash + aesiv_data + seg_cnt = len(segheader_file) + if flash_img == 0: + if seg_cnt != len(segdata_file): + bflb_utils.printf('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: + seg_data = 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] + else: + segdata_crcarray = bflb_utils.get_crc32_bytearray(seg_data) + seg_data_list.append(seg_data) + seg_header = img_create_read_file_append_crc(segheader_file[i], 0) + seg_header = img_create_update_segheader(seg_header, bflb_utils.int_to_4bytearray_l(len(seg_data)), segdata_crcarray) + segheader_crcarray = bflb_utils.get_crc32_bytearray(seg_header) + seg_header = seg_header + segheader_crcarray + seg_header_list.append(seg_header) + i = i + 1 + + i = 0 + while i < seg_cnt: + data_toencrypt += seg_header_list[i] + data_toencrypt += seg_data_list[i] + i += 1 + + else: + seg_data = 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) + if encrypt != 0: + data_toencrypt = img_create_encrypt_data(data_toencrypt, encrypt_key, encrypt_iv, flash_img) + fw_data = bytearray(0) + data_tohash += data_toencrypt + fw_data = data_toencrypt + hash = img_create_sha256_data(data_tohash) + bflb_utils.printf('Image hash is ', binascii.hexlify(hash)) + 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 + bflb_utils.get_crc32_bytearray(pk_data) + flashCfgAddr = len(bootheader_data + pk_data + signature + aesiv_data) + flashCfgListLen = 0 + flashCfgList = bytearray(0) + flashCfgTable = bytearray(0) + if flash_img == 1: + if bootheader_data[25:26] == b'\xff': + flashCfgList, flashCfgTable, flashCfgListLen = create_flashcfg_table(flashCfgAddr) + bootheader_data = img_create_update_bootheader(bootheader_data, hash, seg_cnt, flashCfgAddr, flashCfgListLen) + if flash_img == 1: + bflb_utils.printf('Write flash img') + bootinfo_file_name = cfg.get(cfg_section, 'bootinfo_file') + fp = open(bootinfo_file_name, 'wb+') + bootinfo = bootheader_data + pk_data + signature + aesiv_data + flashCfgList + flashCfgTable + 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() + if encrypt != 0: + if encrypt == 1: + img_update_efuse(cfg, sign, pk_hash, 1, encrypt_key + bytearray(32 - len(encrypt_key)), key_sel, encrypt_key + bytearray(32 - len(encrypt_key)), security) + if encrypt == 2: + img_update_efuse(cfg, sign, pk_hash, 3, encrypt_key + bytearray(32 - len(encrypt_key)), key_sel, encrypt_key + bytearray(32 - len(encrypt_key)), security) + if encrypt == 3: + img_update_efuse(cfg, sign, pk_hash, 2, encrypt_key + bytearray(32 - len(encrypt_key)), key_sel, encrypt_key + bytearray(32 - len(encrypt_key)), security) + else: + img_update_efuse(cfg, sign, pk_hash, encrypt, None, key_sel, None, security) + else: + bflb_utils.printf('Write if img') + 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() + if encrypt != 0: + if encrypt == 1: + img_update_efuse(cfg, sign, pk_hash, 1, None, key_sel, encrypt_key + bytearray(32 - len(encrypt_key)), security) + if encrypt == 2: + img_update_efuse(cfg, sign, pk_hash, 3, None, key_sel, encrypt_key + bytearray(32 - len(encrypt_key)), security) + if encrypt == 3: + img_update_efuse(cfg, sign, pk_hash, 2, None, key_sel, encrypt_key + bytearray(32 - len(encrypt_key)), security) + else: + img_update_efuse(cfg, sign, pk_hash, 0, None, key_sel, bytearray(32), security) + return ( + 'OK', data_tohash) + + +def img_create_do(args, img_dir_path=None, config_file=None): + bflb_utils.printf('Image create path: ', img_dir_path) + if config_file is None: + config_file = img_dir_path + '/img_create_cfg.ini' + bflb_utils.printf('Config file: ', config_file) + cfg = BFConfigParser() + cfg.read(config_file) + img_type = 'media' + signer = 'none' + security = False + data_tohash = bytearray(0) + try: + if args.image: + img_type = args.image + if args.signer: + signer = args.signer + if args.security: + security = args.security == 'efuse' + except Exception as e: + try: + bflb_utils.printf(e) + finally: + e = None + del e + + if img_type == 'media': + flash_img = 1 + else: + flash_img = 0 + ret, data_tohash = img_creat_process(flash_img, cfg, security) + if ret != 'OK': + bflb_utils.printf('Fail to create images!') + + +def create_sp_media_image(config, cpu_type=None, security=False): + bflb_utils.printf('========= sp image create =========') + cfg = BFConfigParser() + cfg.read(config) + img_creat_process(1, cfg, security) +# okay decompiling ./libs/base/bl702l/img_create_do.pyc diff --git a/libs/base/bl702l/jlink_load_cfg.py b/libs/base/bl702l/jlink_load_cfg.py new file mode 100644 index 0000000..1341dff --- /dev/null +++ b/libs/base/bl702l/jlink_load_cfg.py @@ -0,0 +1,12 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/bl702l/jlink_load_cfg.py +jlink_shake_hand_addr = '4202BFF0' +jlink_data_addr = '4202C000' +jlink_load_addr = '22010000' +jlink_core_type = 'RISC-V' +jlink_set_tif = 0 +jlink_run_addr = '22010000' +# okay decompiling ./libs/base/bl702l/jlink_load_cfg.pyc diff --git a/libs/base/bl702l/openocd_load_cfg.py b/libs/base/bl702l/openocd_load_cfg.py new file mode 100644 index 0000000..6bf37e1 --- /dev/null +++ b/libs/base/bl702l/openocd_load_cfg.py @@ -0,0 +1,12 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/bl702l/openocd_load_cfg.py +openocd_shake_hand_addr = '4202BFF0' +openocd_data_addr = '4202C000' +openocd_load_addr = '22010000' +openocd_core_type = 'RISC-V' +openocd_set_tif = 0 +openocd_run_addr = '22010000' +# okay decompiling ./libs/base/bl702l/openocd_load_cfg.pyc diff --git a/libs/base/bl808/bootheader_cfg_keys.py b/libs/base/bl808/bootheader_cfg_keys.py new file mode 100644 index 0000000..52cf6ae --- /dev/null +++ b/libs/base/bl808/bootheader_cfg_keys.py @@ -0,0 +1,614 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/bl808/bootheader_cfg_keys.py +clock_start_pos = 100 +bootcfg_start_pos = 128 +bootcfg_len = 48 +bootcpucfg_start_pos = bootcfg_start_pos + bootcfg_len +bootcpucfg_len = 24 +bootcpucfg_m0_index = 0 +bootcpucfg_d0_index = 1 +bootcpucfg_lp_index = 2 +boot2_start_pos = bootcpucfg_start_pos + bootcpucfg_len * (bootcpucfg_lp_index + 1) +boot2_len = 8 +flashcfg_table_start_pos = boot2_start_pos + boot2_len +flashcfg_table_len = 8 +patch_on_read_start_pos = flashcfg_table_start_pos + flashcfg_table_len +patch_on_read_len = 32 +patch_on_jump_start_pos = patch_on_read_start_pos + patch_on_read_len +patch_on_jump_len = 32 +rsvd_start_pos = patch_on_jump_start_pos + patch_on_jump_len +rsvd_len = 20 +crc32_start_pos = rsvd_start_pos + rsvd_len +bootheader_len = crc32_start_pos + 4 +bootheader_cfg_keys = {'magic_code':{'offset':'0', + 'pos':'0', + 'bitlen':'32'}, + 'revision':{'offset':'4', + 'pos':'0', + 'bitlen':'32'}, + 'flashcfg_magic_code':{'offset':'8', + 'pos':'0', + 'bitlen':'32'}, + 'io_mode':{'offset':'12', + 'pos':'0', + 'bitlen':'8'}, + 'cont_read_support':{'offset':'12', + 'pos':'8', + 'bitlen':'8'}, + 'sfctrl_clk_delay':{'offset':'12', + 'pos':'16', + 'bitlen':'8'}, + 'sfctrl_clk_invert':{'offset':'12', + 'pos':'24', + 'bitlen':'8'}, + 'reset_en_cmd':{'offset':'16', + 'pos':'0', + 'bitlen':'8'}, + 'reset_cmd':{'offset':'16', + 'pos':'8', + 'bitlen':'8'}, + 'exit_contread_cmd':{'offset':'16', + 'pos':'16', + 'bitlen':'8'}, + 'exit_contread_cmd_size':{'offset':'16', + 'pos':'24', + 'bitlen':'8'}, + 'jedecid_cmd':{'offset':'20', + 'pos':'0', + 'bitlen':'8'}, + 'jedecid_cmd_dmy_clk':{'offset':'20', + 'pos':'8', + 'bitlen':'8'}, + 'enter_32bits_addr_cmd':{'offset':'20', + 'pos':'16', + 'bitlen':'8'}, + 'exit_32bits_addr_clk':{'offset':'20', + 'pos':'24', + 'bitlen':'8'}, + 'sector_size':{'offset':'24', + 'pos':'0', + 'bitlen':'8'}, + 'mfg_id':{'offset':'24', + 'pos':'8', + 'bitlen':'8'}, + 'page_size':{'offset':'24', + 'pos':'16', + 'bitlen':'16'}, + 'chip_erase_cmd':{'offset':'28', + 'pos':'0', + 'bitlen':'8'}, + 'sector_erase_cmd':{'offset':'28', + 'pos':'8', + 'bitlen':'8'}, + 'blk32k_erase_cmd':{'offset':'28', + 'pos':'16', + 'bitlen':'8'}, + 'blk64k_erase_cmd':{'offset':'28', + 'pos':'24', + 'bitlen':'8'}, + 'write_enable_cmd':{'offset':'32', + 'pos':'0', + 'bitlen':'8'}, + 'page_prog_cmd':{'offset':'32', + 'pos':'8', + 'bitlen':'8'}, + 'qpage_prog_cmd':{'offset':'32', + 'pos':'16', + 'bitlen':'8'}, + 'qual_page_prog_addr_mode':{'offset':'32', + 'pos':'24', + 'bitlen':'8'}, + 'fast_read_cmd':{'offset':'36', + 'pos':'0', + 'bitlen':'8'}, + 'fast_read_dmy_clk':{'offset':'36', + 'pos':'8', + 'bitlen':'8'}, + 'qpi_fast_read_cmd':{'offset':'36', + 'pos':'16', + 'bitlen':'8'}, + 'qpi_fast_read_dmy_clk':{'offset':'36', + 'pos':'24', + 'bitlen':'8'}, + 'fast_read_do_cmd':{'offset':'40', + 'pos':'0', + 'bitlen':'8'}, + 'fast_read_do_dmy_clk':{'offset':'40', + 'pos':'8', + 'bitlen':'8'}, + 'fast_read_dio_cmd':{'offset':'40', + 'pos':'16', + 'bitlen':'8'}, + 'fast_read_dio_dmy_clk':{'offset':'40', + 'pos':'24', + 'bitlen':'8'}, + 'fast_read_qo_cmd':{'offset':'44', + 'pos':'0', + 'bitlen':'8'}, + 'fast_read_qo_dmy_clk':{'offset':'44', + 'pos':'8', + 'bitlen':'8'}, + 'fast_read_qio_cmd':{'offset':'44', + 'pos':'16', + 'bitlen':'8'}, + 'fast_read_qio_dmy_clk':{'offset':'44', + 'pos':'24', + 'bitlen':'8'}, + 'qpi_fast_read_qio_cmd':{'offset':'48', + 'pos':'0', + 'bitlen':'8'}, + 'qpi_fast_read_qio_dmy_clk':{'offset':'48', + 'pos':'8', + 'bitlen':'8'}, + 'qpi_page_prog_cmd':{'offset':'48', + 'pos':'16', + 'bitlen':'8'}, + 'write_vreg_enable_cmd':{'offset':'48', + 'pos':'24', + 'bitlen':'8'}, + 'wel_reg_index':{'offset':'52', + 'pos':'0', + 'bitlen':'8'}, + 'qe_reg_index':{'offset':'52', + 'pos':'8', + 'bitlen':'8'}, + 'busy_reg_index':{'offset':'52', + 'pos':'16', + 'bitlen':'8'}, + 'wel_bit_pos':{'offset':'52', + 'pos':'24', + 'bitlen':'8'}, + 'qe_bit_pos':{'offset':'56', + 'pos':'0', + 'bitlen':'8'}, + 'busy_bit_pos':{'offset':'56', + 'pos':'8', + 'bitlen':'8'}, + 'wel_reg_write_len':{'offset':'56', + 'pos':'16', + 'bitlen':'8'}, + 'wel_reg_read_len':{'offset':'56', + 'pos':'24', + 'bitlen':'8'}, + 'qe_reg_write_len':{'offset':'60', + 'pos':'0', + 'bitlen':'8'}, + 'qe_reg_read_len':{'offset':'60', + 'pos':'8', + 'bitlen':'8'}, + 'release_power_down':{'offset':'60', + 'pos':'16', + 'bitlen':'8'}, + 'busy_reg_read_len':{'offset':'60', + 'pos':'24', + 'bitlen':'8'}, + 'reg_read_cmd0':{'offset':'64', + 'pos':'0', + 'bitlen':'8'}, + 'reg_read_cmd1':{'offset':'64', + 'pos':'8', + 'bitlen':'8'}, + 'reg_write_cmd0':{'offset':'68', + 'pos':'0', + 'bitlen':'8'}, + 'reg_write_cmd1':{'offset':'68', + 'pos':'8', + 'bitlen':'8'}, + 'enter_qpi_cmd':{'offset':'72', + 'pos':'0', + 'bitlen':'8'}, + 'exit_qpi_cmd':{'offset':'72', + 'pos':'8', + 'bitlen':'8'}, + 'cont_read_code':{'offset':'72', + 'pos':'16', + 'bitlen':'8'}, + 'cont_read_exit_code':{'offset':'72', + 'pos':'24', + 'bitlen':'8'}, + 'burst_wrap_cmd':{'offset':'76', + 'pos':'0', + 'bitlen':'8'}, + 'burst_wrap_dmy_clk':{'offset':'76', + 'pos':'8', + 'bitlen':'8'}, + 'burst_wrap_data_mode':{'offset':'76', + 'pos':'16', + 'bitlen':'8'}, + 'burst_wrap_code':{'offset':'76', + 'pos':'24', + 'bitlen':'8'}, + 'de_burst_wrap_cmd':{'offset':'80', + 'pos':'0', + 'bitlen':'8'}, + 'de_burst_wrap_cmd_dmy_clk':{'offset':'80', + 'pos':'8', + 'bitlen':'8'}, + 'de_burst_wrap_code_mode':{'offset':'80', + 'pos':'16', + 'bitlen':'8'}, + 'de_burst_wrap_code':{'offset':'80', + 'pos':'24', + 'bitlen':'8'}, + 'sector_erase_time':{'offset':'84', + 'pos':'0', + 'bitlen':'16'}, + 'blk32k_erase_time':{'offset':'84', + 'pos':'16', + 'bitlen':'16'}, + 'blk64k_erase_time':{'offset':'88', + 'pos':'0', + 'bitlen':'16'}, + 'page_prog_time':{'offset':'88', + 'pos':'16', + 'bitlen':'16'}, + 'chip_erase_time':{'offset':'92', + 'pos':'0', + 'bitlen':'16'}, + 'power_down_delay':{'offset':'92', + 'pos':'16', + 'bitlen':'8'}, + 'qe_data':{'offset':'92', + 'pos':'24', + 'bitlen':'8'}, + 'flashcfg_crc32':{'offset':'96', + 'pos':'0', + 'bitlen':'32'}, + 'clkcfg_magic_code':{'offset':str(int(clock_start_pos) + 0), + 'pos':'0', + 'bitlen':'32'}, + 'xtal_type':{'offset':str(int(clock_start_pos) + 4), + 'pos':'0', + 'bitlen':'8'}, + 'mcu_clk':{'offset':str(int(clock_start_pos) + 4), + 'pos':'8', + 'bitlen':'8'}, + 'mcu_clk_div':{'offset':str(int(clock_start_pos) + 4), + 'pos':'16', + 'bitlen':'8'}, + 'mcu_bclk_div':{'offset':str(int(clock_start_pos) + 4), + 'pos':'24', + 'bitlen':'8'}, + 'mcu_pbclk_div':{'offset':str(int(clock_start_pos) + 8), + 'pos':'0', + 'bitlen':'8'}, + 'lp_div':{'offset':str(int(clock_start_pos) + 8), + 'pos':'8', + 'bitlen':'8'}, + 'dsp_clk':{'offset':str(int(clock_start_pos) + 8), + 'pos':'16', + 'bitlen':'8'}, + 'dsp_clk_div':{'offset':str(int(clock_start_pos) + 8), + 'pos':'24', + 'bitlen':'8'}, + 'dsp_bclk_div':{'offset':str(int(clock_start_pos) + 12), + 'pos':'0', + 'bitlen':'8'}, + 'dsp_pbclk':{'offset':str(int(clock_start_pos) + 12), + 'pos':'8', + 'bitlen':'8'}, + 'dsp_pbclk_div':{'offset':str(int(clock_start_pos) + 12), + 'pos':'16', + 'bitlen':'8'}, + 'emi_clk':{'offset':str(int(clock_start_pos) + 12), + 'pos':'24', + 'bitlen':'8'}, + 'emi_clk_div':{'offset':str(int(clock_start_pos) + 16), + 'pos':'0', + 'bitlen':'8'}, + 'flash_clk_type':{'offset':str(int(clock_start_pos) + 16), + 'pos':'8', + 'bitlen':'8'}, + 'flash_clk_div':{'offset':str(int(clock_start_pos) + 16), + 'pos':'16', + 'bitlen':'8'}, + 'wifipll_pu':{'offset':str(int(clock_start_pos) + 16), + 'pos':'24', + 'bitlen':'8'}, + 'aupll_pu':{'offset':str(int(clock_start_pos) + 20), + 'pos':'0', + 'bitlen':'8'}, + 'cpupll_pu':{'offset':str(int(clock_start_pos) + 20), + 'pos':'8', + 'bitlen':'8'}, + 'mipipll_pu':{'offset':str(int(clock_start_pos) + 20), + 'pos':'16', + 'bitlen':'8'}, + 'uhspll_pu':{'offset':str(int(clock_start_pos) + 20), + 'pos':'24', + 'bitlen':'8'}, + 'clkcfg_crc32':{'offset':str(int(clock_start_pos) + 24), + 'pos':'0', + 'bitlen':'32'}, + 'sign':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'0', + 'bitlen':'2'}, + 'encrypt_type':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'2', + 'bitlen':'2'}, + 'key_sel':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'4', + 'bitlen':'2'}, + 'xts_mode':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'6', + 'bitlen':'1'}, + 'aes_region_lock':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'7', + 'bitlen':'1'}, + 'no_segment':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'8', + 'bitlen':'1'}, + 'boot2_enable':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'9', + 'bitlen':'1'}, + 'boot2_rollback':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'10', + 'bitlen':'1'}, + 'cpu_master_id':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'11', + 'bitlen':'4'}, + 'notload_in_bootrom':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'15', + 'bitlen':'1'}, + 'crc_ignore':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'16', + 'bitlen':'1'}, + 'hash_ignore':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'17', + 'bitlen':'1'}, + 'power_on_mm':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'18', + 'bitlen':'1'}, + 'em_sel':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'19', + 'bitlen':'3'}, + 'cmds_en':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'22', + 'bitlen':'1'}, + 'cmds_wrap_mode':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'23', + 'bitlen':'2'}, + 'cmds_wrap_len':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'25', + 'bitlen':'4'}, + 'icache_invalid':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'29', + 'bitlen':'1'}, + 'dcache_invalid':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'30', + 'bitlen':'1'}, + 'fpga_halt_release':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'31', + 'bitlen':'1'}, + 'group_image_offset':{'offset':str(int(bootcfg_start_pos) + 4), + 'pos':'0', + 'bitlen':'32'}, + 'aes_region_len':{'offset':str(int(bootcfg_start_pos) + 8), + 'pos':'0', + 'bitlen':'32'}, + 'img_len_cnt':{'offset':str(int(bootcfg_start_pos) + 12), + 'pos':'0', + 'bitlen':'32'}, + 'hash_0':{'offset':str(int(bootcfg_start_pos) + 16), + 'pos':'0', + 'bitlen':'32'}, + 'hash_1':{'offset':str(int(bootcfg_start_pos) + 20), + 'pos':'0', + 'bitlen':'32'}, + 'hash_2':{'offset':str(int(bootcfg_start_pos) + 24), + 'pos':'0', + 'bitlen':'32'}, + 'hash_3':{'offset':str(int(bootcfg_start_pos) + 28), + 'pos':'0', + 'bitlen':'32'}, + 'hash_4':{'offset':str(int(bootcfg_start_pos) + 32), + 'pos':'0', + 'bitlen':'32'}, + 'hash_5':{'offset':str(int(bootcfg_start_pos) + 36), + 'pos':'0', + 'bitlen':'32'}, + 'hash_6':{'offset':str(int(bootcfg_start_pos) + 40), + 'pos':'0', + 'bitlen':'32'}, + 'hash_7':{'offset':str(int(bootcfg_start_pos) + 44), + 'pos':'0', + 'bitlen':'32'}, + 'm0_config_enable':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_m0_index) + 0), + 'pos':'0', + 'bitlen':'8'}, + 'm0_halt_cpu':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_m0_index) + 0), + 'pos':'8', + 'bitlen':'8'}, + 'm0_cache_enable':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_m0_index) + 0), + 'pos':'16', + 'bitlen':'1'}, + 'm0_cache_wa':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_m0_index) + 0), + 'pos':'17', + 'bitlen':'1'}, + 'm0_cache_wb':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_m0_index) + 0), + 'pos':'18', + 'bitlen':'1'}, + 'm0_cache_wt':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_m0_index) + 0), + 'pos':'19', + 'bitlen':'1'}, + 'm0_cache_way_dis':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_m0_index) + 0), + 'pos':'20', + 'bitlen':'4'}, + 'm0_reserved':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_m0_index) + 0), + 'pos':'24', + 'bitlen':'8'}, + 'm0_cache_range_h':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_m0_index) + 4), + 'pos':'0', + 'bitlen':'32'}, + 'm0_cache_range_l':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_m0_index) + 8), + 'pos':'0', + 'bitlen':'32'}, + 'm0_image_address_offset':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_m0_index) + 12), + 'pos':'0', + 'bitlen':'32'}, + 'm0_boot_entry':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_m0_index) + 16), + 'pos':'0', + 'bitlen':'32'}, + 'm0_msp_val':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_m0_index) + 20), + 'pos':'0', + 'bitlen':'32'}, + 'd0_config_enable':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_d0_index) + 0), + 'pos':'0', + 'bitlen':'8'}, + 'd0_halt_cpu':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_d0_index) + 0), + 'pos':'8', + 'bitlen':'8'}, + 'd0_cache_enable':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_d0_index) + 0), + 'pos':'16', + 'bitlen':'1'}, + 'd0_cache_wa':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_d0_index) + 0), + 'pos':'17', + 'bitlen':'1'}, + 'd0_cache_wb':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_d0_index) + 0), + 'pos':'18', + 'bitlen':'1'}, + 'd0_cache_wt':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_d0_index) + 0), + 'pos':'19', + 'bitlen':'1'}, + 'd0_cache_way_dis':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_d0_index) + 0), + 'pos':'20', + 'bitlen':'4'}, + 'd0_reserved':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_d0_index) + 0), + 'pos':'24', + 'bitlen':'8'}, + 'd0_cache_range_h':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_d0_index) + 4), + 'pos':'0', + 'bitlen':'32'}, + 'd0_cache_range_l':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_d0_index) + 8), + 'pos':'0', + 'bitlen':'32'}, + 'd0_image_address_offset':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_d0_index) + 12), + 'pos':'0', + 'bitlen':'32'}, + 'd0_boot_entry':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_d0_index) + 16), + 'pos':'0', + 'bitlen':'32'}, + 'd0_msp_val':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_d0_index) + 20), + 'pos':'0', + 'bitlen':'32'}, + 'lp_config_enable':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_lp_index) + 0), + 'pos':'0', + 'bitlen':'8'}, + 'lp_halt_cpu':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_lp_index) + 0), + 'pos':'8', + 'bitlen':'8'}, + 'lp_cache_enable':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_lp_index) + 0), + 'pos':'16', + 'bitlen':'1'}, + 'lp_cache_wa':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_lp_index) + 0), + 'pos':'17', + 'bitlen':'1'}, + 'lp_cache_wb':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_lp_index) + 0), + 'pos':'18', + 'bitlen':'1'}, + 'lp_cache_wt':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_lp_index) + 0), + 'pos':'19', + 'bitlen':'1'}, + 'lp_cache_way_dis':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_lp_index) + 0), + 'pos':'20', + 'bitlen':'4'}, + 'lp_reserved':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_lp_index) + 0), + 'pos':'24', + 'bitlen':'8'}, + 'lp_cache_range_h':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_lp_index) + 4), + 'pos':'0', + 'bitlen':'32'}, + 'lp_cache_range_l':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_lp_index) + 8), + 'pos':'0', + 'bitlen':'32'}, + 'lp_image_address_offset':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_lp_index) + 12), + 'pos':'0', + 'bitlen':'32'}, + 'lp_boot_entry':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_lp_index) + 16), + 'pos':'0', + 'bitlen':'32'}, + 'lp_msp_val':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_lp_index) + 20), + 'pos':'0', + 'bitlen':'32'}, + 'boot2_pt_table_0':{'offset':str(int(boot2_start_pos) + 0), + 'pos':'0', + 'bitlen':'32'}, + 'boot2_pt_table_1':{'offset':str(int(boot2_start_pos) + 4), + 'pos':'0', + 'bitlen':'32'}, + 'flashCfgTableAddr':{'offset':str(int(flashcfg_table_start_pos) + 0), + 'pos':'0', + 'bitlen':'32'}, + 'flashCfgTableLen':{'offset':str(int(flashcfg_table_start_pos) + 4), + 'pos':'0', + 'bitlen':'32'}, + 'patch_read_addr0':{'offset':str(int(patch_on_read_start_pos) + 0), + 'pos':'0', + 'bitlen':'32'}, + 'patch_read_value0':{'offset':str(int(patch_on_read_start_pos) + 4), + 'pos':'0', + 'bitlen':'32'}, + 'patch_read_addr1':{'offset':str(int(patch_on_read_start_pos) + 8), + 'pos':'0', + 'bitlen':'32'}, + 'patch_read_value1':{'offset':str(int(patch_on_read_start_pos) + 12), + 'pos':'0', + 'bitlen':'32'}, + 'patch_read_addr2':{'offset':str(int(patch_on_read_start_pos) + 16), + 'pos':'0', + 'bitlen':'32'}, + 'patch_read_value2':{'offset':str(int(patch_on_read_start_pos) + 20), + 'pos':'0', + 'bitlen':'32'}, + 'patch_read_addr3':{'offset':str(int(patch_on_read_start_pos) + 24), + 'pos':'0', + 'bitlen':'32'}, + 'patch_read_value3':{'offset':str(int(patch_on_read_start_pos) + 28), + 'pos':'0', + 'bitlen':'32'}, + 'patch_jump_addr0':{'offset':str(int(patch_on_jump_start_pos) + 0), + 'pos':'0', + 'bitlen':'32'}, + 'patch_jump_value0':{'offset':str(int(patch_on_jump_start_pos) + 4), + 'pos':'0', + 'bitlen':'32'}, + 'patch_jump_addr1':{'offset':str(int(patch_on_jump_start_pos) + 8), + 'pos':'0', + 'bitlen':'32'}, + 'patch_jump_value1':{'offset':str(int(patch_on_jump_start_pos) + 12), + 'pos':'0', + 'bitlen':'32'}, + 'patch_jump_addr2':{'offset':str(int(patch_on_jump_start_pos) + 16), + 'pos':'0', + 'bitlen':'32'}, + 'patch_jump_value2':{'offset':str(int(patch_on_jump_start_pos) + 20), + 'pos':'0', + 'bitlen':'32'}, + 'patch_jump_addr3':{'offset':str(int(patch_on_jump_start_pos) + 24), + 'pos':'0', + 'bitlen':'32'}, + 'patch_jump_value3':{'offset':str(int(patch_on_jump_start_pos) + 28), + 'pos':'0', + 'bitlen':'32'}, + 'reserved1':{'offset':str(int(rsvd_start_pos) + 0), + 'pos':'0', + 'bitlen':'32'}, + 'reserved2':{'offset':str(int(rsvd_start_pos) + 4), + 'pos':'0', + 'bitlen':'32'}, + 'reserved3':{'offset':str(int(rsvd_start_pos) + 8), + 'pos':'0', + 'bitlen':'32'}, + 'reserved4':{'offset':str(int(rsvd_start_pos) + 12), + 'pos':'0', + 'bitlen':'32'}, + 'reserved5':{'offset':str(int(rsvd_start_pos) + 16), + 'pos':'0', + 'bitlen':'32'}, + 'crc32':{'offset':str(int(crc32_start_pos) + 0), + 'pos':'0', + 'bitlen':'32'}} +# okay decompiling ./libs/base/bl808/bootheader_cfg_keys.pyc diff --git a/libs/base/bl808/chiptype_patch.py b/libs/base/bl808/chiptype_patch.py new file mode 100644 index 0000000..c5a837c --- /dev/null +++ b/libs/base/bl808/chiptype_patch.py @@ -0,0 +1,10 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/bl808/chiptype_patch.py + + +def img_load_create_predata_before_run_img(): + return bytearray(0) +# okay decompiling ./libs/base/bl808/chiptype_patch.pyc diff --git a/libs/base/bl808/cklink_load_cfg.py b/libs/base/bl808/cklink_load_cfg.py new file mode 100644 index 0000000..d5e15bc --- /dev/null +++ b/libs/base/bl808/cklink_load_cfg.py @@ -0,0 +1,12 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/bl808/cklink_load_cfg.py +cklink_shake_hand_addr = '2204BBE8' +cklink_data_addr = '2204CC88' +cklink_load_addr = '22010000' +cklink_core_type = 'RISC-V' +cklink_set_tif = 0 +cklink_run_addr = '22010000' +# okay decompiling ./libs/base/bl808/cklink_load_cfg.pyc diff --git a/libs/base/bl808/flash_select_do.py b/libs/base/bl808/flash_select_do.py new file mode 100644 index 0000000..34eaaa7 --- /dev/null +++ b/libs/base/bl808/flash_select_do.py @@ -0,0 +1,153 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/bl808/flash_select_do.py +import os, csv +from re import I +import config as gol +from libs import bflb_utils +from libs.bflb_utils import app_path, conf_sign, cgc +from libs.bflb_configobj import BFConfigParser +from libs.base.bl808.bootheader_cfg_keys import bootheader_cfg_keys as flash_cfg_keys + +def get_suitable_file_name(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: + bflb_utils.printf('Flash id duplicate and alternative is:') + for i in range(len(conf_files)): + tmp = conf_files[i].split('.')[0] + bflb_utils.printf('%d:%s' % (i + 1, tmp)) + + return conf_files[i] + if len(conf_files) == 1: + return conf_files[0] + return '' + + +def update_flash_cfg_do(chipname, chiptype, flash_id, file=None, create=False, section=None): + if conf_sign: + cfg_dir = app_path + '/utils/flash/' + chipname + '/' + else: + cfg_dir = app_path + '/utils/flash/' + gol.flash_dict[chipname] + '/' + conf_name = get_suitable_file_name(cfg_dir, flash_id) + value_key = [] + if os.path.isfile(cfg_dir + conf_name) is False: + return False + fp = open(cfg_dir + conf_name, 'r') + for line in fp.readlines(): + value = line.split('=')[0].strip() + if value == '[FLASH_CFG]': + continue + else: + value_key.append(value) + + cfg1 = BFConfigParser() + cfg1.read(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]): + if cfg2.has_option(section, value_key[i]): + tmp_value = cfg1.get('FLASH_CFG', value_key[i]) + bflb_utils.update_cfg(cfg2, section, value_key[i], tmp_value) + + cfg2.write(file, 'w+') + bflb_utils.printf('Update flash cfg finished') + + +def get_supported_flash_do(): + flash_type = [] + return flash_type + + +def get_int_mask(pos, length): + ones = '11111111111111111111111111111111' + zeros = '00000000000000000000000000000000' + mask = ones[0:32 - pos - length] + zeros[0:length] + ones[0:pos] + return int(mask, 2) + + +def create_flashcfg_data_from_cfg(cfg_len, cfgfile): + section = 'FLASH_CFG' + cfg = BFConfigParser() + cfg.read(cfgfile) + data = bytearray(cfg_len) + minOffset = int(flash_cfg_keys.get('io_mode')['offset'], 10) + for key in cfg.options(section): + if flash_cfg_keys.get(key) == None: + bflb_utils.printf(key + ' not exist') + continue + else: + val = cfg.get(section, key) + if val.startswith('0x'): + val = int(val, 16) + else: + val = int(val, 10) + offset = int(flash_cfg_keys.get(key)['offset'], 10) - minOffset + pos = int(flash_cfg_keys.get(key)['pos'], 10) + bitlen = int(flash_cfg_keys.get(key)['bitlen'], 10) + oldval = bflb_utils.bytearray_to_int(bflb_utils.bytearray_reverse(data[offset:offset + 4])) + newval = (oldval & get_int_mask(pos, bitlen)) + (val << pos) + data[offset:offset + 4] = bflb_utils.int_to_4bytearray_l(newval) + + crcarray = bflb_utils.get_crc32_bytearray(data) + data = bflb_utils.int_to_4bytearray_l(1195787078) + data + crcarray + return data + + +def create_flashcfg_table(start_addr): + single_flashcfg_len = 92 + flash_table_list = bytearray(0) + flash_table_data = bytearray(0) + if conf_sign: + table_file = os.path.join(app_path, 'utils', 'flash', 'tg6210a', 'flashcfg_list.csv') + else: + table_file = os.path.join(app_path, 'utils', 'flash', 'bl808', 'flashcfg_list.csv') + with open(table_file, 'r', encoding='utf-8-sig') as csvfile: + table_list = [] + cfgfile_list = [] + reader = csv.DictReader(csvfile) + cnt = 0 + for row in reader: + row_dict = {} + row_dict['jid'] = row.get('flashJedecID', '') + row_dict['cfgfile'] = row.get('configFile', '') + if row_dict['cfgfile'] not in cfgfile_list: + cfgfile_list.append(row_dict['cfgfile']) + else: + table_list.append(row_dict) + cnt += 1 + + table_list_len = 4 + cnt * 8 + 4 + for cfgfile in cfgfile_list: + if conf_sign: + cfgfile = os.path.join(app_path, 'utils', 'flash', 'tg6210a', cfgfile) + else: + cfgfile = os.path.join(app_path, 'utils', 'flash', 'bl808', cfgfile) + data = create_flashcfg_data_from_cfg(single_flashcfg_len - 8, cfgfile) + flash_table_data += data + + for dict in table_list: + flash_table_list += bflb_utils.int_to_4bytearray_b(int(dict['jid'] + '00', 16)) + i = 0 + offset = 0 + for cfgfile in cfgfile_list: + if cfgfile == dict['cfgfile']: + offset = start_addr + table_list_len + single_flashcfg_len * i + break + else: + i += 1 + + flash_table_list += bflb_utils.int_to_4bytearray_l(offset) + + crcarray = bflb_utils.get_crc32_bytearray(flash_table_list) + flash_table_list = bflb_utils.int_to_4bytearray_l(1196704582) + flash_table_list + crcarray + return ( + flash_table_list, flash_table_data, len(flash_table_list)) +# okay decompiling ./libs/base/bl808/flash_select_do.pyc diff --git a/libs/base/bl808/img_create_do.py b/libs/base/bl808/img_create_do.py new file mode 100644 index 0000000..3de62aa --- /dev/null +++ b/libs/base/bl808/img_create_do.py @@ -0,0 +1,950 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/bl808/img_create_do.py +import os, sys, hashlib, binascii, codecs, ecdsa +from CryptoPlus.Cipher import AES as AES_XTS +from libs import bflb_utils +from libs.bflb_utils import img_create_sha256_data, img_create_encrypt_data +from libs.bflb_configobj import BFConfigParser +from libs.base.bl808.flash_select_do import create_flashcfg_table +from libs.base.bl808.bootheader_cfg_keys import flashcfg_table_start_pos as flashcfg_table_start +from libs.base.bl808.bootheader_cfg_keys import bootcpucfg_start_pos as bootcpucfg_start +from libs.base.bl808.bootheader_cfg_keys import bootcpucfg_len as bootcpucfg_length +from libs.base.bl808.bootheader_cfg_keys import bootcpucfg_m0_index as bootcpucfg_m0_index_number +from libs.base.bl808.bootheader_cfg_keys import bootcpucfg_d0_index as bootcpucfg_d0_index_number +from libs.base.bl808.bootheader_cfg_keys import bootcpucfg_lp_index as bootcpucfg_lp_index_number +from libs.base.bl808.bootheader_cfg_keys import bootcfg_start_pos as bootcfg_start +from libs.base.bl808.bootheader_cfg_keys import bootheader_len as header_len +keyslot0 = 28 +keyslot1 = keyslot0 + 16 +keyslot2 = keyslot1 + 16 +keyslot3 = keyslot2 + 16 +keyslot3_end = keyslot3 + 16 +keyslot4 = 128 +keyslot5 = keyslot4 + 16 +keyslot6 = keyslot5 + 16 +keyslot7 = keyslot6 + 16 +keyslot8 = keyslot7 + 16 +keyslot9 = keyslot8 + 16 +keyslot10 = keyslot9 + 16 +keyslot10_end = keyslot10 + 16 +keyslot11 = keyslot3_end + 16 +keyslot11_end = keyslot11 + 16 +wr_lock_boot_mode = 14 +wr_lock_dbg_pwd = 15 +wr_lock_wifi_mac = 16 +wr_lock_key_slot_0 = 17 +wr_lock_key_slot_1 = 18 +wr_lock_key_slot_2 = 19 +wr_lock_key_slot_3 = 20 +wr_lock_sw_usage_0 = 21 +wr_lock_sw_usage_1 = 22 +wr_lock_sw_usage_2 = 23 +wr_lock_sw_usage_3 = 24 +wr_lock_key_slot_11 = 25 +rd_lock_dbg_pwd = 26 +rd_lock_key_slot_0 = 27 +rd_lock_key_slot_1 = 28 +rd_lock_key_slot_2 = 29 +rd_lock_key_slot_3 = 30 +rd_lock_key_slot_11 = 31 +wr_lock_key_slot_4 = 15 +wr_lock_key_slot_5 = 16 +wr_lock_key_slot_6 = 17 +wr_lock_key_slot_7 = 18 +wr_lock_key_slot_8 = 19 +wr_lock_key_slot_9 = 20 +wr_lock_key_slot_10 = 21 +rd_lock_key_slot_4 = 25 +rd_lock_key_slot_5 = 26 +rd_lock_key_slot_6 = 27 +rd_lock_key_slot_7 = 28 +rd_lock_key_slot_8 = 29 +rd_lock_key_slot_9 = 30 +rd_lock_key_slot_10 = 31 + +def bytearray_data_merge(data1, data2, len): + for i in range(len): + data1[i] |= data2[i] + + return data1 + + +def img_update_efuse_group0(cfg, sign, pk_hash, flash_encryp_type, flash_key, sec_eng_key_sel, sec_eng_key, security=False): + fp = open(cfg.get('Img_Group0_Cfg', 'efuse_file'), 'rb') + efuse_data = bytearray(fp.read()) + bytearray(0) + fp.close() + fp = open(cfg.get('Img_Group0_Cfg', 'efuse_mask_file'), 'rb') + efuse_mask_data = bytearray(fp.read()) + bytearray(0) + fp.close() + mask_4bytes = bytearray.fromhex('FFFFFFFF') + if flash_encryp_type >= 3: + efuse_data[0] |= 3 + else: + efuse_data[0] |= flash_encryp_type + if sign > 0: + efuse_data[93] |= sign + efuse_mask_data[93] |= 255 + if flash_encryp_type > 0: + efuse_data[0] |= 48 + efuse_mask_data[0] |= 255 + rw_lock0 = 0 + rw_lock1 = 0 + if pk_hash is not None: + efuse_data[keyslot0:keyslot2] = pk_hash + efuse_mask_data[keyslot0:keyslot2] = mask_4bytes * 8 + rw_lock0 |= 1 << wr_lock_key_slot_0 + rw_lock0 |= 1 << wr_lock_key_slot_1 + if flash_key is not None: + if flash_encryp_type == 1: + efuse_data[keyslot2:keyslot3] = flash_key[0:16] + efuse_mask_data[keyslot2:keyslot3] = mask_4bytes * 4 + else: + if flash_encryp_type == 2: + efuse_data[keyslot2:keyslot3_end] = flash_key + efuse_mask_data[keyslot2:keyslot3_end] = mask_4bytes * 8 + rw_lock0 |= 1 << wr_lock_key_slot_3 + rw_lock0 |= 1 << rd_lock_key_slot_3 + else: + if flash_encryp_type == 3: + efuse_data[keyslot2:keyslot3_end] = flash_key + efuse_mask_data[keyslot2:keyslot3_end] = mask_4bytes * 8 + rw_lock0 |= 1 << wr_lock_key_slot_3 + rw_lock0 |= 1 << rd_lock_key_slot_3 + else: + if flash_encryp_type == 4 or flash_encryp_type == 5 or flash_encryp_type == 6: + efuse_data[keyslot2:keyslot3_end] = flash_key + efuse_mask_data[keyslot2:keyslot3_end] = mask_4bytes * 8 + rw_lock0 |= 1 << wr_lock_key_slot_3 + rw_lock0 |= 1 << rd_lock_key_slot_3 + rw_lock0 |= 1 << wr_lock_key_slot_2 + rw_lock0 |= 1 << rd_lock_key_slot_2 + if sec_eng_key is not None: + if flash_encryp_type == 0: + if sec_eng_key_sel == 0: + efuse_data[keyslot2:keyslot3] = sec_eng_key[16:32] + efuse_data[keyslot3:keyslot3_end] = sec_eng_key[0:16] + efuse_mask_data[keyslot2:keyslot3_end] = mask_4bytes * 8 + rw_lock0 |= 1 << wr_lock_key_slot_2 + rw_lock0 |= 1 << wr_lock_key_slot_3 + rw_lock0 |= 1 << rd_lock_key_slot_2 + rw_lock0 |= 1 << rd_lock_key_slot_3 + if sec_eng_key_sel == 1: + efuse_data[keyslot3:keyslot3_end] = sec_eng_key[16:32] + efuse_data[keyslot4:keyslot5] = sec_eng_key[0:16] + efuse_mask_data[keyslot3:keyslot3_end] = mask_4bytes * 4 + efuse_mask_data[keyslot4:keyslot5] = mask_4bytes * 4 + rw_lock0 |= 1 << wr_lock_key_slot_3 + rw_lock1 |= 1 << wr_lock_key_slot_4 + rw_lock0 |= 1 << rd_lock_key_slot_3 + rw_lock1 |= 1 << rd_lock_key_slot_4 + if sec_eng_key_sel == 2: + efuse_data[keyslot4:keyslot5] = sec_eng_key[16:32] + efuse_data[keyslot2:keyslot3] = sec_eng_key[0:16] + efuse_mask_data[keyslot3:keyslot5] = mask_4bytes * 8 + rw_lock1 |= 1 << wr_lock_key_slot_4 + rw_lock0 |= 1 << wr_lock_key_slot_2 + rw_lock1 |= 1 << rd_lock_key_slot_4 + rw_lock0 |= 1 << rd_lock_key_slot_2 + if sec_eng_key_sel == 3: + efuse_data[keyslot4:keyslot5] = sec_eng_key[16:32] + efuse_data[keyslot2:keyslot3] = sec_eng_key[0:16] + efuse_mask_data[keyslot3:keyslot5] = mask_4bytes * 8 + rw_lock1 |= 1 << wr_lock_key_slot_4 + rw_lock0 |= 1 << wr_lock_key_slot_2 + rw_lock1 |= 1 << rd_lock_key_slot_4 + rw_lock0 |= 1 << rd_lock_key_slot_2 + if flash_encryp_type == 1: + if sec_eng_key_sel == 0: + efuse_data[keyslot5:keyslot6] = sec_eng_key[0:16] + efuse_mask_data[keyslot5:keyslot6] = mask_4bytes * 4 + rw_lock1 |= 1 << wr_lock_key_slot_5 + rw_lock1 |= 1 << rd_lock_key_slot_5 + if sec_eng_key_sel == 1: + efuse_data[keyslot4:keyslot5] = sec_eng_key[0:16] + efuse_mask_data[keyslot4:keyslot5] = mask_4bytes * 4 + rw_lock1 |= 1 << wr_lock_key_slot_4 + rw_lock1 |= 1 << rd_lock_key_slot_4 + if sec_eng_key_sel == 2: + if flash_key is not None: + pass + else: + efuse_data[keyslot3:keyslot3_end] = sec_eng_key[0:16] + efuse_mask_data[keyslot3:keyslot3_end] = mask_4bytes * 4 + rw_lock0 |= 1 << wr_lock_key_slot_3 + rw_lock0 |= 1 << rd_lock_key_slot_3 + if sec_eng_key_sel == 3: + if flash_key is not None: + pass + else: + efuse_data[keyslot2:keyslot3] = sec_eng_key[0:16] + efuse_mask_data[keyslot2:keyslot3] = mask_4bytes * 4 + rw_lock0 |= 1 << wr_lock_key_slot_2 + rw_lock0 |= 1 << rd_lock_key_slot_2 + if flash_encryp_type == 2 or flash_encryp_type == 3 or flash_encryp_type == 4 or flash_encryp_type == 5 or flash_encryp_type == 6: + if sec_eng_key_sel == 0: + efuse_data[keyslot6:keyslot7] = sec_eng_key[16:32] + efuse_data[keyslot10:keyslot10_end] = sec_eng_key[0:16] + efuse_mask_data[keyslot6:keyslot7] = mask_4bytes * 4 + efuse_mask_data[keyslot10:keyslot10_end] = mask_4bytes * 4 + rw_lock1 |= 1 << wr_lock_key_slot_6 + rw_lock1 |= 1 << wr_lock_key_slot_10 + rw_lock1 |= 1 << rd_lock_key_slot_6 + rw_lock1 |= 1 << rd_lock_key_slot_10 + if sec_eng_key_sel == 1: + efuse_data[keyslot10:keyslot10_end] = sec_eng_key[16:32] + efuse_data[keyslot6:keyslot7] = sec_eng_key[0:16] + efuse_mask_data[keyslot6:keyslot7] = mask_4bytes * 4 + efuse_mask_data[keyslot10:keyslot10_end] = mask_4bytes * 4 + rw_lock1 |= 1 << wr_lock_key_slot_6 + rw_lock1 |= 1 << wr_lock_key_slot_10 + rw_lock1 |= 1 << rd_lock_key_slot_6 + rw_lock1 |= 1 << rd_lock_key_slot_10 + if sec_eng_key_sel == 2: + if flash_key is not None: + pass + else: + efuse_data[keyslot2:keyslot3] = sec_eng_key[16:32] + efuse_data[keyslot3:keyslot3_end] = sec_eng_key[0:16] + efuse_mask_data[keyslot2:keyslot3_end] = mask_4bytes * 8 + rw_lock0 |= 1 << wr_lock_key_slot_2 + rw_lock0 |= 1 << rd_lock_key_slot_2 + rw_lock0 |= 1 << wr_lock_key_slot_3 + rw_lock0 |= 1 << rd_lock_key_slot_3 + if sec_eng_key_sel == 3: + if flash_key is not None: + pass + else: + efuse_data[keyslot2:keyslot3_end] = sec_eng_key + efuse_mask_data[keyslot2:keyslot3_end] = mask_4bytes * 8 + rw_lock0 |= 1 << wr_lock_key_slot_2 + rw_lock0 |= 1 << rd_lock_key_slot_2 + rw_lock0 |= 1 << wr_lock_key_slot_3 + rw_lock0 |= 1 << rd_lock_key_slot_3 + efuse_data[124:128] = bytearray_data_merge(efuse_data[124:128], bflb_utils.int_to_4bytearray_l(rw_lock0), 4) + efuse_mask_data[124:128] = bytearray_data_merge(efuse_mask_data[124:128], bflb_utils.int_to_4bytearray_l(rw_lock0), 4) + efuse_data[252:256] = bytearray_data_merge(efuse_data[252:256], bflb_utils.int_to_4bytearray_l(rw_lock1), 4) + efuse_mask_data[252:256] = bytearray_data_merge(efuse_mask_data[252:256], bflb_utils.int_to_4bytearray_l(rw_lock1), 4) + if security is True: + bflb_utils.printf('Encrypt efuse data') + security_key, security_iv = bflb_utils.get_security_key() + efuse_data = img_create_encrypt_data(efuse_data, security_key, security_iv, 0) + efuse_data = bytearray(4096) + efuse_data + fp = open(cfg.get('Img_Group0_Cfg', 'efuse_file'), 'wb+') + fp.write(efuse_data) + fp.close() + fp = open(cfg.get('Img_Group0_Cfg', 'efuse_mask_file'), 'wb+') + fp.write(efuse_mask_data) + fp.close() + + +def img_update_efuse_group1(cfg, sign, pk_hash, flash_encryp_type, flash_key, sec_eng_key_sel, sec_eng_key, security=False): + fp = open(cfg.get('Img_Group1_Cfg', 'efuse_file'), 'rb') + efuse_data = bytearray(fp.read()) + bytearray(0) + fp.close() + fp = open(cfg.get('Img_Group1_Cfg', 'efuse_mask_file'), 'rb') + efuse_mask_data = bytearray(fp.read()) + bytearray(0) + fp.close() + mask_4bytes = bytearray.fromhex('FFFFFFFF') + if flash_encryp_type >= 3: + efuse_data[0] |= 3 + else: + efuse_data[0] |= flash_encryp_type + if sign > 0: + efuse_data[93] |= sign + efuse_mask_data[93] |= 255 + if flash_encryp_type > 0: + efuse_data[0] |= 48 + efuse_mask_data[0] |= 255 + rw_lock0 = 0 + rw_lock1 = 0 + if pk_hash is not None: + efuse_data[keyslot8:keyslot10] = pk_hash + efuse_mask_data[keyslot8:keyslot10] = mask_4bytes * 8 + rw_lock1 |= 1 << wr_lock_key_slot_8 + rw_lock1 |= 1 << wr_lock_key_slot_9 + if flash_key is not None: + if flash_encryp_type == 1: + efuse_data[keyslot3:keyslot3_end] = flash_key[0:16] + efuse_mask_data[keyslot3:keyslot3_end] = mask_4bytes * 4 + rw_lock0 |= 1 << wr_lock_key_slot_3 + rw_lock0 |= 1 << rd_lock_key_slot_3 + else: + pass + if flash_encryp_type == 2: + efuse_data[keyslot4:keyslot6] = flash_key + efuse_mask_data[keyslot4:keyslot6] = mask_4bytes * 8 + rw_lock1 |= 1 << wr_lock_key_slot_4 + rw_lock1 |= 1 << wr_lock_key_slot_5 + rw_lock1 |= 1 << rd_lock_key_slot_4 + rw_lock1 |= 1 << rd_lock_key_slot_5 + else: + if flash_encryp_type == 3: + efuse_data[keyslot4:keyslot6] = flash_key + efuse_mask_data[keyslot4:keyslot6] = mask_4bytes * 8 + rw_lock1 |= 1 << wr_lock_key_slot_4 + rw_lock1 |= 1 << wr_lock_key_slot_5 + rw_lock1 |= 1 << rd_lock_key_slot_4 + rw_lock1 |= 1 << rd_lock_key_slot_5 + else: + if flash_encryp_type == 4 or flash_encryp_type == 5 or flash_encryp_type == 6: + efuse_data[keyslot4:keyslot6] = flash_key + efuse_mask_data[keyslot4:keyslot6] = mask_4bytes * 8 + rw_lock1 |= 1 << wr_lock_key_slot_4 + rw_lock1 |= 1 << wr_lock_key_slot_5 + rw_lock1 |= 1 << rd_lock_key_slot_4 + rw_lock1 |= 1 << rd_lock_key_slot_5 + if sec_eng_key is not None: + if flash_encryp_type == 0: + if sec_eng_key_sel == 0: + efuse_data[keyslot5:keyslot6] = sec_eng_key[16:32] + efuse_data[keyslot6:keyslot7] = sec_eng_key[0:16] + efuse_mask_data[keyslot5:keyslot7] = mask_4bytes * 8 + rw_lock1 |= 1 << wr_lock_key_slot_5 + rw_lock1 |= 1 << wr_lock_key_slot_6 + rw_lock1 |= 1 << rd_lock_key_slot_5 + rw_lock1 |= 1 << rd_lock_key_slot_6 + if sec_eng_key_sel == 1: + efuse_data[keyslot6:keyslot7] = sec_eng_key[16:32] + efuse_data[keyslot7:keyslot8] = sec_eng_key[0:16] + efuse_mask_data[keyslot6:keyslot8] = mask_4bytes * 8 + rw_lock1 |= 1 << wr_lock_key_slot_6 + rw_lock1 |= 1 << wr_lock_key_slot_7 + rw_lock1 |= 1 << rd_lock_key_slot_6 + rw_lock1 |= 1 << rd_lock_key_slot_7 + if sec_eng_key_sel == 2: + efuse_data[keyslot7:keyslot8] = sec_eng_key[16:32] + efuse_data[keyslot5:keyslot6] = sec_eng_key[0:16] + efuse_mask_data[keyslot7:keyslot8] = mask_4bytes * 4 + efuse_mask_data[keyslot5:keyslot6] = mask_4bytes * 4 + rw_lock1 |= 1 << wr_lock_key_slot_7 + rw_lock1 |= 1 << wr_lock_key_slot_5 + rw_lock1 |= 1 << rd_lock_key_slot_7 + rw_lock1 |= 1 << rd_lock_key_slot_5 + if sec_eng_key_sel == 3: + efuse_data[keyslot7:keyslot8] = sec_eng_key[16:32] + efuse_data[keyslot5:keyslot6] = sec_eng_key[0:16] + efuse_mask_data[keyslot7:keyslot8] = mask_4bytes * 4 + efuse_mask_data[keyslot5:keyslot6] = mask_4bytes * 4 + rw_lock1 |= 1 << wr_lock_key_slot_7 + rw_lock1 |= 1 << wr_lock_key_slot_5 + rw_lock1 |= 1 << rd_lock_key_slot_7 + rw_lock1 |= 1 << rd_lock_key_slot_5 + if flash_encryp_type == 1: + if sec_eng_key_sel == 0: + efuse_data[keyslot7:keyslot8] = sec_eng_key[0:16] + efuse_mask_data[keyslot7:keyslot8] = mask_4bytes * 4 + rw_lock1 |= 1 << wr_lock_key_slot_7 + rw_lock1 |= 1 << rd_lock_key_slot_7 + if sec_eng_key_sel == 1: + efuse_data[keyslot6:keyslot7] = sec_eng_key[0:16] + efuse_mask_data[keyslot6:keyslot7] = mask_4bytes * 4 + rw_lock1 |= 1 << wr_lock_key_slot_6 + rw_lock1 |= 1 << rd_lock_key_slot_6 + if sec_eng_key_sel == 2: + if flash_key is not None: + pass + else: + efuse_data[keyslot3:keyslot3_end] = sec_eng_key[0:16] + efuse_mask_data[keyslot3:keyslot3_end] = mask_4bytes * 4 + rw_lock0 |= 1 << wr_lock_key_slot_3 + rw_lock0 |= 1 << rd_lock_key_slot_3 + if sec_eng_key_sel == 3: + if flash_key is not None: + pass + else: + efuse_data[keyslot2:keyslot3] = sec_eng_key[0:16] + efuse_mask_data[keyslot2:keyslot3] = mask_4bytes * 4 + rw_lock0 |= 1 << wr_lock_key_slot_2 + rw_lock0 |= 1 << rd_lock_key_slot_2 + if flash_encryp_type == 2 or flash_encryp_type == 3 or flash_encryp_type == 4 or flash_encryp_type == 5 or flash_encryp_type == 6: + if sec_eng_key_sel == 0: + efuse_data[keyslot7:keyslot8] = sec_eng_key[16:32] + efuse_data[keyslot11:keyslot11_end] = sec_eng_key[0:16] + efuse_mask_data[keyslot7:keyslot8] = mask_4bytes * 4 + efuse_mask_data[keyslot11:keyslot11_end] = mask_4bytes * 4 + rw_lock1 |= 1 << wr_lock_key_slot_7 + rw_lock0 |= 1 << rd_lock_key_slot_11 + rw_lock1 |= 1 << wr_lock_key_slot_7 + rw_lock0 |= 1 << rd_lock_key_slot_11 + if sec_eng_key_sel == 1: + efuse_data[keyslot11:keyslot11_end] = sec_eng_key[16:32] + efuse_data[keyslot7:keyslot8] = sec_eng_key[0:16] + efuse_mask_data[keyslot7:keyslot8] = mask_4bytes * 4 + efuse_mask_data[keyslot11:keyslot11_end] = mask_4bytes * 4 + rw_lock1 |= 1 << wr_lock_key_slot_7 + rw_lock0 |= 1 << rd_lock_key_slot_11 + rw_lock1 |= 1 << wr_lock_key_slot_7 + rw_lock0 |= 1 << rd_lock_key_slot_11 + if sec_eng_key_sel == 2: + if flash_key is not None: + pass + else: + efuse_data[keyslot4:keyslot5] = sec_eng_key[16:32] + efuse_data[keyslot5:keyslot6] = sec_eng_key[0:16] + efuse_mask_data[keyslot4:keyslot6] = mask_4bytes * 8 + rw_lock1 |= 1 << wr_lock_key_slot_4 + rw_lock1 |= 1 << wr_lock_key_slot_5 + rw_lock1 |= 1 << rd_lock_key_slot_4 + rw_lock1 |= 1 << rd_lock_key_slot_5 + if sec_eng_key_sel == 3: + if flash_key is not None: + pass + else: + efuse_data[keyslot4:keyslot6] = sec_eng_key + efuse_mask_data[keyslot4:keyslot6] = mask_4bytes * 8 + rw_lock1 |= 1 << wr_lock_key_slot_4 + rw_lock1 |= 1 << wr_lock_key_slot_5 + rw_lock1 |= 1 << rd_lock_key_slot_4 + rw_lock1 |= 1 << rd_lock_key_slot_5 + efuse_data[124:128] = bytearray_data_merge(efuse_data[124:128], bflb_utils.int_to_4bytearray_l(rw_lock0), 4) + efuse_mask_data[124:128] = bytearray_data_merge(efuse_mask_data[124:128], bflb_utils.int_to_4bytearray_l(rw_lock0), 4) + efuse_data[252:256] = bytearray_data_merge(efuse_data[252:256], bflb_utils.int_to_4bytearray_l(rw_lock1), 4) + efuse_mask_data[252:256] = bytearray_data_merge(efuse_mask_data[252:256], bflb_utils.int_to_4bytearray_l(rw_lock1), 4) + if security is True: + bflb_utils.printf('Encrypt efuse data') + security_key, security_iv = bflb_utils.get_security_key() + efuse_data = img_create_encrypt_data(efuse_data, security_key, security_iv, 0) + efuse_data = bytearray(4096) + efuse_data + fp = open(cfg.get('Img_Group1_Cfg', 'efuse_file'), 'wb+') + fp.write(efuse_data) + fp.close() + fp = open(cfg.get('Img_Group1_Cfg', 'efuse_mask_file'), 'wb+') + fp.write(efuse_mask_data) + fp.close() + + +def img_create_get_sign_encrypt_info(bootheader_data): + sign = bootheader_data[bootcfg_start] & 3 + encrypt = bootheader_data[bootcfg_start] >> 2 & 3 + key_sel = bootheader_data[bootcfg_start] >> 4 & 3 + xts_mode = bootheader_data[bootcfg_start] >> 6 & 1 + return ( + sign, encrypt, key_sel, xts_mode) + + +def img_create_get_img_start_addr(bootheader_data): + bootentry = [] + bootentry.append(bflb_utils.bytearray_to_int(bflb_utils.bytearray_reverse(bootheader_data[bootcpucfg_start + bootcpucfg_length * bootcpucfg_m0_index_number + 16:bootcpucfg_start + bootcpucfg_length * bootcpucfg_m0_index_number + 16 + 4]))) + bootentry.append(bflb_utils.bytearray_to_int(bflb_utils.bytearray_reverse(bootheader_data[bootcpucfg_start + bootcpucfg_length * bootcpucfg_d0_index_number + 16:bootcpucfg_start + bootcpucfg_length * bootcpucfg_d0_index_number + 16 + 4]))) + bootentry.append(bflb_utils.bytearray_to_int(bflb_utils.bytearray_reverse(bootheader_data[bootcpucfg_start + bootcpucfg_length * bootcpucfg_lp_index_number + 16:bootcpucfg_start + bootcpucfg_length * bootcpucfg_lp_index_number + 16 + 4]))) + return bootentry + + +def img_create_flash_default_data(length): + datas = bytearray(length) + for i in range(length): + datas[i] = 255 + + return datas + + +def img_get_file_data(files): + datas = [] + for file in files: + if file == 'UNUSED': + datas.append(bytearray(0)) + continue + else: + with open(file, 'rb') as fp: + data = fp.read() + datas.append(data) + + return datas + + +def img_get_largest_addr(addrs, files): + min = 67108863 + maxlen = 0 + datalen = 0 + for i in range(len(addrs)): + if files[i] == 'UNUSED': + continue + else: + addr = addrs[i] & 67108863 + if addr >= maxlen: + maxlen = addr + datalen = os.path.getsize(files[i]) + if addr <= min: + min = addr + + if maxlen == 0: + if datalen == 0: + return (0, 0) + return ( + maxlen + datalen - min, min) + + +def img_get_one_group_img(d_addrs, d_files): + whole_img_len, min = img_get_largest_addr(d_addrs, d_files) + whole_img_len &= 67108863 + whole_img_data = img_create_flash_default_data(whole_img_len) + filedatas = img_get_file_data(d_files) + for i in range(len(d_addrs)): + if d_files[i] == 'UNUSED': + continue + else: + start_addr = d_addrs[i] + start_addr &= 67108863 + start_addr -= min + whole_img_data[start_addr:start_addr + len(filedatas[i])] = filedatas[i] + + return whole_img_data + + +def img_create_get_hash_ignore(bootheader_data): + return bootheader_data[bootcfg_start + 2] >> 1 & 1 + + +def img_create_get_crc_ignore(bootheader_data): + return bootheader_data[bootcfg_start + 2] & 1 + + +def img_create_update_bootheader_if(bootheader_data, hash, seg_cnt): + bootheader_data[bootcfg_start + 12:bootcfg_start + 12 + 4] = bflb_utils.int_to_4bytearray_l(seg_cnt) + sign = bootheader_data[bootcfg_start] & 3 + encrypt = bootheader_data[bootcfg_start] >> 2 & 3 + key_sel = bootheader_data[bootcfg_start] >> 4 & 3 + xts_mode = bootheader_data[bootcfg_start] >> 6 & 1 + if bootheader_data[bootcfg_start + 2] >> 1 & 1 == 1 and sign == 0: + bflb_utils.printf('Hash ignored') + else: + bootheader_data[bootcfg_start + 16:bootcfg_start + 16 + 32] = hash + if bootheader_data[bootcfg_start + 2] & 1 == 1: + bflb_utils.printf('Header crc ignored') + else: + hd_crcarray = bflb_utils.get_crc32_bytearray(bootheader_data[0:header_len - 4]) + bootheader_data[header_len - 4:header_len] = hd_crcarray + bflb_utils.printf('Header crc: ', binascii.hexlify(hd_crcarray)) + return bootheader_data + + +def img_create_update_bootheader(bootheader_data, hash, seg_cnt, flashcfg_table_addr, flashcfg_table_len): + bootheader_data[flashcfg_table_start:flashcfg_table_start + 4] = bflb_utils.int_to_4bytearray_l(flashcfg_table_addr) + bootheader_data[flashcfg_table_start + 4:flashcfg_table_start + 8] = bflb_utils.int_to_4bytearray_l(flashcfg_table_len) + bootheader_data[bootcfg_start + 12:bootcfg_start + 12 + 4] = bflb_utils.int_to_4bytearray_l(seg_cnt) + sign, encrypt, key_sel, xts_mode = img_create_get_sign_encrypt_info(bootheader_data) + if img_create_get_hash_ignore(bootheader_data) == 1 and sign == 0: + bflb_utils.printf('Hash ignored') + else: + bootheader_data[bootcfg_start + 16:bootcfg_start + 16 + 32] = hash + if img_create_get_crc_ignore(bootheader_data) == 1: + bflb_utils.printf('Header crc ignored') + else: + hd_crcarray = bflb_utils.get_crc32_bytearray(bootheader_data[0:header_len - 4]) + bootheader_data[header_len - 4:header_len] = hd_crcarray + bflb_utils.printf('Header crc: ', binascii.hexlify(hd_crcarray)) + return bootheader_data[0:header_len] + + +def img_create_update_segheader(segheader, segdatalen, segdatacrc): + segheader[4:8] = segdatalen + segheader[8:12] = segdatacrc + return segheader + + +def reverse_str_data_unit_number(str_data_unit_number): + """ + high position low data + data unit number:00000280 + storage format: 80020000 + """ + reverse_str = '' + if len(str_data_unit_number) == 8: + str_part1 = str_data_unit_number[0:2] + str_part2 = str_data_unit_number[2:4] + str_part3 = str_data_unit_number[4:6] + str_part4 = str_data_unit_number[6:8] + reverse_str = str_part4 + str_part3 + str_part2 + str_part1 + return reverse_str + + +def reverse_iv(need_reverse_iv_bytearray): + temp_reverse_iv_bytearray = binascii.hexlify(need_reverse_iv_bytearray).decode() + if temp_reverse_iv_bytearray[24:32] != '00000000': + bflb_utils.printf('The lower 4 bytes of IV should be set 0, if set IV is less than 16 bytes, make up 0 for the low 4 bytes of IV ') + sys.exit() + reverse_iv_bytearray = '00000000' + temp_reverse_iv_bytearray[0:24] + return reverse_iv_bytearray + + +def img_create_encrypt_data_xts(data_bytearray, key_bytearray, iv_bytearray, encrypt): + counter = binascii.hexlify(iv_bytearray[4:16]).decode() + data_unit_number = 0 + key = ( + key_bytearray[0:16], key_bytearray[16:32]) + if encrypt == 2 or encrypt == 3: + key = ( + key_bytearray, key_bytearray) + cipher = AES_XTS.new(key, AES_XTS.MODE_XTS) + total_len = len(data_bytearray) + ciphertext = bytearray(0) + deal_len = 0 + while deal_len < total_len: + data_unit_number = str(hex(data_unit_number)).replace('0x', '') + data_unit_number_to_str = str(data_unit_number) + right_justify_str = data_unit_number_to_str.rjust(8, '0') + reverse_data_unit_number_str = reverse_str_data_unit_number(right_justify_str) + tweak = reverse_data_unit_number_str + counter + tweak = bflb_utils.hexstr_to_bytearray('0' * (32 - len(tweak)) + tweak) + if 32 + deal_len <= total_len: + cur_block = data_bytearray[0 + deal_len:32 + deal_len] + ciphertext += cipher.encrypt(cur_block, tweak) + else: + cur_block = data_bytearray[0 + deal_len:16 + deal_len] + bytearray(16) + ciphertext += cipher.encrypt(cur_block, tweak)[0:16] + deal_len += 32 + data_unit_number = int(data_unit_number, 16) + data_unit_number += 1 + + return ciphertext + + +def img_create_sign_data(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() + bflb_utils.printf('Private key: ', binascii.hexlify(sk.to_string())) + bflb_utils.printf('Public key: ', binascii.hexlify(pk_data)) + pk_hash = img_create_sha256_data(pk_data) + bflb_utils.printf('Public key hash=', binascii.hexlify(pk_hash)) + signature = sk.sign(data_bytearray, hashfunc=(hashlib.sha256), sigencode=(ecdsa.util.sigencode_string)) + bflb_utils.printf('Signature=', binascii.hexlify(signature)) + len_array = bflb_utils.int_to_4bytearray_l(len(signature)) + sig_field = len_array + signature + crcarray = bflb_utils.get_crc32_bytearray(sig_field) + return ( + pk_data, pk_hash, sig_field + crcarray) + + +def img_create_read_file_append_crc(file, crc): + fp = open(file, 'rb') + read_data = bytearray(fp.read()) + crcarray = bytearray(0) + if crc: + crcarray = bflb_utils.get_crc32_bytearray(read_data) + fp.close() + return read_data + crcarray + + +def encrypt_loader_bin_do(file, sign, encrypt, temp_encrypt_key, temp_encrypt_iv, publickey_file, privatekey_file): + if encrypt != 0 or sign != 0: + encrypt_key = bytearray(0) + encrypt_iv = bytearray(0) + load_helper_bin_header = bytearray(0) + load_helper_bin_body = bytearray(0) + offset = bootcfg_start + sign_pos = 0 + encrypt_type_pos = 2 + pk_data = bytearray(0) + signature = bytearray(0) + aesiv_data = bytearray(0) + data_tohash = bytearray(0) + with open(file, 'rb') as fp: + load_helper_bin = fp.read() + load_helper_bin_header = load_helper_bin[0:header_len] + load_helper_bin_body = load_helper_bin[header_len:] + if load_helper_bin_header != bytearray(0): + if load_helper_bin_body != bytearray(0): + load_helper_bin_body = bflb_utils.add_to_16(load_helper_bin_body) + if encrypt != 0: + encrypt_key = bflb_utils.hexstr_to_bytearray(temp_encrypt_key) + encrypt_iv = bflb_utils.hexstr_to_bytearray(temp_encrypt_iv) + iv_crcarray = bflb_utils.get_crc32_bytearray(encrypt_iv) + aesiv_data = encrypt_iv + iv_crcarray + data_tohash = data_tohash + aesiv_data + load_helper_bin_body_encrypt = bflb_utils.img_create_encrypt_data(load_helper_bin_body, encrypt_key, encrypt_iv, 0) + else: + load_helper_bin_body_encrypt = load_helper_bin_body + data = bytearray(load_helper_bin_header) + oldval = bflb_utils.bytearray_to_int(bflb_utils.bytearray_reverse(data[offset:offset + 4])) + newval = oldval + if encrypt != 0: + newval = newval | 1 << encrypt_type_pos + if sign != 0: + newval = newval | 1 << sign_pos + data_tohash += load_helper_bin_body_encrypt + pk_data, pk_hash, signature = img_create_sign_data(data_tohash, privatekey_file, publickey_file) + pk_data = pk_data + bflb_utils.get_crc32_bytearray(pk_data) + data[offset:offset + 4] = bflb_utils.int_to_4bytearray_l(newval) + load_helper_bin_header = data + load_helper_bin_encrypt = load_helper_bin_header + pk_data + signature + aesiv_data + load_helper_bin_body_encrypt + hashfun = hashlib.sha256() + hashfun.update(load_helper_bin_body_encrypt) + hash = bflb_utils.hexstr_to_bytearray(hashfun.hexdigest()) + load_helper_bin_data = bytearray(load_helper_bin_encrypt) + load_helper_bin_encrypt = img_create_update_bootheader_if(load_helper_bin_data, hash, 1) + return ( + True, load_helper_bin_encrypt) + return (False, None) + + +def img_creat_process(group_type, flash_img, cfg, security=False): + encrypt_blk_size = 16 + padding = bytearray(encrypt_blk_size) + data_tohash = bytearray(0) + cfg_section = '' + if group_type == 'group0': + img_update_efuse_fun = img_update_efuse_group0 + cfg_section = 'Img_Group0_Cfg' + else: + if group_type == 'group1': + img_update_efuse_fun = img_update_efuse_group1 + cfg_section = 'Img_Group1_Cfg' + else: + bflb_utils.printf('group type wrong') + return ( + 'FAIL', data_tohash) + 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('|'): + if files: + segdata_file.append(str(files)) + + boot_header_file = cfg.get(cfg_section, 'boot_header_file') + bootheader_data = img_create_read_file_append_crc(boot_header_file, 0) + encrypt = 0 + sign, encrypt, key_sel, xts_mode = img_create_get_sign_encrypt_info(bootheader_data) + boot_entry = img_create_get_img_start_addr(bootheader_data) + aesiv_data = bytearray(0) + pk_data = bytearray(0) + publickey_file = '' + privatekey_file_uecc = '' + if sign != 0: + bflb_utils.printf('Image need sign') + publickey_file = cfg.get(cfg_section, 'publickey_file') + privatekey_file_uecc = cfg.get(cfg_section, 'privatekey_file_uecc') + if encrypt != 0: + bflb_utils.printf('Image need encrypt ', encrypt) + if xts_mode == 1: + bflb_utils.printf('Enable xts mode') + encrypt_key_org = bflb_utils.hexstr_to_bytearray(cfg.get(cfg_section, 'aes_key_org')) + if encrypt == 1: + if xts_mode == 1: + encrypt_key = encrypt_key_org[0:32] + else: + encrypt_key = encrypt_key_org[0:16] + else: + if encrypt == 2: + if xts_mode == 1: + encrypt_key = encrypt_key_org[0:32] + else: + encrypt_key = encrypt_key_org[0:32] + else: + if encrypt == 3: + if xts_mode == 1: + encrypt_key = encrypt_key_org[0:24] + else: + encrypt_key = encrypt_key_org[0:24] + bflb_utils.printf('Key= ', binascii.hexlify(encrypt_key)) + iv_value = cfg.get(cfg_section, 'aes_iv') + if xts_mode == 1: + iv_value = iv_value[24:32] + iv_value[:24] + encrypt_iv = bflb_utils.hexstr_to_bytearray(iv_value) + iv_crcarray = bflb_utils.get_crc32_bytearray(encrypt_iv) + aesiv_data = encrypt_iv + iv_crcarray + data_tohash = data_tohash + aesiv_data + seg_cnt = len(segheader_file) + segdata_cnt = len(segdata_file) + if flash_img == 0: + if seg_cnt != segdata_cnt: + bflb_utils.printf('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: + seg_data = bytearray(0) + if segdata_file[i] != 'UNUSED': + seg_data = img_create_read_file_append_crc(segdata_file[i], 0) + else: + 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 = bflb_utils.get_crc32_bytearray(seg_data) + seg_data_list.append(seg_data) + seg_header = img_create_read_file_append_crc(segheader_file[i], 0) + seg_header = img_create_update_segheader(seg_header, bflb_utils.int_to_4bytearray_l(len(seg_data)), segdata_crcarray) + segheader_crcarray = bflb_utils.get_crc32_bytearray(seg_header) + seg_header = seg_header + segheader_crcarray + seg_header_list.append(seg_header) + i = i + 1 + + i = 0 + cnt = 0 + while i < seg_cnt: + if seg_header_list[i][4:8] != bytearray(4): + data_toencrypt += seg_header_list[i] + data_toencrypt += seg_data_list[i] + cnt += 1 + else: + i += 1 + + seg_cnt = cnt + else: + seg_data = img_get_one_group_img(boot_entry, segdata_file) + 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) + if encrypt != 0: + unencrypt_mfg_data = bytearray(0) + if seg_cnt >= 8192: + if data_toencrypt[4096:4100] == bytearray('0mfg'.encode('utf-8')): + unencrypt_mfg_data = data_toencrypt[4096:8192] + if xts_mode != 0: + data_toencrypt = img_create_encrypt_data_xts(data_toencrypt, encrypt_key, encrypt_iv, encrypt) + else: + data_toencrypt = img_create_encrypt_data(data_toencrypt, encrypt_key, encrypt_iv, flash_img) + if unencrypt_mfg_data != bytearray(0): + data_toencrypt = data_toencrypt[0:4096] + unencrypt_mfg_data + data_toencrypt[8192:] + fw_data = bytearray(0) + data_tohash += data_toencrypt + fw_data = data_toencrypt + hash = img_create_sha256_data(data_tohash) + bflb_utils.printf('Image hash is ', binascii.hexlify(hash)) + 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 + bflb_utils.get_crc32_bytearray(pk_data) + flashCfgAddr = len(bootheader_data + pk_data + pk_data + signature + signature + aesiv_data) + flashCfgListLen = 0 + flashCfgList = bytearray(0) + flashCfgTable = bytearray(0) + if flash_img == 1: + if bootheader_data[25:26] == b'\xff': + flashCfgList, flashCfgTable, flashCfgListLen = create_flashcfg_table(flashCfgAddr) + bootheader_data = img_create_update_bootheader(bootheader_data, hash, seg_cnt, flashCfgAddr, flashCfgListLen) + if flash_img == 1: + bflb_utils.printf('Write flash img') + bootinfo_file_name = cfg.get(cfg_section, 'bootinfo_file') + fp = open(bootinfo_file_name, 'wb+') + bootinfo = bootheader_data + pk_data + pk_data + signature + signature + aesiv_data + flashCfgList + flashCfgTable + 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() + fw_data_hash = img_create_sha256_data(fw_data) + fp = open(fw_file_name.replace('.bin', '_withhash.bin'), 'wb+') + fp.write(fw_data + fw_data_hash) + fp.close() + if encrypt != 0: + flash_encrypt_type = 0 + if encrypt == 1: + flash_encrypt_type = 1 + if encrypt == 2: + flash_encrypt_type = 3 + if encrypt == 3: + flash_encrypt_type = 2 + if xts_mode == 1: + flash_encrypt_type += 3 + img_update_efuse_fun(cfg, sign, pk_hash, flash_encrypt_type, encrypt_key + bytearray(32 - len(encrypt_key)), key_sel, None, security) + else: + img_update_efuse_fun(cfg, sign, pk_hash, encrypt, None, key_sel, None, security) + else: + bflb_utils.printf('Write if img') + whole_img_file_name = cfg.get(cfg_section, 'whole_img_file') + fp = open(whole_img_file_name, 'wb+') + img_data = bootheader_data + pk_data + pk_data + signature + signature + aesiv_data + fw_data + fp.write(img_data) + fp.close() + if encrypt != 0: + if_encrypt_type = 0 + if encrypt == 1: + if_encrypt_type = 1 + if encrypt == 2: + if_encrypt_type = 3 + if encrypt == 3: + if_encrypt_type = 2 + if xts_mode == 1: + if_encrypt_type += 3 + img_update_efuse_fun(cfg, sign, pk_hash, if_encrypt_type, None, key_sel, encrypt_key + bytearray(32 - len(encrypt_key)), security) + else: + img_update_efuse_fun(cfg, sign, pk_hash, 0, None, key_sel, bytearray(32), security) + return ( + 'OK', data_tohash) + + +def img_create_do(args, img_dir_path=None, config_file=None): + bflb_utils.printf('Image create path: ', img_dir_path) + if config_file is None: + config_file = img_dir_path + '/img_create_cfg.ini' + bflb_utils.printf('Config file: ', config_file) + cfg = BFConfigParser() + cfg.read(config_file) + group_type = 'all' + img_type = 'media' + signer = 'none' + security = False + data_tohash = bytearray(0) + try: + if args.image: + img_type = args.image + if args.group: + group_type = args.group + if args.signer: + signer = args.signer + if args.security: + security = args.security == 'efuse' + except Exception as e: + try: + bflb_utils.printf(e) + finally: + e = None + del e + + if img_type == 'media': + flash_img = 1 + else: + flash_img = 0 + ret0 = ret1 = 'OK' + if group_type == 'group0': + ret0, data_tohash0 = img_creat_process('group0', flash_img, cfg, security) + else: + if group_type == 'group1': + ret1, data_tohash1 = img_creat_process('group1', flash_img, cfg, security) + else: + if group_type == 'all': + ret0, data_tohash0 = img_creat_process('group0', flash_img, cfg, False) + ret1, data_tohash1 = img_creat_process('group1', flash_img, cfg, security) + else: + img_creat_process('', flash_img, cfg, security) + if ret0 != 'OK': + bflb_utils.printf('Fail to create group0 images!') + return + if ret1 != 'OK': + bflb_utils.printf('Fail to create group1 images!') + + +def create_sp_media_image(config, cpu_type=None, security=False): + bflb_utils.printf('========= sp image create =========') + cfg = BFConfigParser() + cfg.read(config) + if cpu_type == 'Group1': + img_creat_process('group1', 1, cfg, security) + else: + img_creat_process('group0', 1, cfg, security) + + +if __name__ == '__main__': + data_bytearray = codecs.decode('42464E500100000046434647040101036699FF039F00B7E904EF0001C72052D8060232000B010B013B01BB006B01EB02EB02025000010001010002010101AB01053500000131000038FF20FF77030240770302F02C01B004B0040500FFFF030036C3DD9E5043464704040001010105000101050000010101A612AC86000144650020000000000000503100007A6345494BCABEC7307FD8F8396729EB67DDC8C63B7AD69B797B08564E982A8701000000000000000000000000000000000000D80000000000010000000000000000000000200100000001D80000000000010000000000000000000000200200000002580000000000010000000000000000000000200300000003580000000000010000D0C57503C09E750300200400000004580000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000935F92BB', 'hex') + key_bytearray = codecs.decode('fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0000102030405060708090a0b0c0d0e0f', 'hex') + need_reverse_iv_bytearray = codecs.decode('01000000000000000000000000000000', 'hex') + iv_bytearray = codecs.decode(reverse_iv(need_reverse_iv_bytearray), 'hex') + img_create_encrypt_data_xts(data_bytearray, key_bytearray, iv_bytearray, 0) +# okay decompiling ./libs/base/bl808/img_create_do.pyc diff --git a/libs/base/bl808/jlink_load_cfg.py b/libs/base/bl808/jlink_load_cfg.py new file mode 100644 index 0000000..2874c08 --- /dev/null +++ b/libs/base/bl808/jlink_load_cfg.py @@ -0,0 +1,12 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/bl808/jlink_load_cfg.py +jlink_shake_hand_addr = '2204BBE8' +jlink_data_addr = '2204CC88' +jlink_load_addr = '22010000' +jlink_core_type = 'RISC-V' +jlink_set_tif = 0 +jlink_run_addr = '22010000' +# okay decompiling ./libs/base/bl808/jlink_load_cfg.pyc diff --git a/libs/base/bl808/openocd_load_cfg.py b/libs/base/bl808/openocd_load_cfg.py new file mode 100644 index 0000000..8738e24 --- /dev/null +++ b/libs/base/bl808/openocd_load_cfg.py @@ -0,0 +1,12 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/bl808/openocd_load_cfg.py +openocd_shake_hand_addr = '2204BBE8' +openocd_data_addr = '2204CC88' +openocd_load_addr = '22010000' +openocd_core_type = 'RISC-V' +openocd_set_tif = 0 +openocd_run_addr = '22010000' +# okay decompiling ./libs/base/bl808/openocd_load_cfg.pyc diff --git a/libs/base/wb03/bootheader_cfg_keys.py b/libs/base/wb03/bootheader_cfg_keys.py new file mode 100644 index 0000000..be0e4c5 --- /dev/null +++ b/libs/base/wb03/bootheader_cfg_keys.py @@ -0,0 +1,645 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/wb03/bootheader_cfg_keys.py +custom_config_len = 208 +clock_start_pos = 100 + custom_config_len +bootcfg_start_pos = 120 + custom_config_len +bootcfg_len = 48 +bootcpucfg_start_pos = bootcfg_start_pos + bootcfg_len +bootcpucfg_len = 16 +bootcpucfg_m0_index = 0 +bootcpucfg_d0_index = 1 +bootcpucfg_lp_index = 2 +boot2_start_pos = bootcpucfg_start_pos + bootcpucfg_len * (bootcpucfg_m0_index + 1) +boot2_len = 8 +flashcfg_table_start_pos = boot2_start_pos + boot2_len +flashcfg_table_len = 8 +patch_on_read_start_pos = flashcfg_table_start_pos + flashcfg_table_len +patch_on_read_len = 24 +patch_on_jump_start_pos = patch_on_read_start_pos + patch_on_read_len +patch_on_jump_len = 24 +rsvd_start_pos = patch_on_jump_start_pos + patch_on_jump_len +rsvd_len = 4 +crc32_start_pos = rsvd_start_pos + rsvd_len +bootheader_len = crc32_start_pos + 4 +bootheader_cfg_keys = {'custom_magic_code':{'offset':'0', + 'pos':'0', + 'bitlen':'32'}, + 'custom_crc32':{'offset':'4', + 'pos':'0', + 'bitlen':'32'}, + 'custom_vendor_id':{'offset':'8', + 'pos':'0', + 'bitlen':'32'}, + 'custom_version':{'offset':'12', + 'pos':'0', + 'bitlen':'32'}, + 'custom_vendor_boot_offset':{'offset':'16', + 'pos':'0', + 'bitlen':'32'}, + 'custom_vendor_boot_len':{'offset':'20', + 'pos':'0', + 'bitlen':'32'}, + 'custom_ecc_type':{'offset':'24', + 'pos':'0', + 'bitlen':'8'}, + 'custom_aes_type':{'offset':'24', + 'pos':'8', + 'bitlen':'8'}, + 'custom_rsvd2':{'offset':'24', + 'pos':'16', + 'bitlen':'16'}, + 'custom_hash_0':{'offset':'28', + 'pos':'0', + 'bitlen':'32'}, + 'custom_hash_1':{'offset':'32', + 'pos':'0', + 'bitlen':'32'}, + 'custom_hash_2':{'offset':'36', + 'pos':'0', + 'bitlen':'32'}, + 'custom_hash_3':{'offset':'40', + 'pos':'0', + 'bitlen':'32'}, + 'custom_hash_4':{'offset':'44', + 'pos':'0', + 'bitlen':'32'}, + 'custom_hash_5':{'offset':'48', + 'pos':'0', + 'bitlen':'32'}, + 'custom_hash_6':{'offset':'52', + 'pos':'0', + 'bitlen':'32'}, + 'custom_hash_7':{'offset':'56', + 'pos':'0', + 'bitlen':'32'}, + 'custom_signature_0':{'offset':'60', + 'pos':'0', + 'bitlen':'32'}, + 'custom_signature_1':{'offset':'64', + 'pos':'0', + 'bitlen':'32'}, + 'custom_signature_2':{'offset':'68', + 'pos':'0', + 'bitlen':'32'}, + 'custom_signature_3':{'offset':'72', + 'pos':'0', + 'bitlen':'32'}, + 'custom_signature_4':{'offset':'76', + 'pos':'0', + 'bitlen':'32'}, + 'custom_signature_5':{'offset':'80', + 'pos':'0', + 'bitlen':'32'}, + 'custom_signature_6':{'offset':'84', + 'pos':'0', + 'bitlen':'32'}, + 'custom_signature_7':{'offset':'88', + 'pos':'0', + 'bitlen':'32'}, + 'custom_signature_8':{'offset':'92', + 'pos':'0', + 'bitlen':'32'}, + 'custom_signature_9':{'offset':'96', + 'pos':'0', + 'bitlen':'32'}, + 'custom_signature_10':{'offset':'100', + 'pos':'0', + 'bitlen':'32'}, + 'custom_signature_11':{'offset':'104', + 'pos':'0', + 'bitlen':'32'}, + 'custom_signature_12':{'offset':'108', + 'pos':'0', + 'bitlen':'32'}, + 'custom_signature_13':{'offset':'112', + 'pos':'0', + 'bitlen':'32'}, + 'custom_signature_14':{'offset':'116', + 'pos':'0', + 'bitlen':'32'}, + 'custom_signature_15':{'offset':'120', + 'pos':'0', + 'bitlen':'32'}, + 'custom_pk_0':{'offset':'124', + 'pos':'0', + 'bitlen':'32'}, + 'custom_pk_1':{'offset':'128', + 'pos':'0', + 'bitlen':'32'}, + 'custom_pk_2':{'offset':'132', + 'pos':'0', + 'bitlen':'32'}, + 'custom_pk_3':{'offset':'136', + 'pos':'0', + 'bitlen':'32'}, + 'custom_pk_4':{'offset':'140', + 'pos':'0', + 'bitlen':'32'}, + 'custom_pk_5':{'offset':'144', + 'pos':'0', + 'bitlen':'32'}, + 'custom_pk_6':{'offset':'148', + 'pos':'0', + 'bitlen':'32'}, + 'custom_pk_7':{'offset':'152', + 'pos':'0', + 'bitlen':'32'}, + 'custom_pk_8':{'offset':'156', + 'pos':'0', + 'bitlen':'32'}, + 'custom_pk_9':{'offset':'160', + 'pos':'0', + 'bitlen':'32'}, + 'custom_pk_10':{'offset':'164', + 'pos':'0', + 'bitlen':'32'}, + 'custom_pk_11':{'offset':'168', + 'pos':'0', + 'bitlen':'32'}, + 'custom_pk_12':{'offset':'172', + 'pos':'0', + 'bitlen':'32'}, + 'custom_pk_13':{'offset':'176', + 'pos':'0', + 'bitlen':'32'}, + 'custom_pk_14':{'offset':'180', + 'pos':'0', + 'bitlen':'32'}, + 'custom_pk_15':{'offset':'184', + 'pos':'0', + 'bitlen':'32'}, + 'custom_aes_iv_0':{'offset':'188', + 'pos':'0', + 'bitlen':'32'}, + 'custom_aes_iv_1':{'offset':'192', + 'pos':'0', + 'bitlen':'32'}, + 'custom_aes_iv_2':{'offset':'196', + 'pos':'0', + 'bitlen':'32'}, + 'custom_aes_iv_3':{'offset':'200', + 'pos':'0', + 'bitlen':'32'}, + 'custom_rsvd4':{'offset':'204', + 'pos':'0', + 'bitlen':'32'}, + 'magic_code':{'offset':str(int(custom_config_len) + 0), + 'pos':'0', + 'bitlen':'32'}, + 'revision':{'offset':str(int(custom_config_len) + 4), + 'pos':'0', + 'bitlen':'32'}, + 'flashcfg_magic_code':{'offset':str(int(custom_config_len) + 8), + 'pos':'0', + 'bitlen':'32'}, + 'io_mode':{'offset':str(int(custom_config_len) + 12), + 'pos':'0', + 'bitlen':'8'}, + 'cont_read_support':{'offset':str(int(custom_config_len) + 12), + 'pos':'8', + 'bitlen':'8'}, + 'sfctrl_clk_delay':{'offset':str(int(custom_config_len) + 12), + 'pos':'16', + 'bitlen':'8'}, + 'sfctrl_clk_invert':{'offset':str(int(custom_config_len) + 12), + 'pos':'24', + 'bitlen':'8'}, + 'reset_en_cmd':{'offset':str(int(custom_config_len) + 16), + 'pos':'0', + 'bitlen':'8'}, + 'reset_cmd':{'offset':str(int(custom_config_len) + 16), + 'pos':'8', + 'bitlen':'8'}, + 'exit_contread_cmd':{'offset':str(int(custom_config_len) + 16), + 'pos':'16', + 'bitlen':'8'}, + 'exit_contread_cmd_size':{'offset':str(int(custom_config_len) + 16), + 'pos':'24', + 'bitlen':'8'}, + 'jedecid_cmd':{'offset':str(int(custom_config_len) + 20), + 'pos':'0', + 'bitlen':'8'}, + 'jedecid_cmd_dmy_clk':{'offset':str(int(custom_config_len) + 20), + 'pos':'8', + 'bitlen':'8'}, + 'enter_32bits_addr_cmd':{'offset':str(int(custom_config_len) + 20), + 'pos':'16', + 'bitlen':'8'}, + 'exit_32bits_addr_clk':{'offset':str(int(custom_config_len) + 20), + 'pos':'24', + 'bitlen':'8'}, + 'sector_size':{'offset':str(int(custom_config_len) + 24), + 'pos':'0', + 'bitlen':'8'}, + 'mfg_id':{'offset':str(int(custom_config_len) + 24), + 'pos':'8', + 'bitlen':'8'}, + 'page_size':{'offset':str(int(custom_config_len) + 24), + 'pos':'16', + 'bitlen':'16'}, + 'chip_erase_cmd':{'offset':str(int(custom_config_len) + 28), + 'pos':'0', + 'bitlen':'8'}, + 'sector_erase_cmd':{'offset':str(int(custom_config_len) + 28), + 'pos':'8', + 'bitlen':'8'}, + 'blk32k_erase_cmd':{'offset':str(int(custom_config_len) + 28), + 'pos':'16', + 'bitlen':'8'}, + 'blk64k_erase_cmd':{'offset':str(int(custom_config_len) + 28), + 'pos':'24', + 'bitlen':'8'}, + 'write_enable_cmd':{'offset':str(int(custom_config_len) + 32), + 'pos':'0', + 'bitlen':'8'}, + 'page_prog_cmd':{'offset':str(int(custom_config_len) + 32), + 'pos':'8', + 'bitlen':'8'}, + 'qpage_prog_cmd':{'offset':str(int(custom_config_len) + 32), + 'pos':'16', + 'bitlen':'8'}, + 'qual_page_prog_addr_mode':{'offset':str(int(custom_config_len) + 32), + 'pos':'24', + 'bitlen':'8'}, + 'fast_read_cmd':{'offset':str(int(custom_config_len) + 36), + 'pos':'0', + 'bitlen':'8'}, + 'fast_read_dmy_clk':{'offset':str(int(custom_config_len) + 36), + 'pos':'8', + 'bitlen':'8'}, + 'qpi_fast_read_cmd':{'offset':str(int(custom_config_len) + 36), + 'pos':'16', + 'bitlen':'8'}, + 'qpi_fast_read_dmy_clk':{'offset':str(int(custom_config_len) + 36), + 'pos':'24', + 'bitlen':'8'}, + 'fast_read_do_cmd':{'offset':str(int(custom_config_len) + 40), + 'pos':'0', + 'bitlen':'8'}, + 'fast_read_do_dmy_clk':{'offset':str(int(custom_config_len) + 40), + 'pos':'8', + 'bitlen':'8'}, + 'fast_read_dio_cmd':{'offset':str(int(custom_config_len) + 40), + 'pos':'16', + 'bitlen':'8'}, + 'fast_read_dio_dmy_clk':{'offset':str(int(custom_config_len) + 40), + 'pos':'24', + 'bitlen':'8'}, + 'fast_read_qo_cmd':{'offset':str(int(custom_config_len) + 44), + 'pos':'0', + 'bitlen':'8'}, + 'fast_read_qo_dmy_clk':{'offset':str(int(custom_config_len) + 44), + 'pos':'8', + 'bitlen':'8'}, + 'fast_read_qio_cmd':{'offset':str(int(custom_config_len) + 44), + 'pos':'16', + 'bitlen':'8'}, + 'fast_read_qio_dmy_clk':{'offset':str(int(custom_config_len) + 44), + 'pos':'24', + 'bitlen':'8'}, + 'qpi_fast_read_qio_cmd':{'offset':str(int(custom_config_len) + 48), + 'pos':'0', + 'bitlen':'8'}, + 'qpi_fast_read_qio_dmy_clk':{'offset':str(int(custom_config_len) + 48), + 'pos':'8', + 'bitlen':'8'}, + 'qpi_page_prog_cmd':{'offset':str(int(custom_config_len) + 48), + 'pos':'16', + 'bitlen':'8'}, + 'write_vreg_enable_cmd':{'offset':str(int(custom_config_len) + 48), + 'pos':'24', + 'bitlen':'8'}, + 'wel_reg_index':{'offset':str(int(custom_config_len) + 52), + 'pos':'0', + 'bitlen':'8'}, + 'qe_reg_index':{'offset':str(int(custom_config_len) + 52), + 'pos':'8', + 'bitlen':'8'}, + 'busy_reg_index':{'offset':str(int(custom_config_len) + 52), + 'pos':'16', + 'bitlen':'8'}, + 'wel_bit_pos':{'offset':str(int(custom_config_len) + 52), + 'pos':'24', + 'bitlen':'8'}, + 'qe_bit_pos':{'offset':str(int(custom_config_len) + 56), + 'pos':'0', + 'bitlen':'8'}, + 'busy_bit_pos':{'offset':str(int(custom_config_len) + 56), + 'pos':'8', + 'bitlen':'8'}, + 'wel_reg_write_len':{'offset':str(int(custom_config_len) + 56), + 'pos':'16', + 'bitlen':'8'}, + 'wel_reg_read_len':{'offset':str(int(custom_config_len) + 56), + 'pos':'24', + 'bitlen':'8'}, + 'qe_reg_write_len':{'offset':str(int(custom_config_len) + 60), + 'pos':'0', + 'bitlen':'8'}, + 'qe_reg_read_len':{'offset':str(int(custom_config_len) + 60), + 'pos':'8', + 'bitlen':'8'}, + 'release_power_down':{'offset':str(int(custom_config_len) + 60), + 'pos':'16', + 'bitlen':'8'}, + 'busy_reg_read_len':{'offset':str(int(custom_config_len) + 60), + 'pos':'24', + 'bitlen':'8'}, + 'reg_read_cmd0':{'offset':str(int(custom_config_len) + 64), + 'pos':'0', + 'bitlen':'8'}, + 'reg_read_cmd1':{'offset':str(int(custom_config_len) + 64), + 'pos':'8', + 'bitlen':'8'}, + 'reg_write_cmd0':{'offset':str(int(custom_config_len) + 68), + 'pos':'0', + 'bitlen':'8'}, + 'reg_write_cmd1':{'offset':str(int(custom_config_len) + 68), + 'pos':'8', + 'bitlen':'8'}, + 'enter_qpi_cmd':{'offset':str(int(custom_config_len) + 72), + 'pos':'0', + 'bitlen':'8'}, + 'exit_qpi_cmd':{'offset':str(int(custom_config_len) + 72), + 'pos':'8', + 'bitlen':'8'}, + 'cont_read_code':{'offset':str(int(custom_config_len) + 72), + 'pos':'16', + 'bitlen':'8'}, + 'cont_read_exit_code':{'offset':str(int(custom_config_len) + 72), + 'pos':'24', + 'bitlen':'8'}, + 'burst_wrap_cmd':{'offset':str(int(custom_config_len) + 76), + 'pos':'0', + 'bitlen':'8'}, + 'burst_wrap_dmy_clk':{'offset':str(int(custom_config_len) + 76), + 'pos':'8', + 'bitlen':'8'}, + 'burst_wrap_data_mode':{'offset':str(int(custom_config_len) + 76), + 'pos':'16', + 'bitlen':'8'}, + 'burst_wrap_code':{'offset':str(int(custom_config_len) + 76), + 'pos':'24', + 'bitlen':'8'}, + 'de_burst_wrap_cmd':{'offset':str(int(custom_config_len) + 80), + 'pos':'0', + 'bitlen':'8'}, + 'de_burst_wrap_cmd_dmy_clk':{'offset':str(int(custom_config_len) + 80), + 'pos':'8', + 'bitlen':'8'}, + 'de_burst_wrap_code_mode':{'offset':str(int(custom_config_len) + 80), + 'pos':'16', + 'bitlen':'8'}, + 'de_burst_wrap_code':{'offset':str(int(custom_config_len) + 80), + 'pos':'24', + 'bitlen':'8'}, + 'sector_erase_time':{'offset':str(int(custom_config_len) + 84), + 'pos':'0', + 'bitlen':'16'}, + 'blk32k_erase_time':{'offset':str(int(custom_config_len) + 84), + 'pos':'16', + 'bitlen':'16'}, + 'blk64k_erase_time':{'offset':str(int(custom_config_len) + 88), + 'pos':'0', + 'bitlen':'16'}, + 'page_prog_time':{'offset':str(int(custom_config_len) + 88), + 'pos':'16', + 'bitlen':'16'}, + 'chip_erase_time':{'offset':str(int(custom_config_len) + 92), + 'pos':'0', + 'bitlen':'16'}, + 'power_down_delay':{'offset':str(int(custom_config_len) + 92), + 'pos':'16', + 'bitlen':'8'}, + 'qe_data':{'offset':str(int(custom_config_len) + 92), + 'pos':'24', + 'bitlen':'8'}, + 'flashcfg_crc32':{'offset':str(int(custom_config_len) + 96), + 'pos':'0', + 'bitlen':'32'}, + 'clkcfg_magic_code':{'offset':str(int(clock_start_pos) + 0), + 'pos':'0', + 'bitlen':'32'}, + 'xtal_type':{'offset':str(int(clock_start_pos) + 4), + 'pos':'0', + 'bitlen':'8'}, + 'mcu_clk':{'offset':str(int(clock_start_pos) + 4), + 'pos':'8', + 'bitlen':'8'}, + 'mcu_clk_div':{'offset':str(int(clock_start_pos) + 4), + 'pos':'16', + 'bitlen':'8'}, + 'mcu_bclk_div':{'offset':str(int(clock_start_pos) + 4), + 'pos':'24', + 'bitlen':'8'}, + 'mcu_pbclk_div':{'offset':str(int(clock_start_pos) + 8), + 'pos':'0', + 'bitlen':'8'}, + 'emi_clk':{'offset':str(int(clock_start_pos) + 8), + 'pos':'8', + 'bitlen':'8'}, + 'emi_clk_div':{'offset':str(int(clock_start_pos) + 8), + 'pos':'16', + 'bitlen':'8'}, + 'flash_clk_type':{'offset':str(int(clock_start_pos) + 8), + 'pos':'24', + 'bitlen':'8'}, + 'flash_clk_div':{'offset':str(int(clock_start_pos) + 12), + 'pos':'0', + 'bitlen':'8'}, + 'wifipll_pu':{'offset':str(int(clock_start_pos) + 12), + 'pos':'8', + 'bitlen':'8'}, + 'aupll_pu':{'offset':str(int(clock_start_pos) + 12), + 'pos':'16', + 'bitlen':'8'}, + 'rsvd0':{'offset':str(int(clock_start_pos) + 12), + 'pos':'24', + 'bitlen':'8'}, + 'clkcfg_crc32':{'offset':str(int(clock_start_pos) + 16), + 'pos':'0', + 'bitlen':'32'}, + 'sign':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'0', + 'bitlen':'2'}, + 'encrypt_type':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'2', + 'bitlen':'2'}, + 'key_sel':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'4', + 'bitlen':'2'}, + 'xts_mode':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'6', + 'bitlen':'1'}, + 'aes_region_lock':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'7', + 'bitlen':'1'}, + 'no_segment':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'8', + 'bitlen':'1'}, + 'boot2_enable':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'9', + 'bitlen':'1'}, + 'boot2_rollback':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'10', + 'bitlen':'1'}, + 'cpu_master_id':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'11', + 'bitlen':'4'}, + 'notload_in_bootrom':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'15', + 'bitlen':'1'}, + 'crc_ignore':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'16', + 'bitlen':'1'}, + 'hash_ignore':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'17', + 'bitlen':'1'}, + 'power_on_mm':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'18', + 'bitlen':'1'}, + 'em_sel':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'19', + 'bitlen':'3'}, + 'cmds_en':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'22', + 'bitlen':'1'}, + 'cmds_wrap_mode':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'23', + 'bitlen':'2'}, + 'cmds_wrap_len':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'25', + 'bitlen':'4'}, + 'icache_invalid':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'29', + 'bitlen':'1'}, + 'dcache_invalid':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'30', + 'bitlen':'1'}, + 'fpga_halt_release':{'offset':str(int(bootcfg_start_pos) + 0), + 'pos':'31', + 'bitlen':'1'}, + 'group_image_offset':{'offset':str(int(bootcfg_start_pos) + 4), + 'pos':'0', + 'bitlen':'32'}, + 'aes_region_len':{'offset':str(int(bootcfg_start_pos) + 8), + 'pos':'0', + 'bitlen':'32'}, + 'img_len_cnt':{'offset':str(int(bootcfg_start_pos) + 12), + 'pos':'0', + 'bitlen':'32'}, + 'hash_0':{'offset':str(int(bootcfg_start_pos) + 16), + 'pos':'0', + 'bitlen':'32'}, + 'hash_1':{'offset':str(int(bootcfg_start_pos) + 20), + 'pos':'0', + 'bitlen':'32'}, + 'hash_2':{'offset':str(int(bootcfg_start_pos) + 24), + 'pos':'0', + 'bitlen':'32'}, + 'hash_3':{'offset':str(int(bootcfg_start_pos) + 28), + 'pos':'0', + 'bitlen':'32'}, + 'hash_4':{'offset':str(int(bootcfg_start_pos) + 32), + 'pos':'0', + 'bitlen':'32'}, + 'hash_5':{'offset':str(int(bootcfg_start_pos) + 36), + 'pos':'0', + 'bitlen':'32'}, + 'hash_6':{'offset':str(int(bootcfg_start_pos) + 40), + 'pos':'0', + 'bitlen':'32'}, + 'hash_7':{'offset':str(int(bootcfg_start_pos) + 44), + 'pos':'0', + 'bitlen':'32'}, + 'm0_config_enable':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_m0_index) + 0), + 'pos':'0', + 'bitlen':'8'}, + 'm0_halt_cpu':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_m0_index) + 0), + 'pos':'8', + 'bitlen':'8'}, + 'm0_cache_enable':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_m0_index) + 0), + 'pos':'16', + 'bitlen':'1'}, + 'm0_cache_wa':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_m0_index) + 0), + 'pos':'17', + 'bitlen':'1'}, + 'm0_cache_wb':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_m0_index) + 0), + 'pos':'18', + 'bitlen':'1'}, + 'm0_cache_wt':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_m0_index) + 0), + 'pos':'19', + 'bitlen':'1'}, + 'm0_cache_way_dis':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_m0_index) + 0), + 'pos':'20', + 'bitlen':'4'}, + 'm0_reserved':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_m0_index) + 0), + 'pos':'24', + 'bitlen':'8'}, + 'm0_image_address_offset':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_m0_index) + 4), + 'pos':'0', + 'bitlen':'32'}, + 'm0_boot_entry':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_m0_index) + 8), + 'pos':'0', + 'bitlen':'32'}, + 'm0_msp_val':{'offset':str(int(bootcpucfg_start_pos + bootcpucfg_len * bootcpucfg_m0_index) + 12), + 'pos':'0', + 'bitlen':'32'}, + 'boot2_pt_table_0':{'offset':str(int(boot2_start_pos) + 0), + 'pos':'0', + 'bitlen':'32'}, + 'boot2_pt_table_1':{'offset':str(int(boot2_start_pos) + 4), + 'pos':'0', + 'bitlen':'32'}, + 'flashCfgTableAddr':{'offset':str(int(flashcfg_table_start_pos) + 0), + 'pos':'0', + 'bitlen':'32'}, + 'flashCfgTableLen':{'offset':str(int(flashcfg_table_start_pos) + 4), + 'pos':'0', + 'bitlen':'32'}, + 'patch_read_addr0':{'offset':str(int(patch_on_read_start_pos) + 0), + 'pos':'0', + 'bitlen':'32'}, + 'patch_read_value0':{'offset':str(int(patch_on_read_start_pos) + 4), + 'pos':'0', + 'bitlen':'32'}, + 'patch_read_addr1':{'offset':str(int(patch_on_read_start_pos) + 8), + 'pos':'0', + 'bitlen':'32'}, + 'patch_read_value1':{'offset':str(int(patch_on_read_start_pos) + 12), + 'pos':'0', + 'bitlen':'32'}, + 'patch_read_addr2':{'offset':str(int(patch_on_read_start_pos) + 16), + 'pos':'0', + 'bitlen':'32'}, + 'patch_read_value2':{'offset':str(int(patch_on_read_start_pos) + 20), + 'pos':'0', + 'bitlen':'32'}, + 'patch_jump_addr0':{'offset':str(int(patch_on_jump_start_pos) + 0), + 'pos':'0', + 'bitlen':'32'}, + 'patch_jump_value0':{'offset':str(int(patch_on_jump_start_pos) + 4), + 'pos':'0', + 'bitlen':'32'}, + 'patch_jump_addr1':{'offset':str(int(patch_on_jump_start_pos) + 8), + 'pos':'0', + 'bitlen':'32'}, + 'patch_jump_value1':{'offset':str(int(patch_on_jump_start_pos) + 12), + 'pos':'0', + 'bitlen':'32'}, + 'patch_jump_addr2':{'offset':str(int(patch_on_jump_start_pos) + 16), + 'pos':'0', + 'bitlen':'32'}, + 'patch_jump_value2':{'offset':str(int(patch_on_jump_start_pos) + 20), + 'pos':'0', + 'bitlen':'32'}, + 'reserved':{'offset':str(int(rsvd_start_pos) + 0), + 'pos':'0', + 'bitlen':'32'}, + 'crc32':{'offset':str(int(crc32_start_pos) + 0), + 'pos':'0', + 'bitlen':'32'}} +# okay decompiling ./libs/base/wb03/bootheader_cfg_keys.pyc diff --git a/libs/base/wb03/chiptype_patch.py b/libs/base/wb03/chiptype_patch.py new file mode 100644 index 0000000..662f5cb --- /dev/null +++ b/libs/base/wb03/chiptype_patch.py @@ -0,0 +1,10 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/wb03/chiptype_patch.py + + +def img_load_create_predata_before_run_img(): + return bytearray(0) +# okay decompiling ./libs/base/wb03/chiptype_patch.pyc diff --git a/libs/base/wb03/cklink_load_cfg.py b/libs/base/wb03/cklink_load_cfg.py new file mode 100644 index 0000000..bf90721 --- /dev/null +++ b/libs/base/wb03/cklink_load_cfg.py @@ -0,0 +1,12 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/wb03/cklink_load_cfg.py +cklink_shake_hand_addr = '2204BBEC' +cklink_data_addr = '2204CC88' +cklink_load_addr = '22010000' +cklink_core_type = 'RISC-V' +cklink_set_tif = 0 +cklink_run_addr = '22010000' +# okay decompiling ./libs/base/wb03/cklink_load_cfg.pyc diff --git a/libs/base/wb03/flash_select_do.py b/libs/base/wb03/flash_select_do.py new file mode 100644 index 0000000..4b6def5 --- /dev/null +++ b/libs/base/wb03/flash_select_do.py @@ -0,0 +1,147 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/wb03/flash_select_do.py +import os, csv +from re import I +import config as gol +from libs import bflb_utils +from libs.bflb_utils import app_path, conf_sign +from libs.bflb_configobj import BFConfigParser +from libs.base.wb03.bootheader_cfg_keys import bootheader_cfg_keys as flash_cfg_keys + +def get_suitable_file_name(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: + bflb_utils.printf('Flash id duplicate and alternative is:') + for i in range(len(conf_files)): + tmp = conf_files[i].split('.')[0] + bflb_utils.printf('%d:%s' % (i + 1, tmp)) + + return conf_files[i] + if len(conf_files) == 1: + return conf_files[0] + return '' + + +def update_flash_cfg_do(chipname, chiptype, flash_id, file=None, create=False, section=None): + if conf_sign: + cfg_dir = app_path + '/utils/flash/' + chipname + '/' + else: + cfg_dir = app_path + '/utils/flash/' + gol.flash_dict[chipname] + '/' + conf_name = get_suitable_file_name(cfg_dir, flash_id) + value_key = [] + if os.path.isfile(cfg_dir + conf_name) is False: + return False + fp = open(cfg_dir + conf_name, 'r') + for line in fp.readlines(): + value = line.split('=')[0].strip() + if value == '[FLASH_CFG]': + continue + else: + value_key.append(value) + + cfg1 = BFConfigParser() + cfg1.read(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]): + if cfg2.has_option(section, value_key[i]): + tmp_value = cfg1.get('FLASH_CFG', value_key[i]) + bflb_utils.update_cfg(cfg2, section, value_key[i], tmp_value) + + cfg2.write(file, 'w+') + bflb_utils.printf('Update flash cfg finished') + + +def get_supported_flash_do(): + flash_type = [] + return flash_type + + +def get_int_mask(pos, length): + ones = '11111111111111111111111111111111' + zeros = '00000000000000000000000000000000' + mask = ones[0:32 - pos - length] + zeros[0:length] + ones[0:pos] + return int(mask, 2) + + +def create_flashcfg_data_from_cfg(cfg_len, cfgfile): + section = 'FLASH_CFG' + cfg = BFConfigParser() + cfg.read(cfgfile) + data = bytearray(cfg_len) + minOffset = int(flash_cfg_keys.get('io_mode')['offset'], 10) + for key in cfg.options(section): + if flash_cfg_keys.get(key) == None: + bflb_utils.printf(key + ' not exist') + continue + else: + val = cfg.get(section, key) + if val.startswith('0x'): + val = int(val, 16) + else: + val = int(val, 10) + offset = int(flash_cfg_keys.get(key)['offset'], 10) - minOffset + pos = int(flash_cfg_keys.get(key)['pos'], 10) + bitlen = int(flash_cfg_keys.get(key)['bitlen'], 10) + oldval = bflb_utils.bytearray_to_int(bflb_utils.bytearray_reverse(data[offset:offset + 4])) + newval = (oldval & get_int_mask(pos, bitlen)) + (val << pos) + data[offset:offset + 4] = bflb_utils.int_to_4bytearray_l(newval) + + crcarray = bflb_utils.get_crc32_bytearray(data) + data = bflb_utils.int_to_4bytearray_l(1195787078) + data + crcarray + return data + + +def create_flashcfg_table(start_addr): + single_flashcfg_len = 92 + flash_table_list = bytearray(0) + flash_table_data = bytearray(0) + table_file = os.path.join(app_path, 'utils', 'flash', 'wb03', 'flashcfg_list.csv') + with open(table_file, 'r', encoding='utf-8-sig') as csvfile: + table_list = [] + cfgfile_list = [] + reader = csv.DictReader(csvfile) + cnt = 0 + for row in reader: + row_dict = {} + row_dict['jid'] = row.get('flashJedecID', '') + row_dict['cfgfile'] = row.get('configFile', '') + if row_dict['cfgfile'] not in cfgfile_list: + cfgfile_list.append(row_dict['cfgfile']) + else: + table_list.append(row_dict) + cnt += 1 + + table_list_len = 4 + cnt * 8 + 4 + for cfgfile in cfgfile_list: + cfgfile = os.path.join(app_path, 'utils', 'flash', 'wb03', cfgfile) + data = create_flashcfg_data_from_cfg(single_flashcfg_len - 8, cfgfile) + flash_table_data += data + + for dict in table_list: + flash_table_list += bflb_utils.int_to_4bytearray_b(int(dict['jid'] + '00', 16)) + i = 0 + offset = 0 + for cfgfile in cfgfile_list: + if cfgfile == dict['cfgfile']: + offset = start_addr + table_list_len + single_flashcfg_len * i + break + else: + i += 1 + + flash_table_list += bflb_utils.int_to_4bytearray_l(offset) + + crcarray = bflb_utils.get_crc32_bytearray(flash_table_list) + flash_table_list = bflb_utils.int_to_4bytearray_l(1196704582) + flash_table_list + crcarray + return ( + flash_table_list, flash_table_data, len(flash_table_list)) +# okay decompiling ./libs/base/wb03/flash_select_do.pyc diff --git a/libs/base/wb03/img_create_do.py b/libs/base/wb03/img_create_do.py new file mode 100644 index 0000000..e4773ce --- /dev/null +++ b/libs/base/wb03/img_create_do.py @@ -0,0 +1,766 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/wb03/img_create_do.py +import os, sys, hashlib, binascii, codecs, ecdsa +from CryptoPlus.Cipher import AES as AES_XTS +from libs import bflb_utils +from libs.bflb_utils import img_create_sha256_data, img_create_encrypt_data +from libs.bflb_configobj import BFConfigParser +from libs.base.wb03.flash_select_do import create_flashcfg_table +from libs.base.wb03.bootheader_cfg_keys import custom_config_len as custom_cfg_len +from libs.base.wb03.bootheader_cfg_keys import flashcfg_table_start_pos as flashcfg_table_start +from libs.base.wb03.bootheader_cfg_keys import bootcpucfg_start_pos as bootcpucfg_start +from libs.base.wb03.bootheader_cfg_keys import bootcpucfg_len as bootcpucfg_length +from libs.base.wb03.bootheader_cfg_keys import bootcpucfg_m0_index as bootcpucfg_m0_index_number +from libs.base.wb03.bootheader_cfg_keys import bootcfg_start_pos as bootcfg_start +from libs.base.wb03.bootheader_cfg_keys import bootheader_len as header_len +keyslot0 = 28 +keyslot1 = keyslot0 + 16 +keyslot2 = keyslot1 + 16 +keyslot3 = keyslot2 + 16 +keyslot3_end = keyslot3 + 16 +keyslot4 = 128 +keyslot5 = keyslot4 + 16 +keyslot6 = keyslot5 + 16 +keyslot7 = keyslot6 + 16 +keyslot8 = keyslot7 + 16 +keyslot9 = keyslot8 + 16 +keyslot10 = keyslot9 + 16 +keyslot10_end = keyslot10 + 16 +keyslot11 = keyslot3_end + 16 +keyslot11_end = keyslot11 + 16 +wr_lock_boot_mode = 14 +wr_lock_dbg_pwd = 15 +wr_lock_wifi_mac = 16 +wr_lock_key_slot_0 = 17 +wr_lock_key_slot_1 = 18 +wr_lock_key_slot_2 = 19 +wr_lock_key_slot_3 = 20 +wr_lock_sw_usage_0 = 21 +wr_lock_sw_usage_1 = 22 +wr_lock_sw_usage_2 = 23 +wr_lock_sw_usage_3 = 24 +wr_lock_key_slot_11 = 25 +rd_lock_dbg_pwd = 26 +rd_lock_key_slot_0 = 27 +rd_lock_key_slot_1 = 28 +rd_lock_key_slot_2 = 29 +rd_lock_key_slot_3 = 30 +rd_lock_key_slot_11 = 31 +wr_lock_key_slot_4 = 15 +wr_lock_key_slot_5 = 16 +wr_lock_key_slot_6 = 17 +wr_lock_key_slot_7 = 18 +wr_lock_key_slot_8 = 19 +wr_lock_key_slot_9 = 20 +wr_lock_key_slot_10 = 21 +rd_lock_key_slot_4 = 25 +rd_lock_key_slot_5 = 26 +rd_lock_key_slot_6 = 27 +rd_lock_key_slot_7 = 28 +rd_lock_key_slot_8 = 29 +rd_lock_key_slot_9 = 30 +rd_lock_key_slot_10 = 31 + +def bytearray_data_merge(data1, data2, len): + for i in range(len): + data1[i] |= data2[i] + + return data1 + + +def img_update_efuse_group0(cfg, sign, pk_hash, flash_encryp_type, flash_key, sec_eng_key_sel, sec_eng_key, security=False): + fp = open(cfg.get('Img_Group0_Cfg', 'efuse_file'), 'rb') + efuse_data = bytearray(fp.read()) + bytearray(0) + fp.close() + fp = open(cfg.get('Img_Group0_Cfg', 'efuse_mask_file'), 'rb') + efuse_mask_data = bytearray(fp.read()) + bytearray(0) + fp.close() + mask_4bytes = bytearray.fromhex('FFFFFFFF') + if flash_encryp_type >= 3: + efuse_data[0] |= 3 + else: + efuse_data[0] |= flash_encryp_type + if sign > 0: + efuse_data[92] |= sign << 7 + efuse_mask_data[92] |= 255 + if flash_encryp_type > 0: + efuse_data[0] |= 48 + efuse_mask_data[0] |= 255 + rw_lock0 = 0 + rw_lock1 = 0 + if pk_hash is not None: + efuse_data[keyslot0:keyslot2] = pk_hash + efuse_mask_data[keyslot0:keyslot2] = mask_4bytes * 8 + rw_lock0 |= 1 << wr_lock_key_slot_0 + rw_lock0 |= 1 << wr_lock_key_slot_1 + if flash_key is not None: + if flash_encryp_type == 1: + efuse_data[keyslot2:keyslot3] = flash_key[0:16] + efuse_mask_data[keyslot2:keyslot3] = mask_4bytes * 4 + else: + if flash_encryp_type == 2: + efuse_data[keyslot2:keyslot3_end] = flash_key + efuse_mask_data[keyslot2:keyslot3_end] = mask_4bytes * 8 + rw_lock0 |= 1 << wr_lock_key_slot_3 + rw_lock0 |= 1 << rd_lock_key_slot_3 + else: + if flash_encryp_type == 3: + efuse_data[keyslot2:keyslot3_end] = flash_key + efuse_mask_data[keyslot2:keyslot3_end] = mask_4bytes * 8 + rw_lock0 |= 1 << wr_lock_key_slot_3 + rw_lock0 |= 1 << rd_lock_key_slot_3 + else: + if flash_encryp_type == 4 or flash_encryp_type == 5 or flash_encryp_type == 6: + efuse_data[keyslot2:keyslot3_end] = flash_key + efuse_mask_data[keyslot2:keyslot3_end] = mask_4bytes * 8 + rw_lock0 |= 1 << wr_lock_key_slot_3 + rw_lock0 |= 1 << rd_lock_key_slot_3 + rw_lock0 |= 1 << wr_lock_key_slot_2 + rw_lock0 |= 1 << rd_lock_key_slot_2 + if sec_eng_key is not None: + if flash_encryp_type == 0: + if sec_eng_key_sel == 0: + efuse_data[keyslot2:keyslot3] = sec_eng_key[16:32] + efuse_data[keyslot3:keyslot3_end] = sec_eng_key[0:16] + efuse_mask_data[keyslot2:keyslot3_end] = mask_4bytes * 8 + rw_lock0 |= 1 << wr_lock_key_slot_2 + rw_lock0 |= 1 << wr_lock_key_slot_3 + rw_lock0 |= 1 << rd_lock_key_slot_2 + rw_lock0 |= 1 << rd_lock_key_slot_3 + if sec_eng_key_sel == 1: + efuse_data[keyslot3:keyslot3_end] = sec_eng_key[16:32] + efuse_data[keyslot4:keyslot5] = sec_eng_key[0:16] + efuse_mask_data[keyslot3:keyslot3_end] = mask_4bytes * 4 + efuse_mask_data[keyslot4:keyslot5] = mask_4bytes * 4 + rw_lock0 |= 1 << wr_lock_key_slot_3 + rw_lock1 |= 1 << wr_lock_key_slot_4 + rw_lock0 |= 1 << rd_lock_key_slot_3 + rw_lock1 |= 1 << rd_lock_key_slot_4 + if sec_eng_key_sel == 2: + efuse_data[keyslot4:keyslot5] = sec_eng_key[16:32] + efuse_data[keyslot2:keyslot3] = sec_eng_key[0:16] + efuse_mask_data[keyslot3:keyslot5] = mask_4bytes * 8 + rw_lock1 |= 1 << wr_lock_key_slot_4 + rw_lock0 |= 1 << wr_lock_key_slot_2 + rw_lock1 |= 1 << rd_lock_key_slot_4 + rw_lock0 |= 1 << rd_lock_key_slot_2 + if sec_eng_key_sel == 3: + efuse_data[keyslot4:keyslot5] = sec_eng_key[16:32] + efuse_data[keyslot2:keyslot3] = sec_eng_key[0:16] + efuse_mask_data[keyslot3:keyslot5] = mask_4bytes * 8 + rw_lock1 |= 1 << wr_lock_key_slot_4 + rw_lock0 |= 1 << wr_lock_key_slot_2 + rw_lock1 |= 1 << rd_lock_key_slot_4 + rw_lock0 |= 1 << rd_lock_key_slot_2 + if flash_encryp_type == 1: + if sec_eng_key_sel == 0: + efuse_data[keyslot5:keyslot6] = sec_eng_key[0:16] + efuse_mask_data[keyslot5:keyslot6] = mask_4bytes * 4 + rw_lock1 |= 1 << wr_lock_key_slot_5 + rw_lock1 |= 1 << rd_lock_key_slot_5 + if sec_eng_key_sel == 1: + efuse_data[keyslot4:keyslot5] = sec_eng_key[0:16] + efuse_mask_data[keyslot4:keyslot5] = mask_4bytes * 4 + rw_lock1 |= 1 << wr_lock_key_slot_4 + rw_lock1 |= 1 << rd_lock_key_slot_4 + if sec_eng_key_sel == 2: + if flash_key is not None: + pass + else: + efuse_data[keyslot3:keyslot3_end] = sec_eng_key[0:16] + efuse_mask_data[keyslot3:keyslot3_end] = mask_4bytes * 4 + rw_lock0 |= 1 << wr_lock_key_slot_3 + rw_lock0 |= 1 << rd_lock_key_slot_3 + if sec_eng_key_sel == 3: + if flash_key is not None: + pass + else: + efuse_data[keyslot2:keyslot3] = sec_eng_key[0:16] + efuse_mask_data[keyslot2:keyslot3] = mask_4bytes * 4 + rw_lock0 |= 1 << wr_lock_key_slot_2 + rw_lock0 |= 1 << rd_lock_key_slot_2 + if flash_encryp_type == 2 or flash_encryp_type == 3 or flash_encryp_type == 4 or flash_encryp_type == 5 or flash_encryp_type == 6: + if sec_eng_key_sel == 0: + efuse_data[keyslot6:keyslot7] = sec_eng_key[16:32] + efuse_data[keyslot10:keyslot10_end] = sec_eng_key[0:16] + efuse_mask_data[keyslot6:keyslot7] = mask_4bytes * 4 + efuse_mask_data[keyslot10:keyslot10_end] = mask_4bytes * 4 + rw_lock1 |= 1 << wr_lock_key_slot_6 + rw_lock1 |= 1 << wr_lock_key_slot_10 + rw_lock1 |= 1 << rd_lock_key_slot_6 + rw_lock1 |= 1 << rd_lock_key_slot_10 + if sec_eng_key_sel == 1: + efuse_data[keyslot10:keyslot10_end] = sec_eng_key[16:32] + efuse_data[keyslot6:keyslot7] = sec_eng_key[0:16] + efuse_mask_data[keyslot6:keyslot7] = mask_4bytes * 4 + efuse_mask_data[keyslot10:keyslot10_end] = mask_4bytes * 4 + rw_lock1 |= 1 << wr_lock_key_slot_6 + rw_lock1 |= 1 << wr_lock_key_slot_10 + rw_lock1 |= 1 << rd_lock_key_slot_6 + rw_lock1 |= 1 << rd_lock_key_slot_10 + if sec_eng_key_sel == 2: + if flash_key is not None: + pass + else: + efuse_data[keyslot2:keyslot3] = sec_eng_key[16:32] + efuse_data[keyslot3:keyslot3_end] = sec_eng_key[0:16] + efuse_mask_data[keyslot2:keyslot3_end] = mask_4bytes * 8 + rw_lock0 |= 1 << wr_lock_key_slot_2 + rw_lock0 |= 1 << rd_lock_key_slot_2 + rw_lock0 |= 1 << wr_lock_key_slot_3 + rw_lock0 |= 1 << rd_lock_key_slot_3 + if sec_eng_key_sel == 3: + if flash_key is not None: + pass + else: + efuse_data[keyslot2:keyslot3_end] = sec_eng_key + efuse_mask_data[keyslot2:keyslot3_end] = mask_4bytes * 8 + rw_lock0 |= 1 << wr_lock_key_slot_2 + rw_lock0 |= 1 << rd_lock_key_slot_2 + rw_lock0 |= 1 << wr_lock_key_slot_3 + rw_lock0 |= 1 << rd_lock_key_slot_3 + efuse_data[124:128] = bytearray_data_merge(efuse_data[124:128], bflb_utils.int_to_4bytearray_l(rw_lock0), 4) + efuse_mask_data[124:128] = bytearray_data_merge(efuse_mask_data[124:128], bflb_utils.int_to_4bytearray_l(rw_lock0), 4) + efuse_data[252:256] = bytearray_data_merge(efuse_data[252:256], bflb_utils.int_to_4bytearray_l(rw_lock1), 4) + efuse_mask_data[252:256] = bytearray_data_merge(efuse_mask_data[252:256], bflb_utils.int_to_4bytearray_l(rw_lock1), 4) + if security is True: + bflb_utils.printf('Encrypt efuse data') + security_key, security_iv = bflb_utils.get_security_key() + efuse_data = img_create_encrypt_data(efuse_data, security_key, security_iv, 0) + efuse_data = bytearray(4096) + efuse_data + fp = open(cfg.get('Img_Group0_Cfg', 'efuse_file'), 'wb+') + fp.write(efuse_data) + fp.close() + fp = open(cfg.get('Img_Group0_Cfg', 'efuse_mask_file'), 'wb+') + fp.write(efuse_mask_data) + fp.close() + + +def img_create_get_sign_encrypt_info(bootheader_data): + sign = bootheader_data[bootcfg_start] & 3 + encrypt = bootheader_data[bootcfg_start] >> 2 & 3 + key_sel = bootheader_data[bootcfg_start] >> 4 & 3 + xts_mode = bootheader_data[bootcfg_start] >> 6 & 1 + return ( + sign, encrypt, key_sel, xts_mode) + + +def img_create_get_img_start_addr(bootheader_data): + bootentry = [] + bootentry.append(bflb_utils.bytearray_to_int(bflb_utils.bytearray_reverse(bootheader_data[bootcpucfg_start + bootcpucfg_length * bootcpucfg_m0_index_number + 16:bootcpucfg_start + bootcpucfg_length * bootcpucfg_m0_index_number + 16 + 4]))) + return bootentry + + +def img_create_flash_default_data(length): + datas = bytearray(length) + for i in range(length): + datas[i] = 255 + + return datas + + +def img_get_file_data(files): + datas = [] + for file in files: + if file == 'UNUSED': + datas.append(bytearray(0)) + continue + else: + with open(file, 'rb') as fp: + data = fp.read() + datas.append(data) + + return datas + + +def img_get_largest_addr(addrs, files): + min = 67108863 + maxlen = 0 + datalen = 0 + for i in range(len(addrs)): + if files[i] == 'UNUSED': + continue + else: + addr = addrs[i] & 67108863 + if addr >= maxlen: + maxlen = addr + datalen = os.path.getsize(files[i]) + if addr <= min: + min = addr + + if maxlen == 0: + if datalen == 0: + return (0, 0) + return ( + maxlen + datalen - min, min) + + +def img_get_one_group_img(d_addrs, d_files): + whole_img_len, min = img_get_largest_addr(d_addrs, d_files) + whole_img_len &= 67108863 + whole_img_data = img_create_flash_default_data(whole_img_len) + filedatas = img_get_file_data(d_files) + for i in range(len(d_addrs)): + if d_files[i] == 'UNUSED': + continue + else: + start_addr = d_addrs[i] + start_addr &= 67108863 + start_addr -= min + whole_img_data[start_addr:start_addr + len(filedatas[i])] = filedatas[i] + + return whole_img_data + + +def img_create_get_hash_ignore(bootheader_data): + return bootheader_data[bootcfg_start + 2] >> 1 & 1 + + +def img_create_get_crc_ignore(bootheader_data): + return bootheader_data[bootcfg_start + 2] & 1 + + +def img_create_update_bootheader_if(bootheader_data, hash, seg_cnt): + bootheader_data[bootcfg_start + 12:bootcfg_start + 12 + 4] = bflb_utils.int_to_4bytearray_l(seg_cnt) + sign = bootheader_data[bootcfg_start] & 3 + encrypt = bootheader_data[bootcfg_start] >> 2 & 3 + key_sel = bootheader_data[bootcfg_start] >> 4 & 3 + xts_mode = bootheader_data[bootcfg_start] >> 6 & 1 + if bootheader_data[bootcfg_start + 2] >> 1 & 1 == 1 and sign == 0: + bflb_utils.printf('Hash ignored') + else: + bootheader_data[bootcfg_start + 16:bootcfg_start + 16 + 32] = hash + if bootheader_data[bootcfg_start + 2] & 1 == 1: + bflb_utils.printf('Header crc ignored') + else: + hd_crcarray = bflb_utils.get_crc32_bytearray(bootheader_data[custom_cfg_len:header_len - 4]) + bootheader_data[header_len - 4:header_len] = hd_crcarray + bflb_utils.printf('Header crc: ', binascii.hexlify(hd_crcarray)) + return bootheader_data + + +def img_create_update_custom_bootheader(bootheader_data, seg_cnt, hash, signature, pk_data, aesiv_data): + bootheader_data[20:24] = bflb_utils.int_to_4bytearray_l(seg_cnt) + if hash != bytearray(0): + bootheader_data[28:60] = hash + if signature != bytearray(0): + bootheader_data[60:124] = signature[4:68] + if pk_data != bytearray(0): + bootheader_data[124:188] = pk_data[0:64] + if aesiv_data != bytearray(0): + bootheader_data[188:204] = aesiv_data[0:16] + bootheader_data[4:8] = bflb_utils.get_crc32_bytearray(bootheader_data[8:custom_cfg_len - 4]) + return bootheader_data[0:header_len] + + +def img_create_update_bootheader(bootheader_data, hash, seg_cnt, flashcfg_table_addr, flashcfg_table_len): + bootheader_data[flashcfg_table_start:flashcfg_table_start + 4] = bflb_utils.int_to_4bytearray_l(flashcfg_table_addr) + bootheader_data[flashcfg_table_start + 4:flashcfg_table_start + 8] = bflb_utils.int_to_4bytearray_l(flashcfg_table_len) + bootheader_data[bootcfg_start + 12:bootcfg_start + 12 + 4] = bflb_utils.int_to_4bytearray_l(seg_cnt) + sign, encrypt, key_sel, xts_mode = img_create_get_sign_encrypt_info(bootheader_data) + if img_create_get_hash_ignore(bootheader_data) == 1 and sign == 0: + bflb_utils.printf('Hash ignored') + else: + bootheader_data[bootcfg_start + 16:bootcfg_start + 16 + 32] = hash + if img_create_get_crc_ignore(bootheader_data) == 1: + bflb_utils.printf('Header crc ignored') + else: + hd_crcarray = bflb_utils.get_crc32_bytearray(bootheader_data[custom_cfg_len:header_len - 4]) + bootheader_data[header_len - 4:header_len] = hd_crcarray + bflb_utils.printf('Header crc: ', binascii.hexlify(hd_crcarray)) + return bootheader_data[0:header_len] + + +def img_create_update_segheader(segheader, segdatalen, segdatacrc): + segheader[4:8] = segdatalen + segheader[8:12] = segdatacrc + return segheader + + +def reverse_str_data_unit_number(str_data_unit_number): + """ + high position low data + data unit number:00000280 + storage format: 80020000 + """ + reverse_str = '' + if len(str_data_unit_number) == 8: + str_part1 = str_data_unit_number[0:2] + str_part2 = str_data_unit_number[2:4] + str_part3 = str_data_unit_number[4:6] + str_part4 = str_data_unit_number[6:8] + reverse_str = str_part4 + str_part3 + str_part2 + str_part1 + return reverse_str + + +def reverse_iv(need_reverse_iv_bytearray): + temp_reverse_iv_bytearray = binascii.hexlify(need_reverse_iv_bytearray).decode() + if temp_reverse_iv_bytearray[24:32] != '00000000': + bflb_utils.printf('The lower 4 bytes of IV should be set 0, if set IV is less than 16 bytes, make up 0 for the low 4 bytes of IV ') + sys.exit() + reverse_iv_bytearray = '00000000' + temp_reverse_iv_bytearray[0:24] + return reverse_iv_bytearray + + +def img_create_encrypt_data_xts(data_bytearray, key_bytearray, iv_bytearray, encrypt): + counter = binascii.hexlify(iv_bytearray[4:16]).decode() + data_unit_number = 0 + key = ( + key_bytearray[0:16], key_bytearray[16:32]) + if encrypt == 2 or encrypt == 3: + key = ( + key_bytearray, key_bytearray) + cipher = AES_XTS.new(key, AES_XTS.MODE_XTS) + total_len = len(data_bytearray) + ciphertext = bytearray(0) + deal_len = 0 + while deal_len < total_len: + data_unit_number = str(hex(data_unit_number)).replace('0x', '') + data_unit_number_to_str = str(data_unit_number) + right_justify_str = data_unit_number_to_str.rjust(8, '0') + reverse_data_unit_number_str = reverse_str_data_unit_number(right_justify_str) + tweak = reverse_data_unit_number_str + counter + tweak = bflb_utils.hexstr_to_bytearray('0' * (32 - len(tweak)) + tweak) + if 32 + deal_len <= total_len: + cur_block = data_bytearray[0 + deal_len:32 + deal_len] + ciphertext += cipher.encrypt(cur_block, tweak) + else: + cur_block = data_bytearray[0 + deal_len:16 + deal_len] + bytearray(16) + ciphertext += cipher.encrypt(cur_block, tweak)[0:16] + deal_len += 32 + data_unit_number = int(data_unit_number, 16) + data_unit_number += 1 + + return ciphertext + + +def img_create_sign_data(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() + bflb_utils.printf('Private key: ', binascii.hexlify(sk.to_string())) + bflb_utils.printf('Public key: ', binascii.hexlify(pk_data)) + pk_hash = img_create_sha256_data(pk_data) + bflb_utils.printf('Public key hash=', binascii.hexlify(pk_hash)) + signature = sk.sign(data_bytearray, hashfunc=(hashlib.sha256), sigencode=(ecdsa.util.sigencode_string)) + bflb_utils.printf('Signature=', binascii.hexlify(signature)) + len_array = bflb_utils.int_to_4bytearray_l(len(signature)) + sig_field = len_array + signature + crcarray = bflb_utils.get_crc32_bytearray(sig_field) + return ( + pk_data, pk_hash, sig_field + crcarray) + + +def img_create_read_file_append_crc(file, crc): + fp = open(file, 'rb') + read_data = bytearray(fp.read()) + crcarray = bytearray(0) + if crc: + crcarray = bflb_utils.get_crc32_bytearray(read_data) + fp.close() + return read_data + crcarray + + +def encrypt_loader_bin_do(file, sign, encrypt, temp_encrypt_key, temp_encrypt_iv, publickey_file, privatekey_file): + if encrypt != 0 or sign != 0: + encrypt_key = bytearray(0) + encrypt_iv = bytearray(0) + load_helper_bin_header = bytearray(0) + load_helper_bin_body = bytearray(0) + offset = bootcfg_start + sign_pos = 0 + encrypt_type_pos = 2 + pk_data = bytearray(0) + signature = bytearray(0) + aesiv_data = bytearray(0) + data_tohash = bytearray(0) + with open(file, 'rb') as fp: + load_helper_bin = fp.read() + load_helper_bin_header = load_helper_bin[0:header_len] + load_helper_bin_body = load_helper_bin[header_len:] + if load_helper_bin_header != bytearray(0): + if load_helper_bin_body != bytearray(0): + load_helper_bin_body = bflb_utils.add_to_16(load_helper_bin_body) + if encrypt != 0: + encrypt_key = bflb_utils.hexstr_to_bytearray(temp_encrypt_key) + encrypt_iv = bflb_utils.hexstr_to_bytearray(temp_encrypt_iv) + iv_crcarray = bflb_utils.get_crc32_bytearray(encrypt_iv) + aesiv_data = encrypt_iv + iv_crcarray + data_tohash = data_tohash + aesiv_data + load_helper_bin_body_encrypt = bflb_utils.img_create_encrypt_data(load_helper_bin_body, encrypt_key, encrypt_iv, 0) + else: + load_helper_bin_body_encrypt = load_helper_bin_body + data = bytearray(load_helper_bin_header) + oldval = bflb_utils.bytearray_to_int(bflb_utils.bytearray_reverse(data[offset:offset + 4])) + newval = oldval + if encrypt != 0: + newval = newval | 1 << encrypt_type_pos + if sign != 0: + newval = newval | 1 << sign_pos + data_tohash += load_helper_bin_body_encrypt + pk_data, pk_hash, signature = img_create_sign_data(data_tohash, privatekey_file, publickey_file) + pk_data = pk_data + bflb_utils.get_crc32_bytearray(pk_data) + data[offset:offset + 4] = bflb_utils.int_to_4bytearray_l(newval) + load_helper_bin_header = data + load_helper_bin_encrypt = load_helper_bin_header + pk_data + signature + aesiv_data + load_helper_bin_body_encrypt + hashfun = hashlib.sha256() + hashfun.update(load_helper_bin_body_encrypt) + hash = bflb_utils.hexstr_to_bytearray(hashfun.hexdigest()) + load_helper_bin_data = bytearray(load_helper_bin_encrypt) + load_helper_bin_encrypt = img_create_update_bootheader_if(load_helper_bin_data, hash, 1) + return ( + True, load_helper_bin_encrypt) + return (False, None) + + +def img_creat_process(group_type, flash_img, cfg, security=False): + encrypt_blk_size = 16 + padding = bytearray(encrypt_blk_size) + data_tohash = bytearray(0) + cfg_section = '' + img_update_efuse_fun = img_update_efuse_group0 + cfg_section = 'Img_Group0_Cfg' + 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('|'): + if files: + segdata_file.append(str(files)) + + boot_header_file = cfg.get(cfg_section, 'boot_header_file') + bootheader_data = img_create_read_file_append_crc(boot_header_file, 0) + encrypt = 0 + sign, encrypt, key_sel, xts_mode = img_create_get_sign_encrypt_info(bootheader_data) + boot_entry = img_create_get_img_start_addr(bootheader_data) + aesiv_data = bytearray(0) + pk_data = bytearray(0) + publickey_file = '' + privatekey_file_uecc = '' + if sign != 0: + bflb_utils.printf('Image need sign') + publickey_file = cfg.get(cfg_section, 'publickey_file') + privatekey_file_uecc = cfg.get(cfg_section, 'privatekey_file_uecc') + if encrypt != 0: + bflb_utils.printf('Image need encrypt ', encrypt) + if xts_mode == 1: + bflb_utils.printf('Enable xts mode') + encrypt_key_org = bflb_utils.hexstr_to_bytearray(cfg.get(cfg_section, 'aes_key_org')) + if encrypt == 1: + if xts_mode == 1: + encrypt_key = encrypt_key_org[0:32] + else: + encrypt_key = encrypt_key_org[0:16] + else: + if encrypt == 2: + if xts_mode == 1: + encrypt_key = encrypt_key_org[0:32] + else: + encrypt_key = encrypt_key_org[0:32] + else: + if encrypt == 3: + if xts_mode == 1: + encrypt_key = encrypt_key_org[0:24] + else: + encrypt_key = encrypt_key_org[0:24] + bflb_utils.printf('Key= ', binascii.hexlify(encrypt_key)) + iv_value = cfg.get(cfg_section, 'aes_iv') + if xts_mode == 1: + iv_value = iv_value[24:32] + iv_value[:24] + encrypt_iv = bflb_utils.hexstr_to_bytearray(iv_value) + iv_crcarray = bflb_utils.get_crc32_bytearray(encrypt_iv) + aesiv_data = encrypt_iv + iv_crcarray + seg_cnt = len(segheader_file) + segdata_cnt = len(segdata_file) + if flash_img == 0: + if seg_cnt != segdata_cnt: + bflb_utils.printf('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: + seg_data = bytearray(0) + if segdata_file[i] != 'UNUSED': + seg_data = img_create_read_file_append_crc(segdata_file[i], 0) + else: + 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 = bflb_utils.get_crc32_bytearray(seg_data) + seg_data_list.append(seg_data) + seg_header = img_create_read_file_append_crc(segheader_file[i], 0) + seg_header = img_create_update_segheader(seg_header, bflb_utils.int_to_4bytearray_l(len(seg_data)), segdata_crcarray) + segheader_crcarray = bflb_utils.get_crc32_bytearray(seg_header) + seg_header = seg_header + segheader_crcarray + seg_header_list.append(seg_header) + i = i + 1 + + i = 0 + cnt = 0 + while i < seg_cnt: + if seg_header_list[i][4:8] != bytearray(4): + data_toencrypt += seg_header_list[i] + data_toencrypt += seg_data_list[i] + cnt += 1 + else: + i += 1 + + seg_cnt = cnt + else: + seg_data = img_get_one_group_img(boot_entry, segdata_file) + 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) + if encrypt != 0: + unencrypt_mfg_data = bytearray(0) + if seg_cnt >= 8192: + if data_toencrypt[4096:4100] == bytearray('0mfg'.encode('utf-8')): + unencrypt_mfg_data = data_toencrypt[4096:8192] + if xts_mode != 0: + data_toencrypt = img_create_encrypt_data_xts(data_toencrypt, encrypt_key, encrypt_iv, encrypt) + else: + data_toencrypt = img_create_encrypt_data(data_toencrypt, encrypt_key, encrypt_iv, flash_img) + if unencrypt_mfg_data != bytearray(0): + data_toencrypt = data_toencrypt[0:4096] + unencrypt_mfg_data + data_toencrypt[8192:] + fw_data = bytearray(0) + data_tohash += data_toencrypt + fw_data = data_toencrypt + hash = img_create_sha256_data(data_tohash) + bflb_utils.printf('Image hash is ', binascii.hexlify(hash)) + 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 + bflb_utils.get_crc32_bytearray(pk_data) + flashCfgAddr = len(bootheader_data + pk_data + signature + aesiv_data) + flashCfgListLen = 0 + flashCfgList = bytearray(0) + flashCfgTable = bytearray(0) + if flash_img == 1: + if bootheader_data[233:234] == b'\xff': + flashCfgList, flashCfgTable, flashCfgListLen = create_flashcfg_table(flashCfgAddr) + bootheader_data = img_create_update_custom_bootheader(bootheader_data, seg_cnt, hash, signature, pk_data, aesiv_data) + bootheader_data = img_create_update_bootheader(bootheader_data, hash, seg_cnt, flashCfgAddr, flashCfgListLen) + if flash_img == 1: + bflb_utils.printf('Write flash img') + bootinfo_file_name = cfg.get(cfg_section, 'bootinfo_file') + fp = open(bootinfo_file_name, 'wb+') + bootinfo = bootheader_data + pk_data + signature + aesiv_data + flashCfgList + flashCfgTable + 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() + fw_data_hash = img_create_sha256_data(fw_data) + fp = open(fw_file_name.replace('.bin', '_withhash.bin'), 'wb+') + fp.write(fw_data + fw_data_hash) + fp.close() + if encrypt != 0: + flash_encrypt_type = 0 + if encrypt == 1: + flash_encrypt_type = 1 + if encrypt == 2: + flash_encrypt_type = 3 + if encrypt == 3: + flash_encrypt_type = 2 + if xts_mode == 1: + flash_encrypt_type += 3 + img_update_efuse_fun(cfg, sign, pk_hash, flash_encrypt_type, encrypt_key + bytearray(32 - len(encrypt_key)), key_sel, None, security) + else: + img_update_efuse_fun(cfg, sign, pk_hash, encrypt, None, key_sel, None, security) + else: + bflb_utils.printf('Write if img') + 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() + if encrypt != 0: + if_encrypt_type = 0 + if encrypt == 1: + if_encrypt_type = 1 + if encrypt == 2: + if_encrypt_type = 3 + if encrypt == 3: + if_encrypt_type = 2 + if xts_mode == 1: + if_encrypt_type += 3 + img_update_efuse_fun(cfg, sign, pk_hash, if_encrypt_type, None, key_sel, encrypt_key + bytearray(32 - len(encrypt_key)), security) + else: + img_update_efuse_fun(cfg, sign, pk_hash, 0, None, key_sel, bytearray(32), security) + return ( + 'OK', data_tohash) + + +def img_create_do(args, img_dir_path=None, config_file=None): + bflb_utils.printf('Image create path: ', img_dir_path) + if config_file is None: + config_file = img_dir_path + '/img_create_cfg.ini' + bflb_utils.printf('Config file: ', config_file) + cfg = BFConfigParser() + cfg.read(config_file) + group_type = 'all' + img_type = 'media' + signer = 'none' + security = False + data_tohash = bytearray(0) + try: + if args.image: + img_type = args.image + if args.group: + group_type = args.group + if args.signer: + signer = args.signer + if args.security: + security = args.security == 'efuse' + except Exception as e: + try: + bflb_utils.printf(e) + finally: + e = None + del e + + if img_type == 'media': + flash_img = 1 + else: + flash_img = 0 + ret0 = ret1 = 'OK' + if group_type == 'group0' or group_type == 'all': + ret0, data_tohash0 = img_creat_process('group0', flash_img, cfg, security) + else: + img_creat_process('', flash_img, cfg, security) + if ret0 != 'OK': + bflb_utils.printf('Fail to create group0 images!') + return + if ret1 != 'OK': + bflb_utils.printf('Fail to create group1 images!') + + +def create_sp_media_image(config, cpu_type=None, security=False): + bflb_utils.printf('========= sp image create =========') + cfg = BFConfigParser() + cfg.read(config) + img_creat_process('group0', 1, cfg, security) + + +if __name__ == '__main__': + data_bytearray = codecs.decode('42464E500100000046434647040101036699FF039F00B7E904EF0001C72052D8060232000B010B013B01BB006B01EB02EB02025000010001010002010101AB01053500000131000038FF20FF77030240770302F02C01B004B0040500FFFF030036C3DD9E5043464704040001010105000101050000010101A612AC86000144650020000000000000503100007A6345494BCABEC7307FD8F8396729EB67DDC8C63B7AD69B797B08564E982A8701000000000000000000000000000000000000D80000000000010000000000000000000000200100000001D80000000000010000000000000000000000200200000002580000000000010000000000000000000000200300000003580000000000010000D0C57503C09E750300200400000004580000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000935F92BB', 'hex') + key_bytearray = codecs.decode('fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0000102030405060708090a0b0c0d0e0f', 'hex') + need_reverse_iv_bytearray = codecs.decode('01000000000000000000000000000000', 'hex') + iv_bytearray = codecs.decode(reverse_iv(need_reverse_iv_bytearray), 'hex') + img_create_encrypt_data_xts(data_bytearray, key_bytearray, iv_bytearray, 0) +# okay decompiling ./libs/base/wb03/img_create_do.pyc diff --git a/libs/base/wb03/jlink_load_cfg.py b/libs/base/wb03/jlink_load_cfg.py new file mode 100644 index 0000000..70135f3 --- /dev/null +++ b/libs/base/wb03/jlink_load_cfg.py @@ -0,0 +1,12 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/wb03/jlink_load_cfg.py +jlink_shake_hand_addr = '4201BFF0' +jlink_data_addr = '4201C000' +jlink_load_addr = '22010000' +jlink_core_type = 'RISC-V' +jlink_set_tif = 0 +jlink_run_addr = '22010000' +# okay decompiling ./libs/base/wb03/jlink_load_cfg.pyc diff --git a/libs/base/wb03/openocd_load_cfg.py b/libs/base/wb03/openocd_load_cfg.py new file mode 100644 index 0000000..baa62b4 --- /dev/null +++ b/libs/base/wb03/openocd_load_cfg.py @@ -0,0 +1,12 @@ +# decompyle3 version 3.9.0 +# Python bytecode version base 3.7.0 (3394) +# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) +# [GCC 12.2.1 20220924] +# Embedded file name: libs/base/wb03/openocd_load_cfg.py +openocd_shake_hand_addr = '4201BFF0' +openocd_data_addr = '4201C000' +openocd_load_addr = '22010000' +openocd_core_type = 'RISC-V' +openocd_set_tif = 0 +openocd_run_addr = '22010000' +# okay decompiling ./libs/base/wb03/openocd_load_cfg.pyc diff --git a/pylink/__init__.py b/pylink/__init__.py deleted file mode 100644 index d3bd4d5..0000000 --- a/pylink/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -# decompyle3 version 3.9.0 -# Python bytecode version base 3.7.0 (3394) -# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) -# [GCC 12.2.1 20220924] -# Embedded file name: pylink/__init__.py -__version__ = '0.5.0' -__title__ = 'pylink' -__author__ = 'Square Embedded Software Team' -__author_email__ = 'esw-team@squareup.com' -__copyright__ = 'Copyright 2017 Square, Inc.' -__license__ = 'Apache 2.0' -__url__ = 'http://www.github.com/Square/pylink' -__description__ = 'Python interface for SEGGER J-Link.' -__long_description__ = "This module provides a Python implementation of the\nJ-Link SDK by leveraging the SDK's DLL.\n" -from .enums import * -from .errors import * -from .jlink import * -from .library import * -from .structs import * -from .unlockers import * -# okay decompiling ./pylink/__init__.pyc diff --git a/pylink/binpacker.py b/pylink/binpacker.py deleted file mode 100644 index 1635e3b..0000000 --- a/pylink/binpacker.py +++ /dev/null @@ -1,57 +0,0 @@ -# decompyle3 version 3.9.0 -# Python bytecode version base 3.7.0 (3394) -# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) -# [GCC 12.2.1 20220924] -# Embedded file name: pylink/binpacker.py -import ctypes, math -BITS_PER_BYTE = 8 - -def pack_size(value): - """Returns the number of bytes required to represent a given value. - - Args: - value (int): the natural number whose size to get - - Returns: - The minimal number of bytes required to represent the given integer. - - Raises: - ValueError: if ``value < 0``. - TypeError: if ``value`` is not a number. - """ - if value == 0: - return 1 - if value < 0: - raise ValueError('Expected non-negative integer.') - return int(math.log(value, 256)) + 1 - - -def pack(value, nbits=None): - """Packs a given value into an array of 8-bit unsigned integers. - - If ``nbits`` is not present, calculates the minimal number of bits required - to represent the given ``value``. The result is little endian. - - Args: - value (int): the integer value to pack - nbits (int): optional number of bits to use to represent the value - - Returns: - An array of ``ctypes.c_uint8`` representing the packed ``value``. - - Raises: - ValueError: if ``value < 0`` and ``nbits`` is ``None`` or ``nbits <= 0``. - TypeError: if ``nbits`` or ``value`` are not numbers. - """ - if nbits is None: - nbits = pack_size(value) * BITS_PER_BYTE - else: - if nbits <= 0: - raise ValueError('Given number of bits must be greater than 0.') - buf_size = int(math.ceil(nbits / float(BITS_PER_BYTE))) - buf = (ctypes.c_uint8 * buf_size)() - for idx, _ in enumerate(buf): - buf[idx] = value >> idx * BITS_PER_BYTE & 255 - - return buf -# okay decompiling ./pylink/binpacker.pyc diff --git a/pylink/decorators.py b/pylink/decorators.py deleted file mode 100644 index c1b730f..0000000 --- a/pylink/decorators.py +++ /dev/null @@ -1,52 +0,0 @@ -# decompyle3 version 3.9.0 -# Python bytecode version base 3.7.0 (3394) -# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) -# [GCC 12.2.1 20220924] -# Embedded file name: pylink/decorators.py -from . import threads -import functools - -def async_decorator(func): - """Asynchronous function decorator. Interprets the function as being - asynchronous, so returns a function that will handle calling the - Function asynchronously. - - Args: - func (function): function to be called asynchronously - - Returns: - The wrapped function. - - Raises: - AttributeError: if ``func`` is not callable - """ - - @functools.wraps(func) - def async_wrapper(*args, **kwargs): - if not ('callback' not in kwargs or kwargs['callback']): - return func(*args, **kwargs) - callback = kwargs.pop('callback') - if not callable(callback): - raise TypeError("Expected 'callback' is not callable.") - - def thread_func(*args, **kwargs): - exception, res = (None, None) - try: - res = func(*args, **kwargs) - except Exception as e: - try: - exception = e - finally: - e = None - del e - - return callback(exception, res) - - thread = threads.ThreadReturn(target=thread_func, args=args, - kwargs=kwargs) - thread.daemon = True - thread.start() - return thread - - return async_wrapper -# okay decompiling ./pylink/decorators.pyc diff --git a/pylink/enums.py b/pylink/enums.py deleted file mode 100644 index acd6eab..0000000 --- a/pylink/enums.py +++ /dev/null @@ -1,528 +0,0 @@ -# decompyle3 version 3.9.0 -# Python bytecode version base 3.7.0 (3394) -# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) -# [GCC 12.2.1 20220924] -# Embedded file name: pylink/enums.py -import ctypes - -class JLinkGlobalErrors(object): - __doc__ = 'Enumeration for the error codes which any J-Link SDK DLL API-function\n can have as a return value.' - UNSPECIFIED_ERROR = -1 - EMU_NO_CONNECTION = -256 - EMU_COMM_ERROR = -257 - DLL_NOT_OPEN = -258 - VCC_FAILURE = -259 - INVALID_HANDLE = -260 - NO_CPU_FOUND = -261 - EMU_FEATURE_UNSUPPORTED = -262 - EMU_NO_MEMORY = -263 - TIF_STATUS_ERROR = -264 - FLASH_PROG_COMPARE_FAILED = -265 - FLASH_PROG_PROGRAM_FAILED = -266 - FLASH_PROG_VERIFY_FAILED = -267 - OPEN_FILE_FAILED = -268 - UNKNOWN_FILE_FORMAT = -269 - WRITE_TARGET_MEMORY_FAILED = -270 - DEVICE_FEATURE_NOT_SUPPORTED = -271 - WRONG_USER_CONFIG = -272 - NO_TARGET_DEVICE_SELECTED = -273 - CPU_IN_LOW_POWER_MODE = -274 - - @classmethod - def to_string(cls, error_code): - """Returns the string message for the given ``error_code``. - - Args: - cls (JlinkGlobalErrors): the ``JLinkGlobalErrors`` class - error_code (int): error code to convert - - Returns: - An error string corresponding to the error code. - - Raises: - ValueError: if the error code is invalid. - """ - if error_code == cls.EMU_NO_CONNECTION: - return 'No connection to emulator.' - if error_code == cls.EMU_COMM_ERROR: - return 'Emulator connection error.' - if error_code == cls.DLL_NOT_OPEN: - return "DLL has not been opened. Did you call '.connect()'?" - if error_code == cls.VCC_FAILURE: - return 'Target system has no power.' - if error_code == cls.INVALID_HANDLE: - return 'Given file / memory handle is invalid.' - if error_code == cls.NO_CPU_FOUND: - return 'Could not find supported CPU.' - if error_code == cls.EMU_FEATURE_UNSUPPORTED: - return 'Emulator does not support the selected feature.' - if error_code == cls.EMU_NO_MEMORY: - return 'Emulator out of memory.' - if error_code == cls.TIF_STATUS_ERROR: - return 'Target interface error.' - if error_code == cls.FLASH_PROG_COMPARE_FAILED: - return 'Programmed data differs from source data.' - if error_code == cls.FLASH_PROG_PROGRAM_FAILED: - return 'Programming error occured.' - if error_code == cls.FLASH_PROG_VERIFY_FAILED: - return 'Error while verifying programmed data.' - if error_code == cls.OPEN_FILE_FAILED: - return 'Specified file could not be opened.' - if error_code == cls.UNKNOWN_FILE_FORMAT: - return 'File format of selected file is not supported.' - if error_code == cls.WRITE_TARGET_MEMORY_FAILED: - return 'Could not write target memory.' - if error_code == cls.DEVICE_FEATURE_NOT_SUPPORTED: - return 'Feature not supported by connected device.' - if error_code == cls.WRONG_USER_CONFIG: - return 'User configured DLL parameters incorrectly.' - if error_code == cls.NO_TARGET_DEVICE_SELECTED: - return 'User did not specify core to connect to.' - if error_code == cls.CPU_IN_LOW_POWER_MODE: - return 'Target CPU is in low power mode.' - if error_code == cls.UNSPECIFIED_ERROR: - return 'Unspecified error.' - raise ValueError('Invalid error code: %d' % error_code) - - -class JLinkEraseErrors(JLinkGlobalErrors): - __doc__ = 'Enumeration for the error codes generated during an erase operation.' - ILLEGAL_COMMAND = -5 - - @classmethod - def to_string(cls, error_code): - if error_code == cls.ILLEGAL_COMMAND: - return 'Failed to erase sector.' - return super(JLinkEraseErrors, cls).to_string(error_code) - - -class JLinkFlashErrors(JLinkGlobalErrors): - __doc__ = 'Enumeration for the error codes generated during a flash operation.' - COMPARE_ERROR = -2 - PROGRAM_ERASE_ERROR = -3 - VERIFICATION_ERROR = -4 - - @classmethod - def to_string(cls, error_code): - if error_code == cls.COMPARE_ERROR: - return 'Error comparing flash content to programming data.' - if error_code == cls.PROGRAM_ERASE_ERROR: - return 'Error during program/erase phase.' - if error_code == cls.VERIFICATION_ERROR: - return 'Error verifying programmed data.' - return super(JLinkFlashErrors, cls).to_string(error_code) - - -class JLinkWriteErrors(JLinkGlobalErrors): - __doc__ = 'Enumeration for the error codes generated during a write.' - ZONE_NOT_FOUND_ERROR = -5 - - @classmethod - def to_string(cls, error_code): - if error_code == cls.ZONE_NOT_FOUND_ERROR: - return 'Zone not found' - return super(JLinkWriteErrors, cls).to_string(error_code) - - -class JLinkReadErrors(JLinkGlobalErrors): - __doc__ = 'Enumeration for the error codes generated during a read.' - ZONE_NOT_FOUND_ERROR = -5 - - @classmethod - def to_string(cls, error_code): - if error_code == cls.ZONE_NOT_FOUND_ERROR: - return 'Zone not found' - return super(JLinkReadErrors, cls).to_string(error_code) - - -class JLinkDataErrors(JLinkGlobalErrors): - __doc__ = 'Enumeration for the error codes generated when setting a data event.' - ERROR_UNKNOWN = 2147483648 - ERROR_NO_MORE_EVENTS = 2147483649 - ERROR_NO_MORE_ADDR_COMP = 2147483650 - ERROR_NO_MORE_DATA_COMP = 2147483652 - ERROR_INVALID_ADDR_MASK = 2147483680 - ERROR_INVALID_DATA_MASK = 2147483712 - ERROR_INVALID_ACCESS_MASK = 2147483776 - - @classmethod - def to_string(cls, error_code): - if error_code == cls.ERROR_UNKNOWN: - return 'Unknown error.' - if error_code == cls.ERROR_NO_MORE_EVENTS: - return 'There are no more available watchpoint units.' - if error_code == cls.ERROR_NO_MORE_ADDR_COMP: - return 'No more address comparisons can be set.' - if error_code == cls.ERROR_NO_MORE_DATA_COMP: - return 'No more data comparisons can be set.' - if error_code == cls.ERROR_INVALID_ADDR_MASK: - return 'Invalid flags passed for the address mask.' - if error_code == cls.ERROR_INVALID_DATA_MASK: - return 'Invalid flags passed for the data mask.' - if error_code == cls.ERROR_INVALID_ACCESS_MASK: - return 'Invalid flags passed for the access mask.' - return super(JLinkDataErrors, cls).to_string(error_code) - - -class JLinkRTTErrors(JLinkGlobalErrors): - __doc__ = 'Enumeration for error codes from RTT.' - RTT_ERROR_CONTROL_BLOCK_NOT_FOUND = -2 - - @classmethod - def to_string(cls, error_code): - if error_code == cls.RTT_ERROR_CONTROL_BLOCK_NOT_FOUND: - return 'The RTT Control Block has not yet been found (wait?)' - return super(JLinkRTTErrors, cls).to_string(error_code) - - -class JLinkHost(object): - __doc__ = 'Enumeration for the different JLink hosts: currently only IP and USB.' - USB = 1 - IP = 2 - USB_OR_IP = USB | IP - - -class JLinkInterfaces(object): - __doc__ = 'Target interfaces for the J-Link.' - JTAG = 0 - SWD = 1 - FINE = 3 - ICSP = 4 - SPI = 5 - C2 = 6 - - -class JLinkResetStrategyCortexM3(object): - __doc__ = 'Target reset strategies for the J-Link.\n\n Attributes:\n NORMAL: default reset strategy, does whatever is best to reset.\n CORE: only the core is reset via the ``VECTRESET`` bit.\n RESETPIN: pulls the reset pin low to reset the core and peripherals.\n CONNECT_UNDER_RESET: J-Link connects to target while keeping reset\n active. This is recommented for STM32 devices.\n HALT_AFTER_BTL: halt the core after the bootloader is executed.\n HALT_BEFORE_BTL: halt the core before the bootloader is executed.\n KINETIS: performs a normal reset, but also disables the watchdog.\n ADI_HALT_AFTER_KERNEL: sets the ``SYSRESETREQ`` bit in the ``AIRCR`` in\n order to reset the device.\n CORE_AND_PERIPHERALS: sets the ``SYSRESETREQ`` bit in the ``AIRCR``, and\n the ``VC_CORERESET`` bit in the ``DEMCR`` to make sure that the CPU is\n halted immediately after reset.\n LPC1200: reset for LPC1200 devices.\n S3FN60D: reset for Samsung S3FN60D devices.\n\n Note:\n Please see the J-Link SEGGER Documentation, UM8001, for full information\n about the different reset strategies.\n ' - NORMAL = 0 - CORE = 1 - RESETPIN = 2 - CONNECT_UNDER_RESET = 3 - HALT_AFTER_BTL = 4 - HALT_BEFORE_BTL = 5 - KINETIS = 6 - ADI_HALT_AFTER_KERNEL = 7 - CORE_AND_PERIPHERALS = 8 - LPC1200 = 9 - S3FN60D = 10 - - -class JLinkFunctions(object): - __doc__ = 'Collection of function prototype and type builders for the J-Link SDK\n API calls.' - LOG_PROTOTYPE = ctypes.CFUNCTYPE(None, ctypes.c_char_p) - UNSECURE_HOOK_PROTOTYPE = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_uint32) - FLASH_PROGRESS_PROTOTYPE = ctypes.CFUNCTYPE(None, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_int) - - -class JLinkCore(object): - __doc__ = 'Enumeration for the different CPU core identifiers.\n\n These are the possible cores for targets the J-Link is connected to.\n Note that these are bitfields.' - NONE = 0 - ANY = 4294967295 - CORTEX_M1 = 16777471 - COLDFIRE = 50331647 - CORTEX_M3 = 50331903 - CORTEX_M3_R1P0 = 50331664 - CORTEX_M3_R1P1 = 50331665 - CORTEX_M3_R2P0 = 50331680 - SIM = 83886079 - XSCALE = 100663295 - CORTEX_M0 = 100663551 - CORTEX_M_V8BASEL = 100729087 - ARM7 = 134217727 - ARM7TDMI = 117440767 - ARM7TDMI_R3 = 117440575 - ARM7TDMI_R4 = 117440591 - ARM7TDMI_S = 117441023 - ARM7TDMI_S_R3 = 117440831 - ARM7TDMI_S_R4 = 117440847 - CORTEX_A8 = 134217983 - CORTEX_A7 = 134742271 - CORTEX_A9 = 134807807 - CORTEX_A12 = 134873343 - CORTEX_A15 = 134938879 - CORTEX_A17 = 135004415 - ARM9 = 167772159 - ARM9TDMI_S = 150995455 - ARM920T = 153092351 - ARM922T = 153223423 - ARM926EJ_S = 153485823 - ARM946E_S = 155582975 - ARM966E_S = 157680127 - ARM968E_S = 157811199 - ARM11 = 201326591 - ARM1136 = 188153855 - ARM1136J = 188089087 - ARM1136J_S = 188089343 - ARM1136JF = 188090111 - ARM1136JF_S = 188090367 - ARM1156 = 190251007 - ARM1176 = 192348159 - ARM1176J = 192283391 - ARM1176J_S = 192283647 - ARM1176JF = 192284415 - ARM1176JF_S = 192284671 - CORTEX_R4 = 201326847 - CORTEX_R5 = 201392383 - RX = 234881023 - RX610 = 218169343 - RX62N = 218234879 - RX62T = 218300415 - RX63N = 218365951 - RX630 = 218431487 - RX63T = 218497023 - RX621 = 218562559 - RX62G = 218628095 - RX631 = 218693631 - RX210 = 219217919 - RX21A = 219283455 - RX220 = 219348991 - RX230 = 219414527 - RX231 = 219480063 - RX23T = 219545599 - RX111 = 220266495 - RX110 = 220332031 - RX113 = 220397567 - RX64M = 221315071 - RX71M = 221380607 - CORTEX_M4 = 234881279 - CORTEX_M7 = 234946815 - CORTEX_M_V8MAINL = 235012351 - CORTEX_A5 = 251658495 - POWER_PC = 285212671 - POWER_PC_N1 = 285147391 - POWER_PC_N2 = 285147647 - MIPS = 301989887 - MIPS_M4K = 285278207 - MIPS_MICROAPTIV = 285343743 - EFM8_UNSPEC = 318767103 - CIP51 = 302055423 - - -class JLinkDeviceFamily(object): - __doc__ = 'Enumeration for the difference device families.\n\n These are the possible device families for targets that the J-Link is\n connected to.' - AUTO = 0 - CORTEX_M1 = 1 - COLDFIRE = 2 - CORTEX_M3 = 3 - SIMULATOR = 4 - XSCALE = 5 - CORTEX_M0 = 6 - ARM7 = 7 - CORTEX_A8 = 8 - CORTEX_A9 = 8 - ARM9 = 9 - ARM10 = 10 - ARM11 = 11 - CORTEX_R4 = 12 - RX = 13 - CORTEX_M4 = 14 - CORTEX_A5 = 15 - POWERPC = 16 - MIPS = 17 - EFM8 = 18 - ANY = 255 - - -class JLinkFlags(object): - __doc__ = 'Enumeration for the different flags that are passed to the J-Link C SDK\n API methods.' - GO_OVERSTEP_BP = 1 - DLG_BUTTON_YES = 1 - DLG_BUTTON_NO = 2 - DLG_BUTTON_OK = 4 - DLG_BUTTON_CANCEL = 8 - HW_PIN_STATUS_LOW = 0 - HW_PIN_STATUS_HIGH = 1 - HW_PIN_STATUS_UNKNOWN = 255 - - -class JLinkSWOInterfaces(object): - __doc__ = 'Serial Wire Output (SWO) interfaces.' - UART = 0 - MANCHESTER = 1 - - -class JLinkSWOCommands(object): - __doc__ = 'Serial Wire Output (SWO) commands.' - START = 0 - STOP = 1 - FLUSH = 2 - GET_SPEED_INFO = 3 - GET_NUM_BYTES = 10 - SET_BUFFERSIZE_HOST = 20 - SET_BUFFERSIZE_EMU = 21 - - -class JLinkCPUCapabilities(object): - __doc__ = 'Target CPU Cabilities.' - READ_MEMORY = 2 - WRITE_MEMORY = 4 - READ_REGISTERS = 8 - WRITE_REGISTERS = 16 - GO = 32 - STEP = 64 - HALT = 128 - IS_HALTED = 256 - RESET = 512 - RUN_STOP = 1024 - TERMINAL = 2048 - DCC = 16384 - HSS = 32768 - - -class JLinkHaltReasons(object): - __doc__ = 'Halt reasons for the CPU.\n\n Attributes:\n DBGRQ: CPU has been halted because DBGRQ signal asserted.\n CODE_BREAKPOINT: CPU has been halted because of code breakpoint match.\n DATA_BREAKPOINT: CPU has been halted because of data breakpoint match.\n VECTOR_CATCH: CPU has been halted because of vector catch.\n ' - DBGRQ = 0 - CODE_BREAKPOINT = 1 - DATA_BREAKPOINT = 2 - VECTOR_CATCH = 3 - - -class JLinkVectorCatchCortexM3(object): - __doc__ = 'Vector catch types for the ARM Cortex M3.\n\n Attributes:\n CORE_RESET: The CPU core reset.\n MEM_ERROR: A memory management error occurred.\n COPROCESSOR_ERROR: Usage fault error accessing the Coprocessor.\n CHECK_ERROR: Usage fault error on enabled check.\n STATE_ERROR: Usage fault state error.\n BUS_ERROR: Normal bus error.\n INT_ERROR: Interrupt or exception service error.\n HARD_ERROR: Hard fault error.\n ' - CORE_RESET = 1 - MEM_ERROR = 16 - COPROCESSOR_ERROR = 32 - CHECK_ERROR = 64 - STATE_ERROR = 128 - BUS_ERROR = 256 - INT_ERROR = 512 - HARD_ERROR = 1024 - - -class JLinkBreakpoint(object): - __doc__ = 'J-Link breakpoint types.\n\n Attributes:\n SW_RAM: Software breakpont located in RAM.\n SW_FLASH: Software breakpoint located in flash.\n SW: Software breakpoint located in RAM or flash.\n HW: Hardware breakpoint.\n ANY: Allows specifying any time of breakpoint.\n ARM: Breakpoint in ARM mode (only available on ARM 7/9 cores).\n THUMB: Breakpoint in THUMB mode (only available on ARM 7/9 cores).\n ' - SW_RAM = 16 - SW_FLASH = 32 - SW = 240 - HW = 4294967040 - ANY = 4294967280 - ARM = 1 - THUMB = 2 - - -class JLinkBreakpointImplementation(object): - __doc__ = 'J-Link breakpoint implementation types.\n\n Attributes:\n HARD: Hardware breakpoint using a breakpoint unit.\n SOFT: Software breakpoint using a breakpoint instruction.\n PENDING: Breakpoint has not been set yet.\n FLASH: Breakpoint set in flash.\n ' - HARD = 1 - SOFT = 2 - PENDING = 4 - FLASH = 16 - - -class JLinkEventTypes(object): - __doc__ = 'J-Link data event types.\n\n Attributes:\n BREAKPOINT: breakpoint data event.\n ' - BREAKPOINT = 1 - - -class JLinkAccessFlags(object): - __doc__ = 'J-Link access types for data events.\n\n These access types allow specifying the different types of access events\n that should be monitored.\n\n Attributes:\n READ: specifies to monitor read accesses.\n WRITE: specifies to monitor write accesses.\n PRIVILEGED: specifies to monitor privileged accesses.\n SIZE_8BIT: specifies to monitor an 8-bit access width.\n SIZE_16BIT: specifies to monitor an 16-bit access width.\n SIZE_32BIT: specifies to monitor an 32-bit access width.\n ' - READ = 0 - WRITE = 1 - PRIV = 16 - SIZE_8BIT = 0 - SIZE_16BIT = 2 - SIZE_32BIT = 4 - - -class JLinkAccessMaskFlags(object): - __doc__ = 'J-Link access mask flags.\n\n Attributes:\n SIZE: specifies to not care about the access size of the event.\n DIR: specifies to not care about the access direction of the event.\n PRIV: specifies to not care about the access privilege of the event.\n ' - SIZE = 6 - DIR = 1 - PRIV = 16 - - -class JLinkStraceCommand(object): - __doc__ = 'STRACE commmands.' - TRACE_EVENT_SET = 0 - TRACE_EVENT_CLR = 1 - TRACE_EVENT_CLR_ALL = 2 - SET_BUFFER_SIZE = 3 - - -class JLinkStraceEvent(object): - __doc__ = 'STRACE events.' - CODE_FETCH = 0 - DATA_ACCESS = 1 - DATA_LOAD = 2 - DATA_STORE = 3 - - -class JLinkStraceOperation(object): - __doc__ = 'STRACE operation specifiers.' - TRACE_START = 0 - TRACE_STOP = 1 - TRACE_INCLUDE_RANGE = 2 - TRACE_EXCLUDE_RANGE = 3 - - -class JLinkTraceSource(object): - __doc__ = 'Sources for tracing.' - ETB = 0 - ETM = 1 - MTB = 2 - - -class JLinkTraceCommand(object): - __doc__ = 'J-Link trace commands.' - START = 0 - STOP = 1 - FLUSH = 2 - GET_NUM_SAMPLES = 16 - GET_CONF_CAPACITY = 17 - SET_CAPACITY = 18 - GET_MIN_CAPACITY = 19 - GET_MAX_CAPACITY = 20 - SET_FORMAT = 32 - GET_FORMAT = 33 - GET_NUM_REGIONS = 48 - GET_REGION_PROPS = 49 - GET_REGION_PROPS_EX = 50 - - -class JLinkTraceFormat(object): - __doc__ = 'J-Link trace formats.\n\n Attributes:\n FORMAT_4BIT: 4-bit data.\n FORMAT_8BIT: 8-bit data.\n FORMAT_16BIT: 16-bit data.\n FORMAT_MULTIPLEXED: multiplexing on ETM / buffer link.\n FORMAT_DEMULTIPLEXED: de-multiplexing on ETM / buffer link.\n FORMAT_DOUBLE_EDGE: clock data on both ETM / buffer link edges.\n FORMAT_ETM7_9: ETM7/ETM9 protocol.\n FORMAT_ETM10: ETM10 protocol.\n FORMAT_1BIT: 1-bit data.\n FORMAT_2BIT: 2-bit data.\n ' - FORMAT_4BIT = 1 - FORMAT_8BIT = 2 - FORMAT_16BIT = 4 - FORMAT_MULTIPLEXED = 8 - FORMAT_DEMULTIPLEXED = 16 - FORMAT_DOUBLE_EDGE = 32 - FORMAT_ETM7_9 = 64 - FORMAT_ETM10 = 128 - FORMAT_1BIT = 256 - FORMAT_2BIT = 512 - - -class JLinkROMTable(object): - __doc__ = 'The J-Link ROM tables.' - NONE = 256 - ETM = 257 - MTB = 258 - TPIU = 259 - ITM = 260 - DWT = 261 - FPB = 262 - NVIC = 263 - TMC = 264 - TF = 265 - PTM = 266 - ETB = 267 - DBG = 268 - APBAP = 269 - AHBAP = 270 - SECURE = 271 - - -class JLinkRTTCommand(object): - __doc__ = 'RTT commands.' - START = 0 - STOP = 1 - GETDESC = 2 - GETNUMBUF = 3 - GETSTAT = 4 - - -class JLinkRTTDirection(object): - __doc__ = 'RTT Direction.' - UP = 0 - DOWN = 1 -# okay decompiling ./pylink/enums.pyc diff --git a/pylink/errors.py b/pylink/errors.py deleted file mode 100644 index 308233a..0000000 --- a/pylink/errors.py +++ /dev/null @@ -1,44 +0,0 @@ -# decompyle3 version 3.9.0 -# Python bytecode version base 3.7.0 (3394) -# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) -# [GCC 12.2.1 20220924] -# Embedded file name: pylink/errors.py -from . import enums -from . import util - -class JLinkException(enums.JLinkGlobalErrors, Exception): - __doc__ = 'Generic J-Link exception.' - - def __init__(self, code): - message = code - self.code = None - if util.is_integer(code): - message = self.to_string(code) - self.code = code - super(JLinkException, self).__init__(message) - self.message = message - - -class JLinkEraseException(enums.JLinkEraseErrors, JLinkException): - __doc__ = 'J-Link erase exception.' - - -class JLinkFlashException(enums.JLinkFlashErrors, JLinkException): - __doc__ = 'J-Link flash exception.' - - -class JLinkWriteException(enums.JLinkWriteErrors, JLinkException): - __doc__ = 'J-Link write exception.' - - -class JLinkReadException(enums.JLinkReadErrors, JLinkException): - __doc__ = 'J-Link read exception.' - - -class JLinkDataException(enums.JLinkDataErrors, JLinkException): - __doc__ = 'J-Link data event exception.' - - -class JLinkRTTException(enums.JLinkRTTErrors, JLinkException): - __doc__ = 'J-Link RTT exception.' -# okay decompiling ./pylink/errors.pyc diff --git a/pylink/jlink.py b/pylink/jlink.py deleted file mode 100644 index a270edc..0000000 --- a/pylink/jlink.py +++ /dev/null @@ -1,4629 +0,0 @@ -# decompyle3 version 3.9.0 -# Python bytecode version base 3.7.0 (3394) -# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) -# [GCC 12.2.1 20220924] -# Embedded file name: pylink/jlink.py -from . import binpacker -from . import decorators -from . import enums -from . import errors -from . import jlock -from . import library -from . import structs -from . import unlockers -from . import util -import ctypes, datetime, functools, itertools, logging, math, operator, sys, time, six -logger = logging.getLogger(__name__) - -class JLink(object): - __doc__ = 'Python interface for the SEGGER J-Link.\n\n This is a wrapper around the J-Link C SDK to provide a Python interface\n to it. The shared library is loaded and used to call the SDK methods.\n ' - MAX_BUF_SIZE = 336 - MAX_NUM_CPU_REGISTERS = 256 - MAX_JTAG_SPEED = 12000 - MIN_JTAG_SPEED = 5 - INVALID_JTAG_SPEED = 65534 - AUTO_JTAG_SPEED = 0 - ADAPTIVE_JTAG_SPEED = 65535 - MAX_NUM_MOES = 8 - - def minimum_required(version): - """Decorator to specify the minimum SDK version required. - - Args: - version (str): valid version string - - Returns: - A decorator function. - """ - - def _minimum_required(func): - - @functools.wraps(func) - def wrapper(self, *args, **kwargs): - if list(self.version) < list(version): - raise errors.JLinkException('Version %s required.' % version) - return func(self, *args, **kwargs) - - return wrapper - - return _minimum_required - - def open_required(func): - """Decorator to specify that the J-Link DLL must be opened, and a - J-Link connection must be established. - - Args: - func (function): function being decorated - - Returns: - The wrapper function. - """ - - @functools.wraps(func) - def wrapper(self, *args, **kwargs): - if not self.opened(): - raise errors.JLinkException('J-Link DLL is not open.') - else: - if not self.connected(): - raise errors.JLinkException('J-Link connection has been lost.') - return func(self, *args, **kwargs) - - return wrapper - - def connection_required(func): - """Decorator to specify that a target connection is required in order - for the given method to be used. - - Args: - func (function): function being decorated - - Returns: - The wrapper function. - """ - - @functools.wraps(func) - def wrapper(self, *args, **kwargs): - if not self.target_connected(): - raise errors.JLinkException('Target is not connected.') - return func(self, *args, **kwargs) - - return wrapper - - def interface_required(interface): - """Decorator to specify that a particular interface type is required - for the given method to be used. - - Args: - interface (int): attribute of ``JLinkInterfaces`` - - Returns: - A decorator function. - """ - - def _interface_required(func): - - @functools.wraps(func) - def wrapper(self, *args, **kwargs): - if self.tif != interface: - raise errors.JLinkException('Unsupported for current interface.') - return func(self, *args, **kwargs) - - return wrapper - - return _interface_required - - def __init__(self, lib=None, log=None, detailed_log=None, error=None, warn=None, unsecure_hook=None, serial_no=None, ip_addr=None, open_tunnel=False): - """Initializes the J-Link interface object. - - Note: - By default, the unsecure dialog will reject unsecuring the device on - connection. If you wish to change this behaviour (to have the device - be unsecured and erased), pass a callback that returns - ``JLinkFlags.DLG_BUTTON_YES`` as its return value. - - Args: - self (JLink): the ``JLink`` instance - lib (Library): a valid ``Library`` instance (not ``None`` dll) - log (function): function to be called to write out log messages, by - default this writes to standard out - detailed_log (function): function to be called to write out detailed - log messages, by default this writes to standard out - error (function): function to be called to write out error messages, - default this writes to standard error - warn (function): function to be called to write out warning messages, - default this his writes to standard error - unsecure_hook (function): function to be called for the unsecure - dialog - serial_no (int): serial number of the J-Link - ip_addr (str): IP address and port of the J-Link - (e.g. 192.168.1.1:80) - open_tunnel (bool, None): If ``False`` (default), the ``open`` - method will be called when entering the context manager using - the ``serial_no`` and ``ip_addr`` provided here. - If ``True`` ``open_tunnel`` method will be called instead - of ``open`` method. - If ``None``, the driver will not be opened automatically - (however, it is still closed when exiting the context manager). - - Returns: - ``None`` - - Raises: - TypeError: if lib's DLL is ``None`` - """ - self._initialized = False - if lib is None: - lib = library.Library() - if lib.dll() is None: - raise TypeError('Expected to be given a valid DLL.') - self._library = lib - self._dll = lib.dll() - self._tif = enums.JLinkInterfaces.JTAG - self._unsecure_hook = unsecure_hook or util.unsecure_hook_dialog - self._log_handler = None - self._warning_handler = None - self._error_handler = None - self._detailed_log_handler = None - self._swo_enabled = False - self._lock = None - self._device = None - self._open_refcount = 0 - self._dll.JLINKARM_OpenEx.restype = ctypes.POINTER(ctypes.c_char) - self._dll.JLINKARM_GetCompileDateTime.restype = ctypes.POINTER(ctypes.c_char) - self._dll.JLINKARM_GetRegisterName.restype = ctypes.POINTER(ctypes.c_char) - self.error_handler = lambda s: error or logger.error(s.decode()) - self.warning_handler = lambda s: warn or logger.warning(s.decode()) - self.log_handler = lambda s: log or logger.info(s.decode()) - self.detailed_log_handler = lambda s: detailed_log or logger.debug(s.decode()) - self._JLink__serial_no = serial_no - self._JLink__ip_addr = ip_addr - self._JLink__open_tunnel = open_tunnel - self._initialized = True - - def __del__(self): - """Destructor for the ``JLink`` instance. Closes the J-Link connection - if one exists. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``None`` - """ - self._finalize() - - def __enter__(self): - """Connects to the J-Link emulator (defaults to USB) using context manager. - - Parameters passed to __init__ are used for open() function. - - Returns: - the ``JLink`` instance - - Raises: - JLinkException: if fails to open (i.e. if device is unplugged) - TypeError: if ``serial_no`` is present, but not ``int`` coercible. - AttributeError: if ``serial_no`` and ``ip_addr`` are both ``None``. - """ - if self._JLink__open_tunnel is False: - self.open(serial_no=(self._JLink__serial_no), ip_addr=(self._JLink__ip_addr)) - else: - if self._JLink__open_tunnel is True: - self.open_tunnel(serial_no=(self._JLink__serial_no)) - return self - - def __exit__(self, exc_type, exc_val, exc_tb): - """Closes the JLink connection on exit of the context manager. - - Stops the SWO if enabled and closes the J-Link connection if one - exists. - - Args: - self (JLink): the ``JLink`` instance - exc_type (BaseExceptionType, None): the exception class, if any - raised inside the context manager - exc_val (BaseException, None): the exception object, if any raised - inside the context manager - exc_tb (TracebackType, None): the exception traceback, if any - exception was raised inside the context manager. - - Returns: - ``True`` if exception raised inside the context manager was handled - and shall be suppressed (not propagated), ``None`` otherwise. - """ - self._finalize() - - def _finalize(self): - """Finalizer ("destructor") for the ``JLink`` instance. - - Stops the SWO if enabled and closes the J-Link connection if one - exists. - Called when exiting the context manager or when this object is - destructed (garbage collected). - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``None`` - """ - if self._initialized: - if self.connected(): - if self.swo_enabled(): - self.swo_stop() - if self.opened(): - self.close() - - def _get_register_index_from_name(self, register): - """ - Converts a register name to a register index - - Args: - self (JLink): the ``JLink`` instance - register (str): the register name - - Returns: - ``int`` - """ - regs = list((self.register_name(idx) for idx in self.register_list())) - if isinstance(register, six.string_types): - try: - result = regs.index(register) - except ValueError: - error_message = 'No register found matching name: {}. (available registers: {})' - raise errors.JLinkException(error_message.format(register, ', '.join(regs))) - - return result - - def opened(self): - """Returns whether the DLL is open. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``True`` if the J-Link is open, otherwise ``False``. - """ - return bool(self._dll.JLINKARM_IsOpen()) - - def connected(self): - """Returns whether a J-Link is connected. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``True`` if the J-Link is open and connected, otherwise ``False``. - """ - return self.opened() and bool(self._dll.JLINKARM_EMU_IsConnected()) - - def target_connected(self): - """Returns whether a target is connected to the J-Link. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``True`` if a target is connected, otherwise ``False``. - """ - return self.connected() and bool(self._dll.JLINKARM_IsConnected()) - - @property - def log_handler(self): - """Returns the log handler function. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``None`` if the log handler was not set, otherwise a - ``ctypes.CFUNCTYPE``. - """ - return self._log_handler - - @log_handler.setter - def log_handler(self, handler): - """Setter for the log handler function. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``None`` - """ - if not self.opened(): - handler = handler or util.noop - self._log_handler = enums.JLinkFunctions.LOG_PROTOTYPE(handler) - self._dll.JLINKARM_EnableLog(self._log_handler) - - @property - def detailed_log_handler(self): - """Returns the detailed log handler function. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``None`` if the detailed log handler was not set, otherwise a - ``ctypes.CFUNCTYPE``. - """ - return self._detailed_log_handler - - @detailed_log_handler.setter - def detailed_log_handler(self, handler): - """Setter for the detailed log handler function. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``None`` - """ - if not self.opened(): - handler = handler or util.noop - self._detailed_log_handler = enums.JLinkFunctions.LOG_PROTOTYPE(handler) - self._dll.JLINKARM_EnableLogCom(self._detailed_log_handler) - - @property - def error_handler(self): - """Returns the error handler function. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``None`` if the error handler was not set, otherwise a - ``ctypes.CFUNCTYPE``. - """ - return self._error_handler - - @error_handler.setter - def error_handler(self, handler): - """Setter for the error handler function. - - If the DLL is open, this function is a no-op, so it should be called - prior to calling ``open()``. - - Args: - self (JLink): the ``JLink`` instance - handler (function): function to call on error messages - - Returns: - ``None`` - """ - if not self.opened(): - handler = handler or util.noop - self._error_handler = enums.JLinkFunctions.LOG_PROTOTYPE(handler) - self._dll.JLINKARM_SetErrorOutHandler(self._error_handler) - - @property - def warning_handler(self): - """Returns the warning handler function. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``None`` if the warning handler was not set, otherwise a - ``ctypes.CFUNCTYPE``. - """ - return self._warning_handler - - @warning_handler.setter - def warning_handler(self, handler): - """Setter for the warning handler function. - - If the DLL is open, this function is a no-op, so it should be called - prior to calling ``open()``. - - Args: - self (JLink): the ``JLink`` instance - handler (function): function to call on warning messages - - Returns: - ``None`` - """ - if not self.opened(): - handler = handler or util.noop - self._warning_handler = enums.JLinkFunctions.LOG_PROTOTYPE(handler) - self._dll.JLINKARM_SetWarnOutHandler(self._warning_handler) - - def num_connected_emulators(self): - """Returns the number of emulators which are connected via USB to the - host. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - The number of connected emulators. - """ - return self._dll.JLINKARM_EMU_GetNumDevices() - - def connected_emulators(self, host=enums.JLinkHost.USB): - """Returns a list of all the connected emulators. - - Args: - self (JLink): the ``JLink`` instance - host (int): host type to search (default: ``JLinkHost.USB``) - - Returns: - List of ``JLinkConnectInfo`` specifying the connected emulators. - - Raises: - JLinkException: if fails to enumerate devices. - """ - res = self._dll.JLINKARM_EMU_GetList(host, 0, 0) - if res < 0: - raise errors.JLinkException(res) - num_devices = res - info = (structs.JLinkConnectInfo * num_devices)() - num_found = self._dll.JLINKARM_EMU_GetList(host, info, num_devices) - if num_found < 0: - raise errors.JLinkException(num_found) - return list(info)[:num_found] - - def num_supported_devices(self): - """Returns the number of devices that are supported by the opened - J-Link DLL. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - Number of devices the J-Link DLL supports. - """ - return int(self._dll.JLINKARM_DEVICE_GetInfo(-1, 0)) - - def supported_device(self, index=0): - """Gets the device at the given ``index``. - - Args: - self (JLink): the ``JLink`` instance - index (int): the index of the device whose information to get - - Returns: - A ``JLinkDeviceInfo`` describing the requested device. - - Raises: - ValueError: if index is less than 0 or >= supported device count. - """ - if not util.is_natural(index) or index >= self.num_supported_devices(): - raise ValueError('Invalid index.') - info = structs.JLinkDeviceInfo() - result = self._dll.JLINKARM_DEVICE_GetInfo(index, ctypes.byref(info)) - return info - - def open(self, serial_no=None, ip_addr=None): - """Connects to the J-Link emulator (defaults to USB). - - If ``serial_no`` and ``ip_addr`` are both given, this function will - connect to the J-Link over TCP/IP. - - Args: - self (JLink): the ``JLink`` instance - serial_no (int): serial number of the J-Link - ip_addr (str): IP address and port of the J-Link (e.g. 192.168.1.1:80) - - Returns: - ``None`` - - Raises: - JLinkException: if fails to open (i.e. if device is unplugged) - TypeError: if ``serial_no`` is present, but not ``int`` coercible. - AttributeError: if ``serial_no`` and ``ip_addr`` are both ``None``. - """ - if self._open_refcount > 0: - self._open_refcount += 1 - return - self.close() - if ip_addr is not None: - addr, port = ip_addr.rsplit(':', 1) - if serial_no is None: - result = self._dll.JLINKARM_SelectIP(addr.encode(), int(port)) - if result == 1: - raise errors.JLinkException('Could not connect to emulator at %s.' % ip_addr) - else: - self._dll.JLINKARM_EMU_SelectIPBySN(int(serial_no)) - else: - if serial_no is not None: - result = self._dll.JLINKARM_EMU_SelectByUSBSN(int(serial_no)) - if result < 0: - raise errors.JLinkException('No emulator with serial number %s found.' % serial_no) - else: - result = self._dll.JLINKARM_SelectUSB(0) - if result != 0: - raise errors.JlinkException('Could not connect to default emulator.') - if serial_no is not None: - self._lock = jlock.JLock(serial_no) - if not self._lock.acquire(): - raise errors.JLinkException('J-Link is already open.') - result = self._dll.JLINKARM_OpenEx(self.log_handler, self.error_handler) - result = ctypes.cast(result, ctypes.c_char_p).value - if result is not None: - raise errors.JLinkException(result.decode()) - unsecure_hook = self._unsecure_hook - if unsecure_hook is not None: - if hasattr(self._dll, 'JLINK_SetHookUnsecureDialog'): - func = enums.JLinkFunctions.UNSECURE_HOOK_PROTOTYPE(unsecure_hook) - self._dll.JLINK_SetHookUnsecureDialog(func) - self._open_refcount = 1 - - def open_tunnel(self, serial_no, port=19020): - """Connects to the J-Link emulator (over SEGGER tunnel). - - Args: - self (JLink): the ``JLink`` instance - serial_no (int): serial number of the J-Link - port (int): optional port number (default to 19020). - - Returns: - ``None`` - """ - return self.open(ip_addr=('tunnel:' + str(serial_no) + ':' + str(port))) - - def close(self): - """Closes the open J-Link. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``None`` - - Raises: - JLinkException: if there is no connected JLink. - """ - if self._open_refcount == 0: - return - self._open_refcount -= 1 - if self._open_refcount > 0: - return - self._dll.JLINKARM_Close() - if self._lock is not None: - del self._lock - self._lock = None - - def test(self): - """Performs a self test. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``True`` if test passed, otherwise ``False``. - """ - res = self._dll.JLINKARM_Test() - return res == 0 - - @open_required - def invalidate_firmware(self): - """Invalidates the emulator's firmware. - - This method is useful for downgrading the firmware on an emulator. By - calling this method, the current emulator's firmware is invalidated, - which will make the emulator download the firmware of the J-Link SDK - DLL that this instance was created with. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``None`` - - Raises: - JLinkException: on hardware error. - """ - self.exec_command('InvalidateFW') - - @open_required - def update_firmware(self): - """Performs a firmware update. - - If there is a newer version of firmware available for the J-Link - device, then updates the firmware. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - Checksum of the new firmware on update, ``0`` if the firmware was not - changed. - """ - return self._dll.JLINKARM_UpdateFirmwareIfNewer() - - @open_required - def sync_firmware(self): - """Syncs the emulator's firmware version and the DLL's firmware. - - This method is useful for ensuring that the firmware running on the - J-Link matches the firmware supported by the DLL. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``None`` - """ - serial_no = self.serial_number - if self.firmware_newer(): - try: - self.invalidate_firmware() - self.update_firmware() - except errors.JLinkException as e: - try: - pass - finally: - e = None - del e - - res = self.open(serial_no=serial_no) - if self.firmware_newer(): - raise errors.JLinkException('Failed to sync firmware version.') - return res - if self.firmware_outdated(): - try: - self.update_firmware() - except errors.JLinkException as e: - try: - pass - finally: - e = None - del e - - if self.firmware_outdated(): - raise errors.JLinkException('Failed to sync firmware version.') - return self.open(serial_no=serial_no) - - def exec_command(self, cmd): - """Executes the given command. - - This method executes a command by calling the DLL's exec method. - Direct API methods should be prioritized over calling this method. - - Args: - self (JLink): the ``JLink`` instance - cmd (str): the command to run - - Returns: - The return code of running the command. - - Raises: - JLinkException: if the command is invalid or fails. - - See Also: - For a full list of the supported commands, please see the SEGGER - J-Link documentation, - `UM08001 `__. - """ - err_buf = (ctypes.c_char * self.MAX_BUF_SIZE)() - res = self._dll.JLINKARM_ExecCommand(cmd.encode(), err_buf, self.MAX_BUF_SIZE) - err_buf = ctypes.string_at(err_buf).decode() - if len(err_buf) > 0: - raise errors.JLinkException(err_buf.strip()) - return res - - @minimum_required('5.02') - def enable_dialog_boxes(self): - """Enables showing dialog boxes on certain methods. - - Note: - Dialog boxes only appear on Windows platforms. - - Note: - This can be used for batch or automized test running. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``None`` - """ - self.exec_command('SetBatchMode = 0') - - @minimum_required('5.02') - def disable_dialog_boxes(self): - """Disables showing dialog boxes on certain methods. - - Note: - Dialog boxes only appear on Windows platforms. - - Warning: - This has the effect of also silencing dialog boxes that appear when - updating firmware / to confirm updating firmware. - - Dialog boxes will be shown for a brief period of time (approximately - five seconds), before being automatically hidden, and the default - option chosen. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``None`` - """ - self.exec_command('SilentUpdateFW') - self.exec_command('SuppressInfoUpdateFW') - self.exec_command('SetBatchMode = 1') - - @open_required - def jtag_configure(self, instr_regs=0, data_bits=0): - """Configures the JTAG scan chain to determine which CPU to address. - - Must be called if the J-Link is connected to a JTAG scan chain with - multiple devices. - - Args: - self (JLink): the ``JLink`` instance - instr_regs (int): length of instruction registers of all devices - closer to TD1 then the addressed CPU - data_bits (int): total number of data bits closer to TD1 than the - addressed CPU - - Returns: - ``None`` - - Raises: - ValueError: if ``instr_regs`` or ``data_bits`` are not natural numbers - """ - if not util.is_natural(instr_regs): - raise ValueError('IR value is not a natural number.') - if not util.is_natural(data_bits): - raise ValueError('Data bits is not a natural number.') - self._dll.JLINKARM_ConfigJTAG(instr_regs, data_bits) - - @open_required - @minimum_required('4.98e') - def coresight_configure(self, ir_pre=0, dr_pre=0, ir_post=0, dr_post=0, ir_len=0, perform_tif_init=True): - """Prepares target and J-Link for CoreSight function usage. - - Args: - self (JLink): the ``JLink`` instance - ir_pre (int): sum of instruction register length of all JTAG devices - in the JTAG chain, close to TDO than the actual one, that J-Link - shall communicate with - dr_pre (int): number of JTAG devices in the JTAG chain, closer to TDO - than the actual one, that J-Link shall communicate with - ir_post (int): sum of instruction register length of all JTAG devices - in the JTAG chain, following the actual one, that J-Link shall - communicate with - dr_post (int): Number of JTAG devices in the JTAG chain, following - the actual one, J-Link shall communicate with - ir_len (int): instruction register length of the actual device that - J-Link shall communicate with - perform_tif_init (bool): if ``False``, then do not output switching - sequence on completion - - Returns: - ``None`` - - Note: - This must be called before calling ``coresight_read()`` or - ``coresight_write()``. - """ - if self.tif == enums.JLinkInterfaces.SWD: - res = self._dll.JLINKARM_CORESIGHT_Configure('') - if res < 0: - raise errors.JLinkException(res) - return - config_string = 'IRPre=%s;DRPre=%s;IRPost=%s;DRPost=%s;IRLenDevice=%s;' - config_string = config_string % (ir_pre, dr_pre, ir_post, dr_post, ir_len) - if not perform_tif_init: - config_string = config_string + 'PerformTIFInit=0;' - res = self._dll.JLINKARM_CORESIGHT_Configure(config_string.encode()) - if res < 0: - raise errors.JLinkException(res) - - @open_required - def connect(self, chip_name, speed='auto', verbose=False): - """Connects the J-Link to its target. - - Args: - self (JLink): the ``JLink`` instance - chip_name (str): target chip name - speed (int): connection speed, one of ``{5-12000, 'auto', 'adaptive'}`` - verbose (bool): boolean indicating if connection should be verbose in logging - - Returns: - ``None`` - - Raises: - JLinkException: if connection fails to establish. - TypeError: if given speed is invalid - """ - if verbose: - self.exec_command('EnableRemarks = 1') - self.exec_command('Device = %s' % chip_name) - if speed == 'auto': - self.set_speed(auto=True) - else: - if speed == 'adaptive': - self.set_speed(adaptive=True) - else: - self.set_speed(speed) - result = self._dll.JLINKARM_Connect() - if result < 0: - raise errors.JLinkException(result) - try: - self.halted() - except errors.JLinkException: - pass - - for index in range(self.num_supported_devices()): - device = self.supported_device(index) - if device.name.lower() == chip_name.lower(): - self._device = device - break - else: - raise errors.JLinkException('Unsupported device was connected to.') - - @property - def error(self): - """DLL internal error state. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - The DLL internal error state. This is set if any error occurs in - underlying DLL, otherwise it is ``None``. - """ - error = int(self._dll.JLINKARM_HasError()) - if error == 0: - return - return error - - def clear_error(self): - """Clears the DLL internal error state. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - The error state before the clear. - """ - error = self.error - self._dll.JLINKARM_ClrError() - return error - - @property - def compile_date(self): - """Returns a string specifying the date and time at which the DLL was - translated. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - Datetime string. - """ - result = self._dll.JLINKARM_GetCompileDateTime() - return ctypes.cast(result, ctypes.c_char_p).value.decode() - - @property - def version(self): - """Returns the device's version. - - The device's version is returned as a string of the format: M.mr where - ``M`` is major number, ``m`` is minor number, and ``r`` is revision - character. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - Device version string. - """ - version = int(self._dll.JLINKARM_GetDLLVersion()) - major = version / 10000 - minor = version / 100 % 100 - rev = version % 100 - rev = '' if rev == 0 else chr(rev + ord('a') - 1) - return '%d.%02d%s' % (major, minor, rev) - - @property - @open_required - def compatible_firmware_version(self): - """Returns the DLL's compatible J-Link firmware version. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - The firmware version of the J-Link that the DLL is compatible - with. - - Raises: - JLinkException: on error. - """ - identifier = self.firmware_version.split('compiled')[0] - buf_size = self.MAX_BUF_SIZE - buf = (ctypes.c_char * buf_size)() - res = self._dll.JLINKARM_GetEmbeddedFWString(identifier.encode(), buf, buf_size) - if res < 0: - raise errors.JLinkException(res) - return ctypes.string_at(buf).decode() - - @open_required - def firmware_outdated(self): - """Returns whether the J-Link's firmware version is older than the one - that the DLL is compatible with. - - Note: - This is not the same as calling ``not jlink.firmware_newer()``. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``True`` if the J-Link's firmware is older than the one supported by - the DLL, otherwise ``False``. - """ - datefmt = ' %b %d %Y %H:%M:%S' - compat_date = self.compatible_firmware_version.split('compiled')[1] - compat_date = datetime.datetime.strptime(compat_date, datefmt) - fw_date = self.firmware_version.split('compiled')[1] - fw_date = datetime.datetime.strptime(fw_date, datefmt) - return compat_date > fw_date - - @open_required - def firmware_newer(self): - """Returns whether the J-Link's firmware version is newer than the one - that the DLL is compatible with. - - Note: - This is not the same as calling ``not jlink.firmware_outdated()``. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``True`` if the J-Link's firmware is newer than the one supported by - the DLL, otherwise ``False``. - """ - if self.firmware_outdated(): - return False - return self.firmware_version != self.compatible_firmware_version - - @property - @open_required - def hardware_info(self, mask=4294967295): - """Returns a list of 32 integer values corresponding to the bitfields - specifying the power consumption of the target. - - The values returned by this function only have significance if the - J-Link is powering the target. - - The words, indexed, have the following significance: - 0. If ``1``, target is powered via J-Link. - 1. Overcurrent bitfield: - 0: No overcurrent. - 1: Overcurrent happened. 2ms @ 3000mA - 2: Overcurrent happened. 10ms @ 1000mA - 3: Overcurrent happened. 40ms @ 400mA - 2. Power consumption of target (mA). - 3. Peak of target power consumption (mA). - 4. Peak of target power consumption during J-Link operation (mA). - - Args: - self (JLink): the ``JLink`` instance - mask (int): bit mask to decide which hardware information words are - returned (defaults to all the words). - - Returns: - List of bitfields specifying different states based on their index - within the list and their value. - - Raises: - JLinkException: on hardware error. - """ - buf = (ctypes.c_uint32 * 32)() - res = self._dll.JLINKARM_GetHWInfo(mask, ctypes.byref(buf)) - if res != 0: - raise errors.JLinkException(res) - return list(buf) - - @property - @open_required - def hardware_status(self): - """Retrieves and returns the hardware status. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - A ``JLinkHardwareStatus`` describing the J-Link hardware. - """ - stat = structs.JLinkHardwareStatus() - res = self._dll.JLINKARM_GetHWStatus(ctypes.byref(stat)) - if res == 1: - raise errors.JLinkException('Error in reading hardware status.') - return stat - - @property - @open_required - def hardware_version(self): - """Returns the hardware version of the connected J-Link as a - major.minor string. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - Hardware version string. - """ - version = self._dll.JLINKARM_GetHardwareVersion() - major = version / 10000 % 100 - minor = version / 100 % 100 - return '%d.%02d' % (major, minor) - - @property - @open_required - def firmware_version(self): - """Returns a firmware identification string of the connected J-Link. - - It consists of the following: - - Product Name (e.g. J-Link) - - The string: compiled - - Compile data and time. - - Optional additional information. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - Firmware identification string. - """ - buf = (ctypes.c_char * self.MAX_BUF_SIZE)() - self._dll.JLINKARM_GetFirmwareString(buf, self.MAX_BUF_SIZE) - return ctypes.string_at(buf).decode() - - @property - @open_required - def capabilities(self): - """Returns a bitwise combination of the emulator's capabilities. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - Bitfield of emulator capabilities. - """ - return self._dll.JLINKARM_GetEmuCaps() - - @property - @open_required - def extended_capabilities(self): - """Gets the capabilities of the connected emulator as a list. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - List of 32 integers which define the extended capabilities based on - their value and index within the list. - """ - buf = (ctypes.c_uint8 * 32)() - self._dll.JLINKARM_GetEmuCapsEx(buf, 32) - return list(buf) - - @open_required - def extended_capability(self, capability): - """Checks if the emulator has the given extended capability. - - Args: - self (JLink): the ``JLink`` instance - capability (int): capability being queried - - Returns: - ``True`` if the emulator has the given extended capability, otherwise - ``False``. - """ - res = self._dll.JLINKARM_EMU_HasCapEx(capability) - return res == 1 - - @property - @open_required - def features(self): - """Returns a list of the J-Link embedded features. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - A list of strings, each a feature. Example: - ``[ 'RDI', 'FlashBP', 'FlashDL', 'JFlash', 'GDB' ]`` - """ - buf = (ctypes.c_char * self.MAX_BUF_SIZE)() - self._dll.JLINKARM_GetFeatureString(buf) - result = ctypes.string_at(buf).decode().strip() - if len(result) == 0: - return list() - return result.split(', ') - - @property - @open_required - def product_name(self): - """Returns the product name of the connected J-Link. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - Product name. - """ - buf = (ctypes.c_char * self.MAX_BUF_SIZE)() - self._dll.JLINKARM_EMU_GetProductName(buf, self.MAX_BUF_SIZE) - return ctypes.string_at(buf).decode() - - @property - @open_required - def serial_number(self): - """Returns the serial number of the connected J-Link. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - Serial number as an integer. - """ - return self._dll.JLINKARM_GetSN() - - @property - @open_required - def oem(self): - """Retrieves and returns the OEM string of the connected J-Link. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - The string of the OEM. If this is an original SEGGER product, then - ``None`` is returned instead. - - Raises: - JLinkException: on hardware error. - """ - buf = (ctypes.c_char * self.MAX_BUF_SIZE)() - res = self._dll.JLINKARM_GetOEMString(ctypes.byref(buf)) - if res != 0: - raise errors.JLinkException('Failed to grab OEM string.') - oem = ctypes.string_at(buf).decode() - if len(oem) == 0: - return - return oem - - @property - @open_required - def index(self): - """Retrieves and returns the index number of the actual selected - J-Link. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - Index of the currently connected J-Link. - """ - return self._dll.JLINKARM_GetSelDevice() - - @property - @open_required - def speed(self): - """Returns the current JTAG connection speed. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - JTAG connection speed. - """ - return self._dll.JLINKARM_GetSpeed() - - @open_required - def set_speed(self, speed=None, auto=False, adaptive=False): - """Sets the speed of the JTAG communication with the ARM core. - - If no arguments are present, automatically detects speed. - - If a ``speed`` is provided, the speed must be no larger than - ``JLink.MAX_JTAG_SPEED`` and no smaller than ``JLink.MIN_JTAG_SPEED``. - The given ``speed`` can also not be ``JLink.INVALID_JTAG_SPEED``. - - Args: - self (JLink): the ``JLink`` instance - speed (int): the speed in kHz to set the communication at - auto (bool): automatically detect correct speed - adaptive (bool): select adaptive clocking as JTAG speed - - Returns: - ``None`` - - Raises: - TypeError: if given speed is not a natural number. - ValueError: if given speed is too high, too low, or invalid. - """ - if speed is None: - speed = 0 - else: - if not util.is_natural(speed): - raise TypeError('Expected positive number for speed, given %s.' % speed) - else: - if speed > self.MAX_JTAG_SPEED: - raise ValueError('Given speed exceeds max speed of %d.' % self.MAX_JTAG_SPEED) - else: - if speed < self.MIN_JTAG_SPEED: - raise ValueError('Given speed is too slow. Minimum is %d.' % self.MIN_JTAG_SPEED) - if auto: - speed = speed | self.AUTO_JTAG_SPEED - if adaptive: - speed = speed | self.ADAPTIVE_JTAG_SPEED - self._dll.JLINKARM_SetSpeed(speed) - - @open_required - def set_max_speed(self): - """Sets JTAG communication speed to the maximum supported speed. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``None`` - """ - self._dll.JLINKARM_SetMaxSpeed() - - @property - @open_required - def speed_info(self): - """Retrieves information about supported target interface speeds. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - The ``JLinkSpeedInfo`` instance describing the supported target - interface speeds. - """ - speed_info = structs.JLinkSpeedInfo() - self._dll.JLINKARM_GetSpeedInfo(ctypes.byref(speed_info)) - return speed_info - - @property - @open_required - def licenses(self): - """Returns a string of the built-in licenses the J-Link has. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - String of the contents of the built-in licenses the J-Link has. - """ - buf_size = self.MAX_BUF_SIZE - buf = (ctypes.c_char * buf_size)() - res = self._dll.JLINK_GetAvailableLicense(buf, buf_size) - if res < 0: - raise errors.JLinkException(res) - return ctypes.string_at(buf).decode() - - @property - @open_required - @minimum_required('4.98b') - def custom_licenses(self): - """Returns a string of the installed licenses the J-Link has. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - String of the contents of the custom licenses the J-Link has. - """ - buf = (ctypes.c_char * self.MAX_BUF_SIZE)() - result = self._dll.JLINK_EMU_GetLicenses(buf, self.MAX_BUF_SIZE) - if result < 0: - raise errors.JLinkException(result) - return ctypes.string_at(buf).decode() - - @open_required - @minimum_required('4.98b') - def add_license(self, contents): - """Adds the given ``contents`` as a new custom license to the J-Link. - - Args: - self (JLink): the ``JLink`` instance - contents: the string contents of the new custom license - - Returns: - ``True`` if license was added, ``False`` if license already existed. - - Raises: - JLinkException: if the write fails. - - Note: - J-Link V9 and J-Link ULTRA/PRO V4 have 336 Bytes of memory for - licenses, while older versions of 80 bytes. - """ - buf_size = len(contents) - buf = (ctypes.c_char * (buf_size + 1))(*contents.encode()) - res = self._dll.JLINK_EMU_AddLicense(buf) - if res == -1: - raise errors.JLinkException('Unspecified error.') - else: - if res == -2: - raise errors.JLinkException('Failed to read/write license area.') - else: - if res == -3: - raise errors.JLinkException('J-Link out of space.') - return res == 0 - - @open_required - @minimum_required('4.98b') - def erase_licenses(self): - """Erases the custom licenses from the connected J-Link. - - Note: - This method will erase all licenses stored on the J-Link. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``True`` on success, otherwise ``False``. - """ - res = self._dll.JLINK_EMU_EraseLicenses() - return res == 0 - - @property - @open_required - def tif(self): - """Returns the current target interface of the J-Link. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - Integer specifying the current target interface. - """ - return self._tif - - @open_required - def supported_tifs(self): - """Returns a bitmask of the supported target interfaces. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - Bitfield specifying which target interfaces are supported. - """ - buf = ctypes.c_uint32() - self._dll.JLINKARM_TIF_GetAvailable(ctypes.byref(buf)) - return buf.value - - @open_required - def set_tif(self, interface): - """Selects the specified target interface. - - Note that a restart must be triggered for this to take effect. - - Args: - self (Jlink): the ``JLink`` instance - interface (int): integer identifier of the interface - - Returns: - ``True`` if target was updated, otherwise ``False``. - - Raises: - JLinkException: if the given interface is invalid or unsupported. - """ - if not 1 << interface & self.supported_tifs(): - raise errors.JLinkException('Unsupported target interface: %s' % interface) - res = self._dll.JLINKARM_TIF_Select(interface) - if res != 0: - return False - self._tif = interface - return True - - @open_required - def gpio_properties(self): - """Returns the properties of the user-controllable GPIOs. - - Provided the device supports user-controllable GPIOs, they will be - returned by this method. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - A list of ``JLinkGPIODescriptor`` instances totalling the number of - requested properties. - - Raises: - JLinkException: on error. - """ - res = self._dll.JLINK_EMU_GPIO_GetProps(0, 0) - if res < 0: - raise errors.JLinkException(res) - num_props = res - buf = (structs.JLinkGPIODescriptor * num_props)() - res = self._dll.JLINK_EMU_GPIO_GetProps(ctypes.byref(buf), num_props) - if res < 0: - raise errors.JLinkException(res) - return list(buf) - - @open_required - def gpio_get(self, pins=None): - """Returns a list of states for the given pins. - - Defaults to the first four pins if an argument is not given. - - Args: - self (JLink): the ``JLink`` instance - pins (list): indices of the GPIO pins whose states are requested - - Returns: - A list of states. - - Raises: - JLinkException: on error. - """ - if pins is None: - pins = range(4) - size = len(pins) - indices = (ctypes.c_uint8 * size)(*pins) - statuses = (ctypes.c_uint8 * size)() - result = self._dll.JLINK_EMU_GPIO_GetState(ctypes.byref(indices), ctypes.byref(statuses), size) - if result < 0: - raise errors.JLinkException(result) - return list(statuses) - - @open_required - def gpio_set(self, pins, states): - """Sets the state for one or more user-controllable GPIOs. - - For each of the given pins, sets the the corresponding state based on - the index. - - Args: - self (JLink): the ``JLink`` instance - pins (list): list of GPIO indices - states (list): list of states to set - - Returns: - A list of updated states. - - Raises: - JLinkException: on error. - ValueError: if ``len(pins) != len(states)`` - """ - if len(pins) != len(states): - raise ValueError('Length mismatch between pins and states.') - size = len(pins) - indices = (ctypes.c_uint8 * size)(*pins) - states = (ctypes.c_uint8 * size)(*states) - result_states = (ctypes.c_uint8 * size)() - result = self._dll.JLINK_EMU_GPIO_SetState(ctypes.byref(indices), ctypes.byref(states), ctypes.byref(result_states), size) - if result < 0: - raise errors.JLinkException(result) - return list(result_states) - - @open_required - def comm_supported(self): - """Returns true if the connected emulator supports ``comm_*`` - functions. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``True`` if the emulator supports ``comm_*`` functions, otherwise - ``False``. - """ - return bool(self._dll.JLINKARM_EMU_COM_IsSupported()) - - @open_required - def power_on(self, default=False): - """Turns on the power supply over pin 19 of the JTAG connector. - - If given the optional ``default`` parameter, activates the power supply - by default. - - Args: - self (JLink): the ``JLink`` instance - default (bool): boolean indicating if to set power by default - - Returns: - ``None`` - - Raises: - JLinkException: if J-Link does not support powering the target. - """ - if default: - return self.exec_command('SupplyPowerDefault = 1') - return self.exec_command('SupplyPower = 1') - - @open_required - def power_off(self, default=False): - """Turns off the power supply over pin 19 of the JTAG connector. - - If given the optional ``default`` parameter, deactivates the power supply - by default. - - Args: - self (JLink): the ``JLink`` instance - default (bool): boolean indicating if to set power off by default - - Returns: - The current ``JLink`` instance - - Raises: - JLinkException: if J-Link does not support powering the target. - """ - if default: - return self.exec_command('SupplyPowerDefault = 0') - return self.exec_command('SupplyPower = 0') - - @connection_required - def unlock(self): - """Unlocks the device connected to the J-Link. - - Unlocking a device allows for access to read/writing memory, as well as - flash programming. - - Note: - Unlock is not supported on all devices. - - Supported Devices: - Kinetis - - Returns: - ``True``. - - Raises: - JLinkException: if the device fails to unlock. - """ - if not unlockers.unlock(self, self._device.manufacturer): - raise errors.JLinkException('Failed to unlock device.') - return True - - @connection_required - def cpu_capability(self, capability): - """Checks whether the J-Link has support for a CPU capability. - - This method checks if the emulator has built-in intelligence to handle - the given CPU capability for the target CPU it is connected to. - - Args: - self (JLink): the ``JLink`` instance - capability (int): the capability to check for - - Returns: - ``True`` if the J-Link has built-in intelligence to support the given - ``capability`` for the CPU it is connected to, otherwise ``False``. - """ - res = self._dll.JLINKARM_EMU_HasCPUCap(capability) - return res == 1 - - @connection_required - def set_trace_source(self, source): - """Sets the source to be used for tracing. - - The ``source`` must be one of the ones provided by - ``enums.JLinkTraceSource``. - - Args: - self (JLink): the ``JLink`` instance. - source (int): the source to use. - - Returns: - ``None`` - """ - self._dll.JLINKARM_SelectTraceSource(source) - - @connection_required - def set_etb_trace(self): - """Sets the trace source to ETB. - - Args: - self (JLink): the ``JLink`` instance. - - Returns: - ``None`` - """ - return self.set_trace_source(enums.JLinkTraceSource.ETB) - - @connection_required - def set_etm_trace(self): - """Sets the trace source to ETM. - - Args: - self (JLink): the ``JLink`` instance. - - Returns: - ``None`` - """ - return self.set_trace_source(enums.JLinkTraceSource.ETM) - - @connection_required - def set_reset_strategy(self, strategy): - """Sets the reset strategy for the target. - - The reset strategy defines what happens when the target is reset. - - Args: - self (JLink): the ``JLink`` instance - strategy (int): the reset strategy to use - - Returns: - The previous reset streategy. - """ - return self._dll.JLINKARM_SetResetType(strategy) - - @connection_required - def set_reset_pin_high(self): - """Sets the reset pin high. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``None`` - """ - self._dll.JLINKARM_SetRESET() - - @connection_required - def set_reset_pin_low(self): - """Sets the reset pin low. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``None`` - """ - self._dll.JLINKARM_ClrRESET() - - @connection_required - def set_tck_pin_high(self): - """Sets the TCK pin to the high value (1). - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``None`` - - Raises: - JLinkException: if the emulator does not support this feature. - """ - res = self._dll.JLINKARM_SetTCK() - if res < 0: - raise errors.JLinkException('Feature not supported.') - - @connection_required - def set_tck_pin_low(self): - """Sets the TCK pin to the low value (0). - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``None`` - - Raises: - JLinkException: if the emulator does not support this feature. - """ - res = self._dll.JLINKARM_ClrTCK() - if res < 0: - raise errors.JLinkException('Feature not supported.') - - @connection_required - def set_tdi_pin_high(self): - """Sets the test data input to logical ``1``. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``None`` - """ - self._dll.JLINKARM_SetTDI() - - @connection_required - def set_tdi_pin_low(self): - """Clears the test data input. - - TDI is set to logical ``0`` (Ground). - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``None`` - """ - self._dll.JLINKARM_ClrTDI() - - @connection_required - def set_tms_pin_high(self): - """Sets the test mode select to logical ``1``. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``None`` - """ - self._dll.JLINKARM_SetTMS() - - @connection_required - def set_tms_pin_low(self): - """Clears the test mode select. - - TMS is set to logical ``0`` (Ground). - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``None`` - """ - self._dll.JLINKARM_ClrTMS() - - @connection_required - def set_trst_pin_high(self): - """Sets the TRST pin to high (``1``). - - Deasserts the TRST pin. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``None`` - """ - self._dll.JLINKARM_SetTRST() - - @connection_required - def set_trst_pin_low(self): - """Sets the TRST pin to low (``0``). - - This asserts the TRST pin. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``None`` - """ - self._dll.JLINKARM_ClrTRST() - - @connection_required - def erase(self): - """Erases the flash contents of the device. - - This erases the flash memory of the target device. If this method - fails, the device may be left in an inoperable state. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - Number of bytes erased. - """ - try: - if not self.halted(): - self.halt() - except errors.JLinkException: - pass - - res = self._dll.JLINK_EraseChip() - if res < 0: - raise errors.JLinkEraseException(res) - return res - - @connection_required - def flash(self, data, addr, on_progress=None, power_on=False, flags=0): - """Flashes the target device. - - The given ``on_progress`` callback will be called as - ``on_progress(action, progress_string, percentage)`` periodically as the - data is written to flash. The action is one of ``Compare``, ``Erase``, - ``Verify``, ``Flash``. - - Args: - self (JLink): the ``JLink`` instance - data (list): list of bytes to write to flash - addr (int): start address on flash which to write the data - on_progress (function): callback to be triggered on flash progress - power_on (boolean): whether to power the target before flashing - flags (int): reserved, do not use - - Returns: - Number of bytes flashed. This number may not necessarily be equal to - ``len(data)``, but that does not indicate an error. - - Raises: - JLinkException: on hardware errors. - """ - if flags != 0: - raise errors.JLinkException('Flags are reserved for future use.') - if on_progress is not None: - func = enums.JLinkFunctions.FLASH_PROGRESS_PROTOTYPE(on_progress) - self._dll.JLINK_SetFlashProgProgressCallback(func) - else: - self._dll.JLINK_SetFlashProgProgressCallback(0) - if power_on: - self.power_on() - try: - if not self.halted(): - self.halt() - except errors.JLinkException: - pass - - res = self.flash_write(addr, data, flags=flags) - return res - - @connection_required - def flash_file(self, path, addr, on_progress=None, power_on=False): - """Flashes the target device. - - The given ``on_progress`` callback will be called as - ``on_progress(action, progress_string, percentage)`` periodically as the - data is written to flash. The action is one of ``Compare``, ``Erase``, - ``Verify``, ``Flash``. - - Args: - self (JLink): the ``JLink`` instance - path (str): absolute path to the source file to flash - addr (int): start address on flash which to write the data - on_progress (function): callback to be triggered on flash progress - power_on (boolean): whether to power the target before flashing - - Returns: - Integer value greater than or equal to zero. Has no significance. - - Raises: - JLinkException: on hardware errors. - """ - if on_progress is not None: - func = enums.JLinkFunctions.FLASH_PROGRESS_PROTOTYPE(on_progress) - self._dll.JLINK_SetFlashProgProgressCallback(func) - else: - self._dll.JLINK_SetFlashProgProgressCallback(0) - if power_on: - self.power_on() - try: - if not self.halted(): - self.halt() - except errors.JLinkException: - pass - - bytes_flashed = self._dll.JLINK_DownloadFile(path.encode(), addr) - if bytes_flashed < 0: - raise errors.JLinkFlashException(bytes_flashed) - return bytes_flashed - - @connection_required - def reset(self, ms=0, halt=True): - """Resets the target. - - This method resets the target, and by default toggles the RESET and - TRST pins. - - Args: - self (JLink): the ``JLink`` instance - ms (int): Amount of milliseconds to delay after reset (default: 0) - halt (bool): if the CPU should halt after reset (default: True) - - Returns: - Number of bytes read. - """ - self._dll.JLINKARM_SetResetDelay(ms) - res = self._dll.JLINKARM_Reset() - if res < 0: - raise errors.JLinkException(res) - else: - if not halt: - self._dll.JLINKARM_Go() - return res - - @connection_required - def reset_tap(self): - """Resets the TAP controller via TRST. - - Note: - This must be called at least once after power up if the TAP - controller is to be used. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``None`` - """ - self._dll.JLINKARM_ResetTRST() - - @connection_required - def restart(self, num_instructions=0, skip_breakpoints=False): - """Restarts the CPU core and simulates/emulates instructions. - - Note: - This is a no-op if the CPU isn't halted. - - Args: - self (JLink): the ``JLink`` instance - num_instructions (int): number of instructions to simulate, defaults - to zero - skip_breakpoints (bool): skip current breakpoint (default: ``False``) - - Returns: - ``True`` if device was restarted, otherwise ``False``. - - Raises: - ValueError: if instruction count is not a natural number. - """ - if not util.is_natural(num_instructions): - raise ValueError('Invalid instruction count: %s.' % num_instructions) - if not self.halted(): - return False - flags = 0 - if skip_breakpoints: - flags = flags | enums.JLinkFlags.GO_OVERSTEP_BP - self._dll.JLINKARM_GoEx(num_instructions, flags) - return True - - @connection_required - @decorators.async_decorator - def halt(self): - """Halts the CPU Core. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``True`` if halted, ``False`` otherwise. - """ - res = int(self._dll.JLINKARM_Halt()) - if res == 0: - time.sleep(1) - return True - return False - - @connection_required - def halted(self): - """Returns whether the CPU core was halted. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``True`` if the CPU core is halted, otherwise ``False``. - - Raises: - JLinkException: on device errors. - """ - result = int(self._dll.JLINKARM_IsHalted()) - if result < 0: - raise errors.JLinkException(result) - return result > 0 - - @connection_required - def core_id(self): - """Returns the identifier of the target ARM core. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - Integer identifier of ARM core. - """ - return self._dll.JLINKARM_GetId() - - @connection_required - def core_cpu(self): - """Returns the identifier of the core CPU. - - Note: - This is distinct from the value returned from ``core_id()`` which is - the ARM specific identifier. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - The identifier of the CPU core. - """ - return self._dll.JLINKARM_CORE_GetFound() - - @connection_required - def core_name(self): - """Returns the name of the target ARM core. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - The target core's name. - """ - buf_size = self.MAX_BUF_SIZE - buf = (ctypes.c_char * buf_size)() - self._dll.JLINKARM_Core2CoreName(self.core_cpu(), buf, buf_size) - return ctypes.string_at(buf).decode() - - @connection_required - def ir_len(self): - """Counts and returns the total length of instruction registers of all - the devices in the JTAG scan chain. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - Total instruction register length. - """ - return self._dll.JLINKARM_GetIRLen() - - @connection_required - def scan_len(self): - """Retrieves and returns the length of the scan chain select register. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - Length of the scan chain select register. - """ - return self._dll.JLINKARM_GetScanLen() - - @connection_required - def scan_chain_len(self, scan_chain): - """Retrieves and returns the number of bits in the scan chain. - - Args: - self (JLink): the ``JLink`` instance - scan_chain (int): scan chain to be measured - - Returns: - Number of bits in the specified scan chain. - - Raises: - JLinkException: on error. - """ - res = self._dll.JLINKARM_MeasureSCLen(scan_chain) - if res < 0: - raise errors.JLinkException(res) - return res - - @connection_required - def device_family(self): - """Returns the device family of the target CPU. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - Integer identifier of the device family. - """ - return self._dll.JLINKARM_GetDeviceFamily() - - @connection_required - def register_list(self): - """Returns a list of the indices for the CPU registers. - - The returned indices can be used to read the register content or grab - the register name. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - List of registers. - """ - num_items = self.MAX_NUM_CPU_REGISTERS - buf = (ctypes.c_uint32 * num_items)() - num_regs = self._dll.JLINKARM_GetRegisterList(buf, num_items) - return buf[:num_regs] - - @connection_required - def register_name(self, register_index): - """Retrives and returns the name of an ARM CPU register. - - Args: - self (JLink): the ``JLink`` instance - register_index (int): index of the register whose name to retrieve - - Returns: - Name of the register. - """ - result = self._dll.JLINKARM_GetRegisterName(register_index) - return ctypes.cast(result, ctypes.c_char_p).value.decode() - - @connection_required - def cpu_speed(self, silent=False): - """Retrieves the CPU speed of the target. - - If the target does not support CPU frequency detection, this function - will return ``0``. - - Args: - self (JLink): the ``JLink`` instance - silent (bool): ``True`` if the CPU detection should not report errors - to the error handler on failure. - - Returns: - The measured CPU frequency on success, otherwise ``0`` if the core does - not support CPU frequency detection. - - Raises: - JLinkException: on hardware error. - """ - res = self._dll.JLINKARM_MeasureCPUSpeedEx(-1, 1, int(silent)) - if res < 0: - raise errors.JLinkException(res) - return res - - @connection_required - def cpu_halt_reasons(self): - """Retrives the reasons that the CPU was halted. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - A list of ``JLInkMOEInfo`` instances specifying the reasons for which - the CPU was halted. This list may be empty in the case that the CPU - is not halted. - - Raises: - JLinkException: on hardware error. - """ - buf_size = self.MAX_NUM_MOES - buf = (structs.JLinkMOEInfo * buf_size)() - num_reasons = self._dll.JLINKARM_GetMOEs(buf, buf_size) - if num_reasons < 0: - raise errors.JLinkException(num_reasons) - return list(buf)[:num_reasons] - - @connection_required - def jtag_create_clock(self): - """Creates a JTAG clock on TCK. - - Note: - This function only needs to be called once. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - The state of the TDO pin: either ``0`` or ``1``. - """ - return self._dll.JLINKARM_Clock() - - @connection_required - def jtag_send(self, tms, tdi, num_bits): - """Sends data via JTAG. - - Sends data via JTAG on the rising clock edge, TCK. At on each rising - clock edge, on bit is transferred in from TDI and out to TDO. The - clock uses the TMS to step through the standard JTAG state machine. - - Args: - self (JLink): the ``JLink`` instance - tms (int): used to determine the state transitions for the Test - Access Port (TAP) controller from its current state - tdi (int): input data to be transferred in from TDI to TDO - num_bits (int): a number in the range ``[1, 32]`` inclusively - specifying the number of meaningful bits in the ``tms`` and - ``tdi`` parameters for the purpose of extracting state and data - information - - Returns: - ``None`` - - Raises: - ValueError: if ``num_bits < 1`` or ``num_bits > 32``. - - See Also: - `JTAG Technical Overview `_. - """ - if util.is_natural(num_bits) and num_bits <= 0 or num_bits > 32: - raise ValueError('Number of bits must be >= 1 and <= 32.') - self._dll.JLINKARM_StoreBits(tms, tdi, num_bits) - - @connection_required - def jtag_flush(self): - """Flushes the internal JTAG buffer. - - Note: - The buffer is automatically flushed when a response from the target - is expected, or the buffer is full. This can be used after a - ``memory_write()`` in order to flush the buffer. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``None`` - """ - self._dll.JLINKARM_WriteBits() - - @interface_required(enums.JLinkInterfaces.SWD) - @connection_required - def swd_read8(self, offset): - """Gets a unit of ``8`` bits from the input buffer. - - Args: - self (JLink): the ``JLink`` instance - offset (int): the offset (in bits) from which to start reading - - Returns: - The integer read from the input buffer. - """ - value = self._dll.JLINK_SWD_GetU8(offset) - return ctypes.c_uint8(value).value - - @interface_required(enums.JLinkInterfaces.SWD) - @connection_required - def swd_read16(self, offset): - """Gets a unit of ``16`` bits from the input buffer. - - Args: - self (JLink): the ``JLink`` instance - offset (int): the offset (in bits) from which to start reading - - Returns: - The integer read from the input buffer. - """ - value = self._dll.JLINK_SWD_GetU16(offset) - return ctypes.c_uint16(value).value - - @interface_required(enums.JLinkInterfaces.SWD) - @connection_required - def swd_read32(self, offset): - """Gets a unit of ``32`` bits from the input buffer. - - Args: - self (JLink): the ``JLink`` instance - offset (int): the offset (in bits) from which to start reading - - Returns: - The integer read from the input buffer. - """ - value = self._dll.JLINK_SWD_GetU32(offset) - return ctypes.c_uint32(value).value - - @interface_required(enums.JLinkInterfaces.SWD) - @connection_required - def swd_write(self, output, value, nbits): - """Writes bytes over SWD (Serial Wire Debug). - - Args: - self (JLink): the ``JLink`` instance - output (int): the output buffer offset to write to - value (int): the value to write to the output buffer - nbits (int): the number of bits needed to represent the ``output`` and - ``value`` - - Returns: - The bit position of the response in the input buffer. - """ - pDir = binpacker.pack(output, nbits) - pIn = binpacker.pack(value, nbits) - bitpos = self._dll.JLINK_SWD_StoreRaw(pDir, pIn, nbits) - if bitpos < 0: - raise errors.JLinkException(bitpos) - return bitpos - - @interface_required(enums.JLinkInterfaces.SWD) - @connection_required - def swd_write8(self, output, value): - """Writes one byte over SWD (Serial Wire Debug). - - Args: - self (JLink): the ``JLink`` instance - output (int): the output buffer offset to write to - value (int): the value to write to the output buffer - - Returns: - The bit position of the response in the input buffer. - """ - return self.swd_write(output, value, 8) - - @interface_required(enums.JLinkInterfaces.SWD) - @connection_required - def swd_write16(self, output, value): - """Writes two bytes over SWD (Serial Wire Debug). - - Args: - self (JLink): the ``JLink`` instance - output (int): the output buffer offset to write to - value (int): the value to write to the output buffer - - Returns: - The bit position of the response in the input buffer. - """ - return self.swd_write(output, value, 16) - - @interface_required(enums.JLinkInterfaces.SWD) - @connection_required - def swd_write32(self, output, value): - """Writes four bytes over SWD (Serial Wire Debug). - - Args: - self (JLink): the ``JLink`` instance - output (int): the output buffer offset to write to - value (int): the value to write to the output buffer - - Returns: - The bit position of the response in the input buffer. - """ - return self.swd_write(output, value, 32) - - @interface_required(enums.JLinkInterfaces.SWD) - @connection_required - def swd_sync(self, pad=False): - """Causes a flush to write all data remaining in output buffers to SWD - device. - - Args: - self (JLink): the ``JLink`` instance - pad (bool): ``True`` if should pad the data to full byte size - - Returns: - ``None`` - """ - if pad: - self._dll.JLINK_SWD_SyncBytes() - else: - self._dll.JLINK_SWD_SyncBits() - - @connection_required - def flash_write(self, addr, data, nbits=None, flags=0): - """Writes data to the flash region of a device. - - The given number of bits, if provided, must be either ``8``, ``16``, or - ``32``. - - Args: - self (JLink): the ``JLink`` instance - addr (int): starting flash address to write to - data (list): list of data units to write - nbits (int): number of bits to use for each unit - - Returns: - Number of bytes written to flash. - """ - self._dll.JLINKARM_BeginDownload(flags) - self.memory_write(addr, data, nbits=nbits) - bytes_flashed = self._dll.JLINKARM_EndDownload() - if bytes_flashed < 0: - raise errors.JLinkFlashException(bytes_flashed) - return bytes_flashed - - @connection_required - def flash_write8(self, addr, data): - """Writes bytes to the flash region of a device. - - Args: - self (JLink): the ``JLink`` instance - addr (int): starting flash address to write to - data (list): list of bytes to write - - Returns: - Number of bytes written to flash. - """ - return self.flash_write(addr, data, 8) - - @connection_required - def flash_write16(self, addr, data): - """Writes halfwords to the flash region of a device. - - Args: - self (JLink): the ``JLink`` instance - addr (int): starting flash address to write to - data (list): list of halfwords to write - - Returns: - Number of bytes written to flash. - """ - return self.flash_write(addr, data, 16) - - @connection_required - def flash_write32(self, addr, data): - """Writes words to the flash region of a device. - - Args: - self (JLink): the ``JLink`` instance - addr (int): starting flash address to write to - data (list): list of words to write - - Returns: - Number of bytes written to flash. - """ - return self.flash_write(addr, data, 32) - - @connection_required - def code_memory_read(self, addr, num_bytes): - """Reads bytes from code memory. - - Note: - This is similar to calling ``memory_read`` or ``memory_read8``, - except that this uses a cache and reads ahead. This should be used - in instances where you want to read a small amount of bytes at a - time, and expect to always read ahead. - - Args: - self (JLink): the ``JLink`` instance - addr (int): starting address from which to read - num_bytes (int): number of bytes to read - - Returns: - A list of bytes read from the target. - - Raises: - JLinkException: if memory could not be read. - """ - buf_size = num_bytes - buf = (ctypes.c_uint8 * buf_size)() - res = self._dll.JLINKARM_ReadCodeMem(addr, buf_size, buf) - if res < 0: - raise errors.JLinkException(res) - return list(buf)[:res] - - @connection_required - def num_memory_zones(self): - """Returns the number of memory zones supported by the target. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - An integer count of the number of memory zones supported by the - target. - - Raises: - JLinkException: on error. - """ - count = self._dll.JLINK_GetMemZones(0, 0) - if count < 0: - raise errors.JLinkException(count) - return count - - @connection_required - def memory_zones(self): - """Gets all memory zones supported by the current target. - - Some targets support multiple memory zones. This function provides the - ability to get a list of all the memory zones to facilate using the - memory zone routing functions. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - A list of all the memory zones as ``JLinkMemoryZone`` structures. - - Raises: - JLinkException: on hardware errors. - """ - count = self.num_memory_zones() - if count == 0: - return list() - buf = (structs.JLinkMemoryZone * count)() - res = self._dll.JLINK_GetMemZones(buf, count) - if res < 0: - raise errors.JLinkException(res) - return list(buf) - - @connection_required - def memory_read(self, addr, num_units, zone=None, nbits=None): - """Reads memory from a target system or specific memory zone. - - The optional ``zone`` specifies a memory zone to access to read from, - e.g. ``IDATA``, ``DDATA``, or ``CODE``. - - The given number of bits, if provided, must be either ``8``, ``16``, or - ``32``. If not provided, always reads ``num_units`` bytes. - - Args: - self (JLink): the ``JLink`` instance - addr (int): start address to read from - num_units (int): number of units to read - zone (str): optional memory zone name to access - nbits (int): number of bits to use for each unit - - Returns: - List of units read from the target system. - - Raises: - JLinkException: if memory could not be read. - ValueError: if ``nbits`` is not ``None``, and not in ``8``, ``16``, - or ``32``. - """ - buf_size = num_units - buf = None - access = 0 - if nbits is None: - buf = (ctypes.c_uint8 * buf_size)() - access = 0 - else: - if nbits == 8: - buf = (ctypes.c_uint8 * buf_size)() - access = 1 - else: - if nbits == 16: - buf = (ctypes.c_uint16 * buf_size)() - access = 2 - buf_size = buf_size * access - else: - if nbits == 32: - buf = (ctypes.c_uint32 * buf_size)() - access = 4 - buf_size = buf_size * access - else: - raise ValueError('Given bit size is invalid: %s' % nbits) - args = [ - addr, buf_size, buf, access] - method = self._dll.JLINKARM_ReadMemEx - if zone is not None: - method = self._dll.JLINKARM_ReadMemZonedEx - args.append(zone.encode()) - units_read = method(*args) - if units_read < 0: - raise errors.JLinkReadException(units_read) - return buf[:units_read] - - @connection_required - def memory_read8(self, addr, num_bytes, zone=None): - """Reads memory from the target system in units of bytes. - - Args: - self (JLink): the ``JLink`` instance - addr (int): start address to read from - num_bytes (int): number of bytes to read - zone (str): memory zone to read from - - Returns: - List of bytes read from the target system. - - Raises: - JLinkException: if memory could not be read. - """ - return self.memory_read(addr, num_bytes, zone=zone, nbits=8) - - @connection_required - def memory_read16(self, addr, num_halfwords, zone=None): - """Reads memory from the target system in units of 16-bits. - - Args: - self (JLink): the ``JLink`` instance - addr (int): start address to read from - num_halfwords (int): number of half words to read - zone (str): memory zone to read from - - Returns: - List of halfwords read from the target system. - - Raises: - JLinkException: if memory could not be read - """ - return self.memory_read(addr, num_halfwords, zone=zone, nbits=16) - - @connection_required - def memory_read32(self, addr, num_words, zone=None): - """Reads memory from the target system in units of 32-bits. - - Args: - self (JLink): the ``JLink`` instance - addr (int): start address to read from - num_words (int): number of words to read - zone (str): memory zone to read from - - Returns: - List of words read from the target system. - - Raises: - JLinkException: if memory could not be read - """ - return self.memory_read(addr, num_words, zone=zone, nbits=32) - - @connection_required - def memory_read64(self, addr, num_long_words): - """Reads memory from the target system in units of 64-bits. - - Args: - self (JLink): the ``JLink`` instance - addr (int): start address to read from - num_long_words (int): number of long words to read - - Returns: - List of long words read from the target system. - - Raises: - JLinkException: if memory could not be read - """ - buf_size = num_long_words - buf = (ctypes.c_ulonglong * buf_size)() - units_read = self._dll.JLINKARM_ReadMemU64(addr, buf_size, buf, 0) - if units_read < 0: - raise errors.JLinkException(units_read) - return buf[:units_read] - - @connection_required - def memory_write(self, addr, data, zone=None, nbits=None): - """Writes memory to a target system or specific memory zone. - - The optional ``zone`` specifies a memory zone to access to write to, - e.g. ``IDATA``, ``DDATA``, or ``CODE``. - - The given number of bits, if provided, must be either ``8``, ``16``, or - ``32``. - - Args: - self (JLink): the ``JLink`` instance - addr (int): start address to write to - data (list): list of data units to write - zone (str): optional memory zone name to access - nbits (int): number of bits to use for each unit - - Returns: - Number of units written. - - Raises: - JLinkException: on write hardware failure. - ValueError: if ``nbits`` is not ``None``, and not in ``8``, ``16`` or - ``32``. - """ - buf_size = len(data) - buf = None - access = 0 - if nbits is None: - packed_data = map(lambda d: reversed(binpacker.pack(d)) -, data) - packed_data = list((itertools.chain)(*packed_data)) - buf_size = len(packed_data) - buf = (ctypes.c_uint8 * buf_size)(*packed_data) - access = 0 - else: - if nbits == 8: - buf = (ctypes.c_uint8 * buf_size)(*data) - access = 1 - else: - if nbits == 16: - buf = (ctypes.c_uint16 * buf_size)(*data) - access = 2 - buf_size = buf_size * access - else: - if nbits == 32: - buf = (ctypes.c_uint32 * buf_size)(*data) - access = 4 - buf_size = buf_size * access - else: - raise ValueError('Given bit size is invalid: %s' % nbits) - args = [ - addr, buf_size, buf, access] - method = self._dll.JLINKARM_WriteMemEx - if zone is not None: - method = self._dll.JLINKARM_WriteMemZonedEx - args.append(zone.encode()) - units_written = method(*args) - if units_written < 0: - raise errors.JLinkWriteException(units_written) - return units_written - - @connection_required - def memory_write8(self, addr, data, zone=None): - """Writes bytes to memory of a target system. - - Args: - self (JLink): the ``JLink`` instance - addr (int): start address to write to - data (list): list of bytes to write - zone (str): optional memory zone to access - - Returns: - Number of bytes written to target. - - Raises: - JLinkException: on memory access error. - """ - return self.memory_write(addr, data, zone, 8) - - @connection_required - def memory_write16(self, addr, data, zone=None): - """Writes half-words to memory of a target system. - - Args: - self (JLink): the ``JLink`` instance - addr (int): start address to write to - data (list): list of half-words to write - zone (str): optional memory zone to access - - Returns: - Number of half-words written to target. - - Raises: - JLinkException: on memory access error. - """ - return self.memory_write(addr, data, zone, 16) - - @connection_required - def memory_write32(self, addr, data, zone=None): - """Writes words to memory of a target system. - - Args: - self (JLink): the ``JLink`` instance - addr (int): start address to write to - data (list): list of words to write - zone (str): optional memory zone to access - - Returns: - Number of words written to target. - - Raises: - JLinkException: on memory access error. - """ - return self.memory_write(addr, data, zone, 32) - - @connection_required - def memory_write64(self, addr, data, zone=None): - """Writes long words to memory of a target system. - - Note: - This is little-endian. - - Args: - self (JLink): the ``JLink`` instance - addr (int): start address to write to - data (list): list of long words to write - zone (str): optional memory zone to access - - Returns: - Number of long words written to target. - - Raises: - JLinkException: on memory access error. - """ - words = [] - bitmask = 4294967295 - for long_word in data: - words.append(long_word & bitmask) - words.append(long_word >> 32 & bitmask) - - return self.memory_write32(addr, words, zone=zone) - - @connection_required - def register_read(self, register_index): - """Reads the value from the given register. - - Args: - self (JLink): the ``JLink`` instance - register_index (int/str): the register to read - - Returns: - The value stored in the given register. - """ - if isinstance(register_index, six.string_types): - register_index = self._get_register_index_from_name(register_index) - return self._dll.JLINKARM_ReadReg(register_index) - - @connection_required - def register_read_multiple(self, register_indices): - """Retrieves the values from the registers specified. - - Args: - self (JLink): the ``JLink`` instance - register_indices (list): list of registers to read - - Returns: - A list of values corresponding one-to-one for each of the given - register indices. The returned list of values are the values in - order of which the indices were specified. - - Raises: - JLinkException: if a given register is invalid or an error occurs. - """ - register_indices = register_indices[:] - num_regs = len(register_indices) - for idx, indice in enumerate(register_indices): - if isinstance(indice, six.string_types): - register_indices[idx] = self._get_register_index_from_name(indice) - - buf = (ctypes.c_uint32 * num_regs)(*register_indices) - data = ctypes.c_uint32 * num_regs(0) - statuses = ctypes.c_uint8 * num_regs(0) - res = self._dll.JLINKARM_ReadRegs(buf, data, statuses, num_regs) - if res < 0: - raise errors.JLinkException(res) - return list(data) - - @connection_required - def register_write(self, reg_index, value): - """Writes into an ARM register. - - Note: - The data is not immediately written, but is cached before being - transferred to the CPU on CPU start. - - Args: - self (JLink): the ``JLink`` instance - reg_index (int/str): the ARM register to write to - value (int): the value to write to the register - - Returns: - The value written to the ARM register. - - Raises: - JLinkException: on write error. - """ - if isinstance(reg_index, six.string_types): - reg_index = self._get_register_index_from_name(reg_index) - res = self._dll.JLINKARM_WriteReg(reg_index, value) - if res != 0: - raise errors.JLinkException('Error writing to register %d' % reg_index) - return value - - @connection_required - def register_write_multiple(self, register_indices, values): - """Writes to multiple CPU registers. - - Writes the values to the given registers in order. There must be a - one-to-one correspondence between the values and the registers - specified. - - Args: - self (JLink): the ``JLink`` instance - register_indices (list): list of registers to write to - values (list): list of values to write to the registers - - Returns: - ``None`` - - Raises: - ValueError: if ``len(register_indices) != len(values)`` - JLinkException: if a register could not be written to or on error - """ - register_indices = register_indices[:] - if len(register_indices) != len(values): - raise ValueError('Must be an equal number of registers and values') - num_regs = len(register_indices) - for idx, indice in enumerate(register_indices): - if isinstance(indice, six.string_types): - register_indices[idx] = self._get_register_index_from_name(indice) - - buf = (ctypes.c_uint32 * num_regs)(*register_indices) - data = (ctypes.c_uint32 * num_regs)(*values) - statuses = ctypes.c_uint8 * num_regs(0) - res = self._dll.JLINKARM_WriteRegs(buf, data, statuses, num_regs) - if res != 0: - raise errors.JLinkException(res) - - @connection_required - def ice_register_read(self, register_index): - """Reads a value from an ARM ICE register. - - Args: - self (JLink): the ``JLink`` instance - register_index (int): the register to read - - Returns: - The value read from the register. - """ - return self._dll.JLINKARM_ReadICEReg(register_index) - - @connection_required - def ice_register_write(self, register_index, value, delay=False): - """Writes a value to an ARM ICE register. - - Args: - self (JLink): the ``JLink`` instance - register_index (int): the ICE register to write to - value (int): the value to write to the ICE register - delay (bool): boolean specifying if the write should be delayed - - Returns: - ``None`` - """ - self._dll.JLINKARM_WriteICEReg(register_index, int(value), int(delay)) - - @connection_required - def etm_supported(self): - """Returns if the CPU core supports ETM. - - Args: - self (JLink): the ``JLink`` instance. - - Returns: - ``True`` if the CPU has the ETM unit, otherwise ``False``. - """ - res = self._dll.JLINKARM_ETM_IsPresent() - if res == 1: - return True - info = ctypes.c_uint32(0) - index = enums.JLinkROMTable.ETM - res = self._dll.JLINKARM_GetDebugInfo(index, ctypes.byref(info)) - if res == 1: - return False - return True - - @connection_required - def etm_register_read(self, register_index): - """Reads a value from an ETM register. - - Args: - self (JLink): the ``JLink`` instance. - register_index (int): the register to read. - - Returns: - The value read from the ETM register. - """ - return self._dll.JLINKARM_ETM_ReadReg(register_index) - - @connection_required - def etm_register_write(self, register_index, value, delay=False): - """Writes a value to an ETM register. - - Args: - self (JLink): the ``JLink`` instance. - register_index (int): the register to write to. - value (int): the value to write to the register. - delay (bool): boolean specifying if the write should be buffered. - - Returns: - ``None`` - """ - self._dll.JLINKARM_ETM_WriteReg(int(register_index), int(value), int(delay)) - - @connection_required - def coresight_read(self, reg, ap=True): - """Reads an Ap/DP register on a CoreSight DAP. - - Wait responses and special handling are both handled by this method. - - Note: - ``coresight_configure()`` must be called prior to calling this method. - - Args: - self (JLink): the ``JLink`` instance - reg (int): index of DP/AP register to read - ap (bool): ``True`` if reading from an Access Port register, - otherwise ``False`` for Debug Port - - Returns: - Data read from register. - - Raises: - JLinkException: on hardware error - """ - data = ctypes.c_uint32() - ap = 1 if ap else 0 - res = self._dll.JLINKARM_CORESIGHT_ReadAPDPReg(reg, ap, ctypes.byref(data)) - if res < 0: - raise errors.JLinkException(res) - return data.value - - @connection_required - def coresight_write(self, reg, data, ap=True): - """Writes an Ap/DP register on a CoreSight DAP. - - Note: - ``coresight_configure()`` must be called prior to calling this method. - - Args: - self (JLink): the ``JLink`` instance - reg (int): index of DP/AP register to write - data (int): data to write - ap (bool): ``True`` if writing to an Access Port register, otherwise - ``False`` for Debug Port - - Returns: - Number of repetitions needed until write request accepted. - - Raises: - JLinkException: on hardware error - """ - ap = 1 if ap else 0 - res = self._dll.JLINKARM_CORESIGHT_WriteAPDPReg(reg, ap, data) - if res < 0: - raise errors.JLinkException(res) - return res - - @connection_required - def enable_reset_pulls_reset(self): - """Enables RESET pin toggling on the JTAG bus on resets. - - When ``.reset()`` is called, it will also toggle the RESET pin on the - JTAG bus. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``None`` - """ - self._dll.JLINKARM_ResetPullsRESET(1) - - @connection_required - def disable_reset_pulls_reset(self): - """Disables RESET pin toggling on the JTAG bus on resets. - - When ``.reset()`` is called, it will not toggle the RESET pin on the - JTAG bus. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``None`` - """ - self._dll.JLINKARM_ResetPullsRESET(0) - - @connection_required - def enable_reset_pulls_trst(self): - """Enables TRST pin toggling on the JTAG bus on resets. - - When ``.reset()`` is called, it will also toggle the TRST pin on the - JTAG bus. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``None`` - """ - self._dll.JLINKARM_ResetPullsTRST(1) - - @connection_required - def disable_reset_pulls_trst(self): - """Disables TRST pin toggling on the JTAG bus on resets. - - When ``.reset()`` is called, it will not toggle the TRST pin on the - JTAG bus. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``None`` - """ - self._dll.JLINKARM_ResetPullsTRST(0) - - @connection_required - def enable_reset_inits_registers(self): - """Enables CPU register initialization on resets. - - When ``.reset()`` is called, it will initialize the CPU registers. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``True`` if was previously enabled, otherwise ``False``. - """ - return bool(self._dll.JLINKARM_SetInitRegsOnReset(1)) - - @connection_required - def disable_reset_inits_registers(self): - """Disables CPU register initialization on resets. - - When ``.reset()`` is called, the CPU registers will be read and not - initialized. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``True`` if was previously enabled, otherwise ``False``. - """ - return bool(self._dll.JLINKARM_SetInitRegsOnReset(0)) - - @connection_required - def set_little_endian(self): - """Sets the target hardware to little endian. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``True`` if target was big endian before call, otherwise ``False``. - """ - res = self._dll.JLINKARM_SetEndian(0) - return res == 1 - - @connection_required - def set_big_endian(self): - """Sets the target hardware to big endian. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``True`` if target was little endian before call, otherwise ``False``. - """ - res = self._dll.JLINKARM_SetEndian(1) - return res == 0 - - @connection_required - def set_vector_catch(self, flags): - """Sets vector catch bits of the processor. - - The CPU will jump to a vector if the given vector catch is active, and - will enter a debug state. This has the effect of halting the CPU as - well, meaning the CPU must be explicitly restarted. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``None`` - - Raises: - JLinkException: on error. - """ - res = self._dll.JLINKARM_WriteVectorCatch(flags) - if res < 0: - raise errors.JLinkException(res) - - @connection_required - def step(self, thumb=False): - """Executes a single step. - - Steps even if there is a breakpoint. - - Args: - self (JLink): the ``JLink`` instance - thumb (bool): boolean indicating if to step in thumb mode - - Returns: - ``None`` - - Raises: - JLinkException: on error - """ - method = self._dll.JLINKARM_Step - if thumb: - method = self._dll.JLINKARM_StepComposite - res = method() - if res != 0: - raise errors.JLinkException('Failed to step over instruction.') - - @connection_required - def enable_soft_breakpoints(self): - """Enables software breakpoints. - - Note: - This should be called before calling ``software_breakpoint_set()``. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``None`` - """ - self._dll.JLINKARM_EnableSoftBPs(1) - - @connection_required - def disable_soft_breakpoints(self): - """Disables software breakpoints. - - Note: - After this function is called, ``software_breakpoint_set()`` cannot - be used without first calling ``enable_soft_breakpoints()``. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``None`` - """ - self._dll.JLINKARM_EnableSoftBPs(0) - - @connection_required - def num_active_breakpoints(self): - """Returns the number of currently active breakpoints. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - The number of breakpoints that are currently set. - """ - return self._dll.JLINKARM_GetNumBPs() - - @connection_required - def num_available_breakpoints(self, arm=False, thumb=False, ram=False, flash=False, hw=False): - """Returns the number of available breakpoints of the specified type. - - If ``arm`` is set, gets the number of available ARM breakpoint units. - If ``thumb`` is set, gets the number of available THUMB breakpoint - units. If ``ram`` is set, gets the number of available software RAM - breakpoint units. If ``flash`` is set, gets the number of available - software flash breakpoint units. If ``hw`` is set, gets the number of - available hardware breakpoint units. - - If a combination of the flags is given, then - ``num_available_breakpoints()`` returns the number of breakpoints - specified by the given flags. If no flags are specified, then the - count of available breakpoint units is returned. - - Args: - self (JLink): the ``JLink`` instance - arm (bool): Boolean indicating to get number of ARM breakpoints. - thumb (bool): Boolean indicating to get number of THUMB breakpoints. - ram (bool): Boolean indicating to get number of SW RAM breakpoints. - flash (bool): Boolean indicating to get number of Flash breakpoints. - hw (bool): Boolean indicating to get number of Hardware breakpoints. - - Returns: - The number of available breakpoint units of the specified type. - """ - flags = [ - enums.JLinkBreakpoint.ARM, - enums.JLinkBreakpoint.THUMB, - enums.JLinkBreakpoint.SW_RAM, - enums.JLinkBreakpoint.SW_FLASH, - enums.JLinkBreakpoint.HW] - set_flags = [ - arm, - thumb, - ram, - flash, - hw] - if not any(set_flags): - flags = enums.JLinkBreakpoint.ANY - else: - flags = list((f for i, f in enumerate(flags) if set_flags[i])) - flags = functools.reduce(operator.__or__, flags, 0) - return self._dll.JLINKARM_GetNumBPUnits(flags) - - @connection_required - def breakpoint_info(self, handle=0, index=-1): - """Returns the information about a set breakpoint. - - Note: - Either ``handle`` or ``index`` can be specified. If the ``index`` - is not provided, the ``handle`` must be set, and vice-versa. If - both ``index`` and ``handle`` are provided, the ``index`` overrides - the provided ``handle``. - - Args: - self (JLink): the ``JLink`` instance - handle (int): option handle of a valid breakpoint - index (int): optional index of the breakpoint. - - Returns: - An instance of ``JLinkBreakpointInfo`` specifying information about - the breakpoint. - - Raises: - JLinkException: on error. - ValueError: if both the handle and index are invalid. - """ - if index < 0: - if handle == 0: - raise ValueError('Handle must be provided if index is not set.') - bp = structs.JLinkBreakpointInfo() - bp.Handle = int(handle) - res = self._dll.JLINKARM_GetBPInfoEx(index, ctypes.byref(bp)) - if res < 0: - raise errors.JLinkException('Failed to get breakpoint info.') - return bp - - @connection_required - def breakpoint_find(self, addr): - """Returns the handle of a breakpoint at the given address, if any. - - Args: - self (JLink): the ``JLink`` instance - addr (int): the address to search for the breakpoint - - Returns: - A non-zero integer if a breakpoint was found at the given address, - otherwise zero. - """ - return self._dll.JLINKARM_FindBP(addr) - - @connection_required - def breakpoint_set(self, addr, thumb=False, arm=False): - """Sets a breakpoint at the specified address. - - If ``thumb`` is ``True``, the breakpoint is set in THUMB-mode, while if - ``arm`` is ``True``, the breakpoint is set in ARM-mode, otherwise a - normal breakpoint is set. - - Args: - self (JLink): the ``JLink`` instance - addr (int): the address where the breakpoint will be set - thumb (bool): boolean indicating to set the breakpoint in THUMB mode - arm (bool): boolean indicating to set the breakpoint in ARM mode - - Returns: - An integer specifying the breakpoint handle. This handle should be - retained for future breakpoint operations. - - Raises: - TypeError: if the given address is not an integer. - JLinkException: if the breakpoint could not be set. - """ - flags = enums.JLinkBreakpoint.ANY - if thumb: - flags = flags | enums.JLinkBreakpoint.THUMB - else: - if arm: - flags = flags | enums.JLinkBreakpoint.ARM - handle = self._dll.JLINKARM_SetBPEx(int(addr), flags) - if handle <= 0: - raise errors.JLinkException('Breakpoint could not be set.') - return handle - - @connection_required - def software_breakpoint_set(self, addr, thumb=False, arm=False, flash=False, ram=False): - """Sets a software breakpoint at the specified address. - - If ``thumb`` is ``True``, the breakpoint is set in THUMB-mode, while if - ``arm`` is ``True``, the breakpoint is set in ARM-mode, otherwise a - normal breakpoint is set. - - If ``flash`` is ``True``, the breakpoint is set in flash, otherwise if - ``ram`` is ``True``, the breakpoint is set in RAM. If both are - ``True`` or both are ``False``, then the best option is chosen for - setting the breakpoint in software. - - Args: - self (JLink): the ``JLink`` instance - addr (int): the address where the breakpoint will be set - thumb (bool): boolean indicating to set the breakpoint in THUMB mode - arm (bool): boolean indicating to set the breakpoint in ARM mode - flash (bool): boolean indicating to set the breakpoint in flash - ram (bool): boolean indicating to set the breakpoint in RAM - - Returns: - An integer specifying the breakpoint handle. This handle should sbe - retained for future breakpoint operations. - - Raises: - TypeError: if the given address is not an integer. - JLinkException: if the breakpoint could not be set. - """ - if flash and not ram: - flags = enums.JLinkBreakpoint.SW_FLASH - else: - if not flash or ram: - flags = enums.JLinkBreakpoint.SW_RAM - else: - flags = enums.JLinkBreakpoint.SW - if thumb: - flags = flags | enums.JLinkBreakpoint.THUMB - else: - if arm: - flags = flags | enums.JLinkBreakpoint.ARM - handle = self._dll.JLINKARM_SetBPEx(int(addr), flags) - if handle <= 0: - raise errors.JLinkException('Software breakpoint could not be set.') - return handle - - @connection_required - def hardware_breakpoint_set(self, addr, thumb=False, arm=False): - """Sets a hardware breakpoint at the specified address. - - If ``thumb`` is ``True``, the breakpoint is set in THUMB-mode, while if - ``arm`` is ``True``, the breakpoint is set in ARM-mode, otherwise a - normal breakpoint is set. - - Args: - self (JLink): the ``JLink`` instance - addr (int): the address where the breakpoint will be set - thumb (bool): boolean indicating to set the breakpoint in THUMB mode - arm (bool): boolean indicating to set the breakpoint in ARM mode - - Returns: - An integer specifying the breakpoint handle. This handle should sbe - retained for future breakpoint operations. - - Raises: - TypeError: if the given address is not an integer. - JLinkException: if the breakpoint could not be set. - """ - flags = enums.JLinkBreakpoint.HW - if thumb: - flags = flags | enums.JLinkBreakpoint.THUMB - else: - if arm: - flags = flags | enums.JLinkBreakpoint.ARM - handle = self._dll.JLINKARM_SetBPEx(int(addr), flags) - if handle <= 0: - raise errors.JLinkException('Hardware breakpoint could not be set.') - return handle - - @connection_required - def breakpoint_clear(self, handle): - """Removes a single breakpoint. - - Args: - self (JLink): the ``JLink`` instance - handle (int): the handle of the breakpoint to be removed - - Returns: - ``True`` if the breakpoint was cleared, otherwise ``False`` if the - breakpoint was not valid. - """ - return not self._dll.JLINKARM_ClrBPEx(handle) - - @connection_required - def breakpoint_clear_all(self): - """Removes all breakpoints that have been set. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``True`` if they were cleared, otherwise ``False``. - """ - return not self._dll.JLINKARM_ClrBPEx(4294967295) - - @connection_required - def num_active_watchpoints(self): - """Returns the number of currently active watchpoints. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - The number of watchpoints that are currently set. - """ - return self._dll.JLINKARM_GetNumWPs() - - @connection_required - def num_available_watchpoints(self): - """Returns the number of available watchpoints. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - The number of watchpoints that are available to be set. - """ - return self._dll.JLINKARM_GetNumWPUnits() - - @connection_required - def watchpoint_info(self, handle=0, index=-1): - """Returns information about the specified watchpoint. - - Note: - Either ``handle`` or ``index`` can be specified. If the ``index`` - is not provided, the ``handle`` must be set, and vice-versa. If - both ``index`` and ``handle`` are provided, the ``index`` overrides - the provided ``handle``. - - Args: - self (JLink): the ``JLink`` instance - handle (int): optional handle of a valid watchpoint. - index (int): optional index of a watchpoint. - - Returns: - An instance of ``JLinkWatchpointInfo`` specifying information about - the watchpoint if the watchpoint was found, otherwise ``None``. - - Raises: - JLinkException: on error. - ValueError: if both handle and index are invalid. - """ - if index < 0: - if handle == 0: - raise ValueError('Handle must be provided if index is not set.') - wp = structs.JLinkWatchpointInfo() - res = self._dll.JLINKARM_GetWPInfoEx(index, ctypes.byref(wp)) - if res < 0: - raise errors.JLinkException('Failed to get watchpoint info.') - for i in range(res): - res = self._dll.JLINKARM_GetWPInfoEx(i, ctypes.byref(wp)) - if res < 0: - raise errors.JLinkException('Failed to get watchpoint info.') - if wp.Handle == handle or wp.WPUnit == index: - return wp - - @connection_required - def watchpoint_set(self, addr, addr_mask=0, data=0, data_mask=0, access_size=None, read=False, write=False, privileged=False): - """Sets a watchpoint at the given address. - - This method allows for a watchpoint to be set on an given address or - range of addresses. The watchpoint can then be triggered if the data - at the given address matches the specified ``data`` or range of data as - determined by ``data_mask``, on specific access size events, reads, - writes, or privileged accesses. - - Both ``addr_mask`` and ``data_mask`` are used to specify ranges. Bits - set to ``1`` are masked out and not taken into consideration when - comparison against an address or data value. E.g. an ``addr_mask`` - with a value of ``0x1`` and ``addr`` with value ``0xdeadbeef`` means - that the watchpoint will be set on addresses ``0xdeadbeef`` and - ``0xdeadbeee``. If the ``data`` was ``0x11223340`` and the given - ``data_mask`` has a value of ``0x0000000F``, then the watchpoint would - trigger for data matching ``0x11223340 - 0x1122334F``. - - Note: - If both ``read`` and ``write`` are specified, then the watchpoint - will trigger on both read and write events to the given address. - - Args: - self (JLink): the ``JLink`` instance - addr_mask (int): optional mask to use for determining which address - the watchpoint should be set on - data (int): optional data to set the watchpoint on in order to have - the watchpoint triggered when the value at the specified address - matches the given ``data`` - data_mask (int): optional mask to use for determining the range of - data on which the watchpoint should be triggered - access_size (int): if specified, this must be one of ``{8, 16, 32}`` - and determines the access size for which the watchpoint should - trigger - read (bool): if ``True``, triggers the watchpoint on read events - write (bool): if ``True``, triggers the watchpoint on write events - privileged (bool): if ``True``, triggers the watchpoint on privileged - accesses - - Returns: - The handle of the created watchpoint. - - Raises: - ValueError: if an invalid access size is given. - JLinkException: if the watchpoint fails to be set. - """ - access_flags = 0 - access_mask_flags = 0 - if access_size is None: - access_mask_flags = access_mask_flags | enums.JLinkAccessMaskFlags.SIZE - else: - if access_size == 8: - access_flags = access_flags | enums.JLinkAccessFlags.SIZE_8BIT - else: - if access_size == 16: - access_flags = access_flags | enums.JLinkAccessFlags.SIZE_16BIT - else: - if access_size == 32: - access_flags = access_flags | enums.JLinkAccessFlags.SIZE_32BIT - else: - raise ValueError('Invalid access size given: %d' % access_size) - if read and write: - access_mask_flags = access_mask_flags | enums.JLinkAccessMaskFlags.DIR - else: - if read: - access_flags = access_flags | enums.JLinkAccessFlags.READ - else: - if write: - access_flags = access_flags | enums.JLinkAccessFlags.WRITE - if privileged: - access_flags = access_flags | enums.JLinkAccessFlags.PRIV - else: - access_mask_flags = access_mask_flags | enums.JLinkAccessMaskFlags.PRIV - wp = structs.JLinkDataEvent() - wp.Addr = addr - wp.AddrMask = addr_mask - wp.Data = data - wp.DataMask = data_mask - wp.Access = access_flags - wp.AccessMask = access_mask_flags - handle = ctypes.c_uint32() - res = self._dll.JLINKARM_SetDataEvent(ctypes.pointer(wp), ctypes.pointer(handle)) - if res < 0: - raise errors.JLinkDataException(res) - return handle.value - - @connection_required - def watchpoint_clear(self, handle): - """Clears the watchpoint with the specified handle. - - Args: - self (JLink): the ``JLink`` instance - handle (int): the handle of the watchpoint - - Returns: - ``True`` if watchpoint was removed, otherwise ``False``. - """ - return not self._dll.JLINKARM_ClrDataEvent(handle) - - @connection_required - def watchpoint_clear_all(self): - """Removes all watchpoints that have been set. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``True`` if they were cleared, otherwise ``False``. - """ - return not self._dll.JLINKARM_ClrDataEvent(4294967295) - - def disassemble_instruction(self, instruction): - """Disassembles and returns the assembly instruction string. - - Args: - self (JLink): the ``JLink`` instance. - instruction (int): the instruction address. - - Returns: - A string corresponding to the assembly instruction string at the - given instruction address. - - Raises: - JLinkException: on error. - TypeError: if ``instruction`` is not a number. - """ - if not util.is_integer(instruction): - raise TypeError('Expected instruction to be an integer.') - buf_size = self.MAX_BUF_SIZE - buf = (ctypes.c_char * buf_size)() - res = self._dll.JLINKARM_DisassembleInst(ctypes.byref(buf), buf_size, instruction) - if res < 0: - raise errors.JLinkException('Failed to disassemble instruction.') - return ctypes.string_at(buf).decode() - - @connection_required - def strace_configure(self, port_width): - """Configures the trace port width for tracing. - - Note that configuration cannot occur while STRACE is running. - - Args: - self (JLink): the ``JLink`` instance - port_width (int): the trace port width to use. - - Returns: - ``None`` - - Raises: - ValueError: if ``port_width`` is not ``1``, ``2``, or ``4``. - JLinkException: on error. - """ - if port_width not in (1, 2, 4): - raise ValueError('Invalid port width: %s' % str(port_width)) - config_string = 'PortWidth=%d' % port_width - res = self._dll.JLINK_STRACE_Config(config_string.encode()) - if res < 0: - raise errors.JLinkException('Failed to configure STRACE port') - - @connection_required - def strace_start(self): - """Starts the capturing of STRACE data. - - Args: - self (JLink): the ``JLink`` instance. - - Returns: - ``None`` - - Raises: - JLinkException: on error. - """ - res = self._dll.JLINK_STRACE_Start() - if res < 0: - raise errors.JLinkException('Failed to start STRACE.') - - @connection_required - def strace_stop(self): - """Stops the sampling of STRACE data. - - Any capturing of STRACE data is automatically stopped when the CPU is - halted. - - Args: - self (JLink): the ``JLink`` instance. - - Returns: - ``None`` - - Raises: - JLinkException: on error. - """ - res = self._dll.JLINK_STRACE_Stop() - if res < 0: - raise errors.JLinkException('Failed to stop STRACE.') - - @connection_required - def strace_read(self, num_instructions): - """Reads and returns a number of instructions captured by STRACE. - - The number of instructions must be a non-negative value of at most - ``0x10000`` (``65536``). - - Args: - self (JLink): the ``JLink`` instance. - num_instructions (int): number of instructions to fetch. - - Returns: - A list of instruction addresses in order from most recently executed - to oldest executed instructions. Note that the number of - instructions returned can be less than the number of instructions - requested in the case that there are not ``num_instructions`` in the - trace buffer. - - Raises: - JLinkException: on error. - ValueError: if ``num_instructions < 0`` or - ``num_instructions > 0x10000``. - """ - if num_instructions < 0 or num_instructions > 65536: - raise ValueError('Invalid instruction count.') - buf = (ctypes.c_uint32 * num_instructions)() - buf_size = num_instructions - res = self._dll.JLINK_STRACE_Read(ctypes.byref(buf), buf_size) - if res < 0: - raise errors.JLinkException('Failed to read from STRACE buffer.') - return list(buf)[:res] - - @connection_required - def strace_code_fetch_event(self, operation, address, address_range=0): - """Sets an event to trigger trace logic when an instruction is fetched. - - Args: - self (JLink): the ``JLink`` instance. - operation (int): one of the operations in ``JLinkStraceOperation``. - address (int): the address of the instruction that is fetched. - address_range (int): optional range of address to trigger event on. - - Returns: - An integer specifying the trace event handle. This handle should be - retained in order to clear the event at a later time. - - Raises: - JLinkException: on error. - """ - cmd = enums.JLinkStraceCommand.TRACE_EVENT_SET - event_info = structs.JLinkStraceEventInfo() - event_info.Type = enums.JLinkStraceEvent.CODE_FETCH - event_info.Op = operation - event_info.Addr = int(address) - event_info.AddrRangeSize = int(address_range) - handle = self._dll.JLINK_STRACE_Control(cmd, ctypes.byref(event_info)) - if handle < 0: - raise errors.JLinkException(handle) - return handle - - @connection_required - def strace_data_access_event(self, operation, address, data, data_mask=None, access_width=4, address_range=0): - """Sets an event to trigger trace logic when data access is made. - - Data access corresponds to either a read or write. - - Args: - self (JLink): the ``JLink`` instance. - operation (int): one of the operations in ``JLinkStraceOperation``. - address (int): the address of the load/store data. - data (int): the data to be compared the event data to. - data_mask (int): optional bitmask specifying bits to ignore in - comparison. - acess_width (int): optional access width for the data. - address_range (int): optional range of address to trigger event on. - - Returns: - An integer specifying the trace event handle. This handle should be - retained in order to clear the event at a later time. - - Raises: - JLinkException: on error. - """ - cmd = enums.JLinkStraceCommand.TRACE_EVENT_SET - event_info = structs.JLinkStraceEventInfo() - event_info.Type = enums.JLinkStraceEvent.DATA_ACCESS - event_info.Op = operation - event_info.AccessSize = int(access_width) - event_info.Addr = int(address) - event_info.Data = int(data) - event_info.DataMask = int(data_mask or 0) - event_info.AddrRangeSize = int(address_range) - handle = self._dll.JLINK_STRACE_Control(cmd, ctypes.byref(event_info)) - if handle < 0: - raise errors.JLinkException(handle) - return handle - - @connection_required - def strace_data_load_event(self, operation, address, address_range=0): - """Sets an event to trigger trace logic when data read access is made. - - Args: - self (JLink): the ``JLink`` instance. - operation (int): one of the operations in ``JLinkStraceOperation``. - address (int): the address of the load data. - address_range (int): optional range of address to trigger event on. - - Returns: - An integer specifying the trace event handle. This handle should be - retained in order to clear the event at a later time. - - Raises: - JLinkException: on error. - """ - cmd = enums.JLinkStraceCommand.TRACE_EVENT_SET - event_info = structs.JLinkStraceEventInfo() - event_info.Type = enums.JLinkStraceEvent.DATA_LOAD - event_info.Op = operation - event_info.Addr = int(address) - event_info.AddrRangeSize = int(address_range) - handle = self._dll.JLINK_STRACE_Control(cmd, ctypes.byref(event_info)) - if handle < 0: - raise errors.JLinkException(handle) - return handle - - @connection_required - def strace_data_store_event(self, operation, address, address_range=0): - """Sets an event to trigger trace logic when data write access is made. - - Args: - self (JLink): the ``JLink`` instance. - operation (int): one of the operations in ``JLinkStraceOperation``. - address (int): the address of the store data. - address_range (int): optional range of address to trigger event on. - - Returns: - An integer specifying the trace event handle. This handle should be - retained in order to clear the event at a later time. - - Raises: - JLinkException: on error. - """ - cmd = enums.JLinkStraceCommand.TRACE_EVENT_SET - event_info = structs.JLinkStraceEventInfo() - event_info.Type = enums.JLinkStraceEvent.DATA_STORE - event_info.Op = operation - event_info.Addr = int(address) - event_info.AddrRangeSize = int(address_range) - handle = self._dll.JLINK_STRACE_Control(cmd, ctypes.byref(event_info)) - if handle < 0: - raise errors.JLinkException(handle) - return handle - - @connection_required - def strace_clear(self, handle): - """Clears the trace event specified by the given handle. - - Args: - self (JLink): the ``JLink`` instance. - handle (int): handle of the trace event. - - Returns: - ``None`` - - Raises: - JLinkException: on error. - """ - data = ctypes.c_int(handle) - res = self._dll.JLINK_STRACE_Control(enums.JLinkStraceCommand.TRACE_EVENT_CLR, ctypes.byref(data)) - if res < 0: - raise errors.JLinkException('Failed to clear STRACE event.') - - @connection_required - def strace_clear_all(self): - """Clears all STRACE events. - - Args: - self (JLink): the ``JLink`` instance. - - Returns: - ``None`` - - Raises: - JLinkException: on error. - """ - data = 0 - res = self._dll.JLINK_STRACE_Control(enums.JLinkStraceCommand.TRACE_EVENT_CLR_ALL, data) - if res < 0: - raise errors.JLinkException('Failed to clear all STRACE events.') - - @connection_required - def strace_set_buffer_size(self, size): - """Sets the STRACE buffer size. - - Args: - self (JLink): the ``JLink`` instance. - - Returns: - ``None`` - - Raises: - JLinkException: on error. - """ - size = ctypes.c_uint32(size) - res = self._dll.JLINK_STRACE_Control(enums.JLinkStraceCommand.SET_BUFFER_SIZE, size) - if res < 0: - raise errors.JLinkException('Failed to set the STRACE buffer size.') - - @connection_required - def trace_start(self): - """Starts collecting trace data. - - Args: - self (JLink): the ``JLink`` instance. - - Returns: - ``None`` - """ - cmd = enums.JLinkTraceCommand.START - res = self._dll.JLINKARM_TRACE_Control(cmd, 0) - if res == 1: - raise errors.JLinkException('Failed to start trace.') - - @connection_required - def trace_stop(self): - """Stops collecting trace data. - - Args: - self (JLink): the ``JLink`` instance. - - Returns: - ``None`` - """ - cmd = enums.JLinkTraceCommand.STOP - res = self._dll.JLINKARM_TRACE_Control(cmd, 0) - if res == 1: - raise errors.JLinkException('Failed to stop trace.') - - @connection_required - def trace_flush(self): - """Flushes the trace buffer. - - After this method is called, the trace buffer is empty. This method is - best called when the device is reset. - - Args: - self (JLink): the ``JLink`` instance. - - Returns: - ``None`` - """ - cmd = enums.JLinkTraceCommand.FLUSH - res = self._dll.JLINKARM_TRACE_Control(cmd, 0) - if res == 1: - raise errors.JLinkException('Failed to flush the trace buffer.') - - @connection_required - def trace_sample_count(self): - """Retrieves the number of samples in the trace buffer. - - Args: - self (JLink): the ``JLink`` instance. - - Returns: - Number of samples in the trace buffer. - """ - cmd = enums.JLinkTraceCommand.GET_NUM_SAMPLES - data = ctypes.c_uint32(self.trace_max_buffer_capacity()) - res = self._dll.JLINKARM_TRACE_Control(cmd, ctypes.byref(data)) - if res == 1: - raise errors.JLinkException('Failed to get trace sample count.') - return data.value - - @connection_required - def trace_buffer_capacity(self): - """Retrieves the trace buffer's current capacity. - - Args: - self (JLink): the ``JLink`` instance. - - Returns: - The current capacity of the trace buffer. This is not necessarily - the maximum possible size the buffer could be configured with. - """ - cmd = enums.JLinkTraceCommand.GET_CONF_CAPACITY - data = ctypes.c_uint32(0) - res = self._dll.JLINKARM_TRACE_Control(cmd, ctypes.byref(data)) - if res == 1: - raise errors.JLinkException('Failed to get trace buffer size.') - return data.value - - @connection_required - def trace_set_buffer_capacity(self, size): - """Sets the capacity for the trace buffer. - - Args: - self (JLink): the ``JLink`` instance. - size (int): the new capacity for the trace buffer. - - Returns: - ``None`` - """ - cmd = enums.JLinkTraceCommand.SET_CAPACITY - data = ctypes.c_uint32(size) - res = self._dll.JLINKARM_TRACE_Control(cmd, ctypes.byref(data)) - if res == 1: - raise errors.JLinkException('Failed to set trace buffer size.') - - @connection_required - def trace_min_buffer_capacity(self): - """Retrieves the minimum capacity the trace buffer can be configured with. - - Args: - self (JLink): the ``JLink`` instance. - - Returns: - The minimum configurable capacity for the trace buffer. - """ - cmd = enums.JLinkTraceCommand.GET_MIN_CAPACITY - data = ctypes.c_uint32(0) - res = self._dll.JLINKARM_TRACE_Control(cmd, ctypes.byref(data)) - if res == 1: - raise errors.JLinkException('Failed to get min trace buffer size.') - return data.value - - @connection_required - def trace_max_buffer_capacity(self): - """Retrieves the maximum size the trace buffer can be configured with. - - Args: - self (JLink): the ``JLink`` instance. - - Returns: - The maximum configurable capacity for the trace buffer. - """ - cmd = enums.JLinkTraceCommand.GET_MAX_CAPACITY - data = ctypes.c_uint32(0) - res = self._dll.JLINKARM_TRACE_Control(cmd, ctypes.byref(data)) - if res == 1: - raise errors.JLinkException('Failed to get max trace buffer size.') - return data.value - - @connection_required - def trace_set_format(self, fmt): - """Sets the format for the trace buffer to use. - - Args: - self (JLink): the ``JLink`` instance. - fmt (int): format for the trace buffer; this is one of the attributes - of ``JLinkTraceFormat``. - - Returns: - ``None`` - """ - cmd = enums.JLinkTraceCommand.SET_FORMAT - data = ctypes.c_uint32(fmt) - res = self._dll.JLINKARM_TRACE_Control(cmd, ctypes.byref(data)) - if res == 1: - raise errors.JLinkException('Failed to set trace format.') - - @connection_required - def trace_format(self): - """Retrieves the current format the trace buffer is using. - - Args: - self (JLink): the ``JLink`` instance. - - Returns: - The current format the trace buffer is using. This is one of the - attributes of ``JLinkTraceFormat``. - """ - cmd = enums.JLinkTraceCommand.GET_FORMAT - data = ctypes.c_uint32(0) - res = self._dll.JLINKARM_TRACE_Control(cmd, ctypes.byref(data)) - if res == 1: - raise errors.JLinkException('Failed to get trace format.') - return data.value - - @connection_required - def trace_region_count(self): - """Retrieves a count of the number of available trace regions. - - Args: - self (JLink): the ``JLink`` instance. - - Returns: - Count of the number of available trace regions. - """ - cmd = enums.JLinkTraceCommand.GET_NUM_REGIONS - data = ctypes.c_uint32(0) - res = self._dll.JLINKARM_TRACE_Control(cmd, ctypes.byref(data)) - if res == 1: - raise errors.JLinkException('Failed to get trace region count.') - return data.value - - @connection_required - def trace_region(self, region_index): - """Retrieves the properties of a trace region. - - Args: - self (JLink): the ``JLink`` instance. - region_index (int): the trace region index. - - Returns: - An instance of ``JLinkTraceRegion`` describing the specified region. - """ - cmd = enums.JLinkTraceCommand.GET_REGION_PROPS_EX - region = structs.JLinkTraceRegion() - region.RegionIndex = int(region_index) - res = self._dll.JLINKARM_TRACE_Control(cmd, ctypes.byref(region)) - if res == 1: - raise errors.JLinkException('Failed to get trace region.') - return region - - @connection_required - def trace_read(self, offset, num_items): - """Reads data from the trace buffer and returns it. - - Args: - self (JLink): the ``JLink`` instance. - offset (int): the offset from which to start reading from the trace - buffer. - num_items (int): number of items to read from the trace buffer. - - Returns: - A list of ``JLinkTraceData`` instances corresponding to the items - read from the trace buffer. Note that this list may have size less - than ``num_items`` in the event that there are not ``num_items`` - items in the trace buffer. - - Raises: - JLinkException: on error. - """ - buf_size = ctypes.c_uint32(num_items) - buf = (structs.JLinkTraceData * num_items)() - res = self._dll.JLINKARM_TRACE_Read(buf, int(offset), ctypes.byref(buf_size)) - if res == 1: - raise errors.JLinkException('Failed to read from trace buffer.') - return list(buf)[:int(buf_size.value)] - - def swo_enabled(self): - """Returns whether or not SWO is enabled. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``True`` if SWO is enabled, otherwise ``False``. - """ - return self._swo_enabled - - @connection_required - def swo_start(self, swo_speed=9600): - """Starts collecting SWO data. - - Note: - If SWO is already enabled, it will first stop SWO before enabling it - again. - - Args: - self (JLink): the ``JLink`` instance - swo_speed (int): the frequency in Hz used by the target to communicate - - Returns: - ``None`` - - Raises: - JLinkException: on error - """ - if self.swo_enabled(): - self.swo_stop() - info = structs.JLinkSWOStartInfo() - info.Speed = swo_speed - res = self._dll.JLINKARM_SWO_Control(enums.JLinkSWOCommands.START, ctypes.byref(info)) - if res < 0: - raise errors.JLinkException(res) - self._swo_enabled = True - - @connection_required - def swo_stop(self): - """Stops collecting SWO data. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - ``None`` - - Raises: - JLinkException: on error - """ - res = self._dll.JLINKARM_SWO_Control(enums.JLinkSWOCommands.STOP, 0) - if res < 0: - raise errors.JLinkException(res) - - @connection_required - def swo_enable(self, cpu_speed, swo_speed=9600, port_mask=1): - """Enables SWO output on the target device. - - Configures the output protocol, the SWO output speed, and enables any - ITM & stimulus ports. - - This is equivalent to calling ``.swo_start()``. - - Note: - If SWO is already enabled, it will first stop SWO before enabling it - again. - - Args: - self (JLink): the ``JLink`` instance - cpu_speed (int): the target CPU frequency in Hz - swo_speed (int): the frequency in Hz used by the target to communicate - port_mask (int): port mask specifying which stimulus ports to enable - - Returns: - ``None`` - - Raises: - JLinkException: on error - """ - if self.swo_enabled(): - self.swo_stop() - res = self._dll.JLINKARM_SWO_EnableTarget(cpu_speed, swo_speed, enums.JLinkSWOInterfaces.UART, port_mask) - if res != 0: - raise errors.JLinkException(res) - self._swo_enabled = True - - @connection_required - def swo_disable(self, port_mask): - """Disables ITM & Stimulus ports. - - Args: - self (JLink): the ``JLink`` instance - port_mask (int): mask specifying which ports to disable - - Returns: - ``None`` - - Raises: - JLinkException: on error - """ - res = self._dll.JLINKARM_SWO_DisableTarget(port_mask) - if res != 0: - raise errors.JLinkException(res) - - @connection_required - def swo_flush(self, num_bytes=None): - """Flushes data from the SWO buffer. - - After this method is called, the flushed part of the SWO buffer is - empty. - - If ``num_bytes`` is not present, flushes all data currently in the SWO - buffer. - - Args: - self (JLink): the ``JLink`` instance - num_bytes (int): the number of bytes to flush - - Returns: - ``None`` - - Raises: - JLinkException: on error - """ - if num_bytes is None: - num_bytes = self.swo_num_bytes() - buf = ctypes.c_uint32(num_bytes) - res = self._dll.JLINKARM_SWO_Control(enums.JLinkSWOCommands.FLUSH, ctypes.byref(buf)) - if res < 0: - raise errors.JLinkException(res) - - @connection_required - def swo_speed_info(self): - """Retrieves information about the supported SWO speeds. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - A ``JLinkSWOSpeedInfo`` instance describing the target's supported - SWO speeds. - - Raises: - JLinkException: on error - """ - info = structs.JLinkSWOSpeedInfo() - res = self._dll.JLINKARM_SWO_Control(enums.JLinkSWOCommands.GET_SPEED_INFO, ctypes.byref(info)) - if res < 0: - raise errors.JLinkException(res) - return info - - @connection_required - def swo_num_bytes(self): - """Retrives the number of bytes in the SWO buffer. - - Args: - self (JLink): the ``JLink`` instance - - Returns: - Number of bytes in the SWO buffer. - - Raises: - JLinkException: on error - """ - res = self._dll.JLINKARM_SWO_Control(enums.JLinkSWOCommands.GET_NUM_BYTES, 0) - if res < 0: - raise errors.JLinkException(res) - return res - - @connection_required - def swo_set_host_buffer_size(self, buf_size): - """Sets the size of the buffer used by the host to collect SWO data. - - Args: - self (JLink): the ``JLink`` instance - buf_size (int): the new size of the host buffer - - Returns: - ``None`` - - Raises: - JLinkException: on error - """ - buf = ctypes.c_uint32(buf_size) - res = self._dll.JLINKARM_SWO_Control(enums.JLinkSWOCommands.SET_BUFFERSIZE_HOST, ctypes.byref(buf)) - if res < 0: - raise errors.JLinkException(res) - - @connection_required - def swo_set_emu_buffer_size(self, buf_size): - """Sets the size of the buffer used by the J-Link to collect SWO data. - - Args: - self (JLink): the ``JLink`` instance - buf_size (int): the new size of the emulator buffer - - Returns: - ``None`` - - Raises: - JLinkException: on error - """ - buf = ctypes.c_uint32(buf_size) - res = self._dll.JLINKARM_SWO_Control(enums.JLinkSWOCommands.SET_BUFFERSIZE_EMU, ctypes.byref(buf)) - if res < 0: - raise errors.JLinkException(res) - - @connection_required - def swo_supported_speeds(self, cpu_speed, num_speeds=3): - """Retrives a list of SWO speeds supported by both the target and the - connected J-Link. - - The supported speeds are returned in order from highest to lowest. - - Args: - self (JLink): the ``JLink`` instance - cpu_speed (int): the target's CPU speed in Hz - num_speeds (int): the number of compatible speeds to return - - Returns: - A list of compatible SWO speeds in Hz in order from highest to lowest. - """ - buf_size = num_speeds - buf = (ctypes.c_uint32 * buf_size)() - res = self._dll.JLINKARM_SWO_GetCompatibleSpeeds(cpu_speed, 0, buf, buf_size) - if res < 0: - raise errors.JLinkException(res) - return list(buf)[:res] - - @connection_required - def swo_read(self, offset, num_bytes, remove=False): - """Reads data from the SWO buffer. - - The data read is not automatically removed from the SWO buffer after - reading unless ``remove`` is ``True``. Otherwise the callee must - explicitly remove the data by calling ``.swo_flush()``. - - Args: - self (JLink): the ``JLink`` instance - offset (int): offset of first byte to be retrieved - num_bytes (int): number of bytes to read - remove (bool): if data should be removed from buffer after read - - Returns: - A list of bytes read from the SWO buffer. - """ - buf_size = ctypes.c_uint32(num_bytes) - buf = ctypes.c_uint8 * num_bytes(0) - self._dll.JLINKARM_SWO_Read(buf, offset, ctypes.byref(buf_size)) - buf_size = buf_size.value - if remove: - self.swo_flush(buf_size) - return list(buf)[:buf_size] - - @connection_required - def swo_read_stimulus(self, port, num_bytes): - """Reads the printable data via SWO. - - This method reads SWO for one stimulus port, which is all printable - data. - - Note: - Stimulus port ``0`` is used for ``printf`` debugging. - - Args: - self (JLink): the ``JLink`` instance - port (int): the stimulus port to read from, ``0 - 31`` - num_bytes (int): number of bytes to read - - Returns: - A list of bytes read via SWO. - - Raises: - ValueError: if ``port < 0`` or ``port > 31`` - """ - if port < 0 or port > 31: - raise ValueError('Invalid port number: %s' % port) - buf_size = num_bytes - buf = (ctypes.c_uint8 * buf_size)() - bytes_read = self._dll.JLINKARM_SWO_ReadStimulus(port, buf, buf_size) - return list(buf)[:bytes_read] - - @open_required - def rtt_start(self): - """Starts RTT processing, including background read of target data. - Args: - self (JLink): the ``JLink`` instance - - Raises: - JLinkRTTException if the underlying JLINK_RTTERMINAL_Control call fails. - """ - self.rtt_control(enums.JLinkRTTCommand.START, None) - - @open_required - def rtt_stop(self): - """Stops RTT on the J-Link and host side. - Args: - self (JLink): the ``JLink`` instance - - Raises: - JLinkRTTException if the underlying JLINK_RTTERMINAL_Control call fails. - """ - self.rtt_control(enums.JLinkRTTCommand.STOP, None) - - @open_required - def rtt_get_num_up_buffers(self): - """After starting RTT, get the current number of up buffers. - Args: - self (JLink): the ``JLink`` instance - - Returns: - The number of configured up buffers on the target. - - Raises: - JLinkRTTException if the underlying JLINK_RTTERMINAL_Control call fails. - """ - cmd = enums.JLinkRTTCommand.GETNUMBUF - dir = ctypes.c_int(enums.JLinkRTTDirection.UP) - return self.rtt_control(cmd, dir) - - @open_required - def rtt_get_num_down_buffers(self): - """After starting RTT, get the current number of down buffers. - Args: - self (JLink): the ``JLink`` instance - - Returns: - The number of configured down buffers on the target. - - Raises: - JLinkRTTException if the underlying JLINK_RTTERMINAL_Control call fails. - """ - cmd = enums.JLinkRTTCommand.GETNUMBUF - dir = ctypes.c_int(enums.JLinkRTTDirection.DOWN) - return self.rtt_control(cmd, dir) - - @open_required - def rtt_read(self, buffer_index, num_bytes): - """Reads data from the RTT buffer. - - This method will read at most num_bytes bytes from the specified - RTT buffer. The data is automatically removed from the RTT buffer. - If there are not num_bytes bytes waiting in the RTT buffer, the - entire contents of the RTT buffer will be read. - - Args: - self (JLink): the ``JLink`` instance - buffer_index (int): the index of the RTT buffer to read from - num_bytes (int): the maximum number of bytes to read - - Returns: - A list of bytes read from RTT. - - Raises: - JLinkRTTException if the underlying JLINK_RTTERMINAL_Read call fails. - """ - buf = (ctypes.c_ubyte * num_bytes)() - bytes_read = self._dll.JLINK_RTTERMINAL_Read(buffer_index, buf, num_bytes) - if bytes_read < 0: - raise errors.JLinkRTTException(bytes_read) - return list(buf)[:bytes_read] - - @open_required - def rtt_write(self, buffer_index, data): - """Writes data to the RTT buffer. - - This method will write at most len(data) bytes to the specified RTT - buffer. - - Args: - self (JLink): the ``JLink`` instance - buffer_index (int): the index of the RTT buffer to write to - data (list): the list of bytes to write to the RTT buffer - - Returns: - The number of bytes successfully written to the RTT buffer. - - Raises: - JLinkRTTException if the underlying JLINK_RTTERMINAL_Write call fails. - """ - buf_size = len(data) - buf = (ctypes.c_ubyte * buf_size)(*bytearray(data)) - bytes_written = self._dll.JLINK_RTTERMINAL_Write(buffer_index, buf, buf_size) - if bytes_written < 0: - raise errors.JLinkRTTException(bytes_written) - return bytes_written - - @open_required - def rtt_control(self, command, config): - """Issues an RTT Control command. - - All RTT control is done through a single API call which expects - specifically laid-out configuration structures. - - Args: - self (JLink): the ``JLink`` instance - command (int): the command to issue (see enums.JLinkRTTCommand) - config (ctypes type): the configuration to pass by reference. - - Returns: - An integer containing the result of the command. - """ - config_byref = ctypes.byref(config) if config is not None else None - res = self._dll.JLINK_RTTERMINAL_Control(command, config_byref) - if res < 0: - raise errors.JLinkRTTException(res) - return res - - @connection_required - def cp15_present(self): - """Returns whether target has CP15 co-processor. - - Returns: - ``True`` if the target has CP15 co-processor, otherwise ``False``. - """ - result = False - if self._dll.JLINKARM_CP15_IsPresent() != 0: - result = True - return result - - @open_required - def cp15_register_read(self, cr_n, op_1, cr_m, op_2): - """Reads value from specified coprocessor register. - - Args: - cr_n (int): CRn value - op_1 (int): Op1 value - cr_m (int): CRm value - op_2 (int): Op2 value - - Returns: - An integer containing the value of coprocessor register - - Raises: - JLinkException: on error - """ - value = ctypes.c_uint32(0) - p_value = ctypes.pointer(value) - res = self._dll.JLINKARM_CP15_ReadEx(cr_n, cr_m, op_1, op_2, p_value) - if res != 0: - raise errors.JLinkException(res) - else: - value = value.value - return value - - @open_required - def cp15_register_write(self, cr_n, op_1, cr_m, op_2, value): - """Writes value to specified coprocessor register. - - Args: - cr_n (int): CRn value - op_1 (int): Op1 value - cr_m (int): CRm value - op_2 (int): Op2 value - value (int): value to write - - Returns: - An integer containing the result of the command - - Raises: - JLinkException: on error - """ - res = self._dll.JLINKARM_CP15_WriteEx(cr_n, cr_m, op_1, op_2, value) - if res != 0: - raise errors.JLinkException(res) - return res -# okay decompiling ./pylink/jlink.pyc diff --git a/pylink/jlock.py b/pylink/jlock.py deleted file mode 100644 index 4a2ce22..0000000 --- a/pylink/jlock.py +++ /dev/null @@ -1,114 +0,0 @@ -# decompyle3 version 3.9.0 -# Python bytecode version base 3.7.0 (3394) -# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) -# [GCC 12.2.1 20220924] -# Embedded file name: pylink/jlock.py -import psutil, errno, tempfile, os - -class JLock(object): - __doc__ = 'Lockfile for accessing a particular J-Link.\n\n The J-Link SDK does not prevent accessing the same J-Link multiple times\n from the same process or multiple processes. As a result, a user can\n have the same J-Link being accessed by multiple processes. This class\n provides an interface to a lock-file like structure for the physical\n J-Links to ensure that any instance of a ``JLink`` with an open emulator\n connection will be the only one accessing that emulator.\n\n This class uses a PID-style lockfile to allow acquiring of the lockfile in\n the instances where the lockfile exists, but the process which created it\n is no longer running.\n\n To share the same emulator connection between multiple threads, processes,\n or functions, a single instance of a ``JLink`` should be created and passed\n between the threads and processes.\n\n Attributes:\n name: the name of the lockfile.\n path: full path to the lockfile.\n fd: file description of the lockfile.\n acquired: boolean indicating if the lockfile lock has been acquired.\n ' - SERIAL_NAME_FMT = '.pylink-usb-{}.lck' - IPADDR_NAME_FMT = '.pylink-ip-{}.lck' - - def __init__(self, serial_no): - """Creates an instance of a ``JLock`` and populates the name. - - Note: - This method may fail if there is no temporary directory in which to - have the lockfile placed. - - Args: - self (JLock): the ``JLock`` instance - serial_no (int): the serial number of the J-Link - - Returns: - ``None`` - """ - self.name = self.SERIAL_NAME_FMT.format(serial_no) - self.acquired = False - self.fd = None - self.path = None - self.path = os.path.join(tempfile.tempdir, self.name) - - def __del__(self): - """Cleans up the lockfile instance if it was acquired. - - Args: - self (JLock): the ``JLock`` instance - - Returns: - ``None`` - """ - self.release() - - def acquire(self): - """Attempts to acquire a lock for the J-Link lockfile. - - If the lockfile exists but does not correspond to an active process, - the lockfile is first removed, before an attempt is made to acquire it. - - Args: - self (Jlock): the ``JLock`` instance - - Returns: - ``True`` if the lock was acquired, otherwise ``False``. - - Raises: - OSError: on file errors. - """ - if os.path.exists(self.path): - try: - pid = None - with open(self.path, 'r') as f: - line = f.readline().strip() - pid = int(line) - if not psutil.pid_exists(pid): - os.remove(self.path) - except ValueError as e: - try: - os.remove(self.path) - finally: - e = None - del e - - except IOError as e: - try: - pass - finally: - e = None - del e - - try: - self.fd = os.open(self.path, os.O_CREAT | os.O_EXCL | os.O_RDWR) - to_write = '%s%s' % (os.getpid(), os.linesep) - os.write(self.fd, to_write.encode()) - except OSError as e: - try: - if not os.path.exists(self.path): - raise - return False - finally: - e = None - del e - - self.acquired = True - return True - - def release(self): - """Cleans up the lockfile if it was acquired. - - Args: - self (JLock): the ``JLock`` instance - - Returns: - ``False`` if the lock was not released or the lock is not acquired, - otherwise ``True``. - """ - if not self.acquired: - return False - os.close(self.fd) - if os.path.exists(self.path): - os.remove(self.path) - self.acquired = False - return True -# okay decompiling ./pylink/jlock.pyc diff --git a/pylink/library.py b/pylink/library.py deleted file mode 100644 index 2994707..0000000 --- a/pylink/library.py +++ /dev/null @@ -1,346 +0,0 @@ -# decompyle3 version 3.9.0 -# Python bytecode version base 3.7.0 (3394) -# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) -# [GCC 12.2.1 20220924] -# Embedded file name: pylink/library.py -from . import util -import ctypes -import ctypes.util as ctypes_util -import os, sys, tempfile - -class Library(object): - __doc__ = 'Wrapper to provide easy access to loading the J-Link SDK DLL.\n\n This class provides a convenience for finding and loading the J-Link DLL\n across multiple platforms, and accounting for the inconsistencies between\n Windows and nix-based platforms.\n\n Attributes:\n _standard_calls_: list of names of the methods for the API calls that\n must be converted to standard calling convention on the Windows\n platform.\n JLINK_SDK_NAME: name of the J-Link DLL on nix-based platforms.\n WINDOWS_JLINK_SDK_NAME: name of the J-Link DLL on Windows platforms.\n ' - _standard_calls_ = [ - 'JLINK_Configure', - 'JLINK_DownloadFile', - 'JLINK_GetAvailableLicense', - 'JLINK_GetPCode', - 'JLINK_PrintConfig', - 'JLINK_EraseChip', - 'JLINK_SPI_Transfer', - 'JLINK_GetpFunc', - 'JLINK_GetMemZones', - 'JLINK_ReadMemZonedEx', - 'JLINK_SetHookUnsecureDialog', - 'JLINK_WriteMemZonedEx', - 'JLINK_DIALOG_Configure', - 'JLINK_DIALOG_ConfigureEx', - 'JLINK_EMU_GPIO_GetProps', - 'JLINK_EMU_GPIO_GetState', - 'JLINK_EMU_GPIO_SetState', - 'JLINK_EMU_AddLicense', - 'JLINK_EMU_EraseLicenses', - 'JLINK_EMU_GetLicenses', - 'JLINK_HSS_GetCaps', - 'JLINK_HSS_Start', - 'JLINK_HSS_Stop', - 'JLINK_HSS_Read', - 'JLINK_POWERTRACE_Control', - 'JLINK_POWERTRACE_Read', - 'JLINK_RTTERMINAL_Control', - 'JLINK_RTTERMINAL_Read', - 'JLINK_RTTERMINAL_Write', - 'JLINK_STRACE_Config', - 'JLINK_STRACE_Control', - 'JLINK_STRACE_Read', - 'JLINK_STRACE_Start', - 'JLINK_STRACE_Stop', - 'JLINK_SWD_GetData', - 'JLINK_SWD_GetU8', - 'JLINK_SWD_GetU16', - 'JLINK_SWD_GetU32', - 'JLINK_SWD_StoreGetRaw', - 'JLINK_SWD_StoreRaw', - 'JLINK_SWD_SyncBits', - 'JLINK_SWD_SyncBytes', - 'JLINK_SetFlashProgProgressCallback'] - JLINK_SDK_NAME = 'libjlinkarm' - WINDOWS_32_JLINK_SDK_NAME = 'JLinkARM' - WINDOWS_64_JLINK_SDK_NAME = 'JLink_x64' - - @classmethod - def get_appropriate_windows_sdk_name(cls): - """Returns the appropriate JLink SDK library name on Windows depending - on 32bit or 64bit Python variant. - - SEGGER delivers two variants of their dynamic library on Windows: - - ``JLinkARM.dll`` for 32-bit platform - - ``JLink_x64.dll`` for 64-bit platform - - Args: - cls (Library): the ``Library`` class - - Returns: - The name of the library depending on the platform this module is run on. - - """ - if sys.maxsize == 9223372036854775807: - return Library.WINDOWS_64_JLINK_SDK_NAME - return Library.WINDOWS_32_JLINK_SDK_NAME - - @classmethod - def find_library_windows(cls): - r"""Loads the SEGGER DLL from the windows installation directory. - - On Windows, these are found either under: - - ``C:\Program Files\SEGGER\JLink`` - - ``C:\Program Files (x86)\SEGGER\JLink``. - - Args: - cls (Library): the ``Library`` class - - Returns: - The paths to the J-Link library files in the order that they are - found. - """ - dll = cls.get_appropriate_windows_sdk_name() + '.dll' - root = 'C:\\' - for d in os.listdir(root): - dir_path = os.path.join(root, d) - if d.startswith('Program Files'): - if os.path.isdir(dir_path): - dir_path = os.path.join(dir_path, 'SEGGER') - if not os.path.isdir(dir_path): - continue - else: - ds = filter(lambda x: x.startswith('JLink') -, os.listdir(dir_path)) - for jlink_dir in ds: - lib_path = os.path.join(dir_path, jlink_dir, dll) - if os.path.isfile(lib_path): - yield lib_path - - @classmethod - def find_library_linux(cls): - """Loads the SEGGER DLL from the root directory. - - On Linux, the SEGGER tools are installed under the ``/opt/SEGGER`` - directory with versioned directories having the suffix ``_VERSION``. - - Args: - cls (Library): the ``Library`` class - - Returns: - The paths to the J-Link library files in the order that they are - found. - """ - dll = Library.JLINK_SDK_NAME - root = os.path.join('/', 'opt', 'SEGGER') - for directory_name, subdirs, files in os.walk(root): - fnames = [] - x86_found = False - for f in files: - path = os.path.join(directory_name, f) - if os.path.isfile(path): - if f.startswith(dll): - fnames.append(f) - if '_x86' in path: - x86_found = True - - for fname in fnames: - fpath = os.path.join(directory_name, fname) - if util.is_os_64bit(): - if '_x86' not in fname: - yield fpath - else: - if x86_found: - if '_x86' in fname: - yield fpath - else: - yield fpath - - @classmethod - def find_library_darwin(cls): - r"""Loads the SEGGER DLL from the installed applications. - - This method accounts for the all the different ways in which the DLL - may be installed depending on the version of the DLL. Always uses - the first directory found. - - SEGGER's DLL is installed in one of three ways dependent on which - which version of the SEGGER tools are installed: - - ======== ============================================================ - Versions Directory - ======== ============================================================ - < 5.0.0 ``/Applications/SEGGER/JLink\ NUMBER`` - < 6.0.0 ``/Applications/SEGGER/JLink/libjlinkarm.major.minor.dylib`` - >= 6.0.0 ``/Applications/SEGGER/JLink/libjlinkarm`` - ======== ============================================================ - - Args: - cls (Library): the ``Library`` class - - Returns: - The path to the J-Link library files in the order they are found. - """ - dll = Library.JLINK_SDK_NAME - root = os.path.join('/', 'Applications', 'SEGGER') - if not os.path.isdir(root): - return - for d in os.listdir(root): - dir_path = os.path.join(root, d) - if os.path.isdir(dir_path): - if d.startswith('JLink'): - files = list((f for f in os.listdir(dir_path) if os.path.isfile(os.path.join(dir_path, f)))) - if dll + '.dylib' in files: - yield os.path.join(dir_path, dll + '.dylib') - else: - for f in files: - if f.startswith(dll): - yield os.path.join(dir_path, f) - - def __init__(self, dllpath=None): - """Initializes an instance of a ``Library``. - - Loads the default J-Link DLL if ``dllpath`` is ``None``, otherwise - loads the DLL specified by the given ``dllpath``. - - Args: - self (Library): the ``Library`` instance - dllpath (str): the DLL to load into the library - - Returns: - ``None`` - """ - self._lib = None - self._winlib = None - self._path = None - self._windows = sys.platform.startswith('win') - self._cygwin = sys.platform.startswith('cygwin') - self._temp = None - if self._windows or self._cygwin: - self._sdk = self.get_appropriate_windows_sdk_name() - else: - self._sdk = self.JLINK_SDK_NAME - if dllpath is not None: - self.load(dllpath) - else: - self.load_default() - - def __del__(self): - """Cleans up the temporary DLL file created when the lib was loaded. - - Args: - self (Library): the ``Library`` instance - - Returns: - ``None`` - """ - self.unload() - - def load_default(self): - """Loads the default J-Link SDK DLL. - - The default J-Link SDK is determined by first checking if ``ctypes`` - can find the DLL, then by searching the platform-specific paths. - - Args: - self (Library): the ``Library`` instance - - Returns: - ``True`` if the DLL was loaded, otherwise ``False``. - """ - path = ctypes_util.find_library(self._sdk) - if not path is None or self._windows or self._cygwin: - path = next(self.find_library_windows(), None) - else: - if sys.platform.startswith('linux'): - path = next(self.find_library_linux(), None) - else: - if sys.platform.startswith('darwin'): - path = next(self.find_library_darwin(), None) - if path is not None: - return self.load(path) - return False - - def load(self, path=None): - """Loads the specified DLL, if any, otherwise re-loads the current DLL. - - If ``path`` is specified, loads the DLL at the given ``path``, - otherwise re-loads the DLL currently specified by this library. - - Note: - This creates a temporary DLL file to use for the instance. This is - necessary to work around a limitation of the J-Link DLL in which - multiple J-Links cannot be accessed from the same process. - - Args: - self (Library): the ``Library`` instance - path (path): path to the DLL to load - - Returns: - ``True`` if library was loaded successfully. - - Raises: - OSError: if there is no J-LINK SDK DLL present at the path. - - See Also: - `J-Link Multi-session `_. - """ - self.unload() - self._path = path or self._path - if self._windows or self._cygwin: - suffix = '.dll' - else: - if sys.platform.startswith('darwin'): - suffix = '.dylib' - else: - suffix = '.so' - tf = tempfile.NamedTemporaryFile(delete=False, suffix=suffix) - with open(tf.name, 'wb') as outputfile: - with open(self._path, 'rb') as inputfile: - outputfile.write(inputfile.read()) - tf.close() - self._temp = tf - self._lib = ctypes.cdll.LoadLibrary(tf.name) - if self._windows: - self._winlib = ctypes.windll.LoadLibrary(tf.name) - for stdcall in self._standard_calls_: - if hasattr(self._winlib, stdcall): - setattr(self._lib, stdcall, getattr(self._winlib, stdcall)) - - return True - - def unload(self): - """Unloads the library's DLL if it has been loaded. - - This additionally cleans up the temporary DLL file that was created - when the library was loaded. - - Args: - self (Library): the ``Library`` instance - - Returns: - ``True`` if the DLL was unloaded, otherwise ``False``. - """ - unloaded = False - if self._lib is not None: - if self._winlib is not None: - ctypes.windll.kernel32.FreeLibrary.argtypes = ( - ctypes.c_void_p,) - ctypes.windll.kernel32.FreeLibrary(self._lib._handle) - ctypes.windll.kernel32.FreeLibrary(self._winlib._handle) - self._lib = None - self._winlib = None - unloaded = True - else: - del self._lib - self._lib = None - unloaded = True - if self._temp is not None: - os.remove(self._temp.name) - self._temp = None - return unloaded - - def dll(self): - """Returns the DLL for the underlying shared library. - - Args: - self (Library): the ``Library`` instance - - Returns: - A ``ctypes`` DLL instance if one was loaded, otherwise ``None``. - """ - return self._lib -# okay decompiling ./pylink/library.pyc diff --git a/pylink/registers.py b/pylink/registers.py deleted file mode 100644 index 02b6f6f..0000000 --- a/pylink/registers.py +++ /dev/null @@ -1,206 +0,0 @@ -# decompyle3 version 3.9.0 -# Python bytecode version base 3.7.0 (3394) -# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) -# [GCC 12.2.1 20220924] -# Embedded file name: pylink/registers.py -import ctypes - -class IDCodeRegisterBits(ctypes.LittleEndianStructure): - __doc__ = 'This class holds the different bit masks for the IDCode register.\n\n Attributes:\n valid: validity bit, should always be ``0``.\n manufactuer: the JEDEC Manufacturer ID.\n part_no: the part number defined by the manufacturer.\n version_code: the version code.\n ' - _fields_ = [ - ( - 'valid', ctypes.c_uint32, 1), - ( - 'manufacturer', ctypes.c_uint32, 11), - ( - 'part_no', ctypes.c_uint32, 16), - ( - 'version_code', ctypes.c_uint32, 4)] - - -class IDCodeRegisterFlags(ctypes.Union): - __doc__ = 'Mask for the IDCode register bits.\n\n Attributes:\n value: the value stored in the mask.\n ' - _anonymous_ = ('bit', ) - _fields_ = [ - ( - 'bit', IDCodeRegisterBits), - ( - 'value', ctypes.c_uint32)] - - -class AbortRegisterBits(ctypes.LittleEndianStructure): - __doc__ = 'This class holds the different bit mask for the Abort Register.\n\n Attributes:\n DAPABORT: write ``1`` to trigger a DAP abort.\n STKCMPCLR: write ``1`` to clear the ``STICKYCMP`` sticky compare flag\n (only supported on SW-DP).\n STKERRCLR: write ``1`` to clear the ``STICKYERR`` sticky error flag\n (only supported on SW-DP).\n WDERRCLR: write ``1`` to clear the ``WDATAERR`` write data error flag\n (only supported on SW-DP).\n ORUNERRCLR: write ``1`` to clear the ``STICKYORUN`` overrun error flag\n (only supported on SW-DP).\n ' - _fields_ = [ - ( - 'DAPABORT', ctypes.c_uint32, 1), - ( - 'STKCMPCLR', ctypes.c_uint32, 1), - ( - 'STKERRCLR', ctypes.c_uint32, 1), - ( - 'WDERRCLR', ctypes.c_uint32, 1), - ( - 'ORUNERRCLR', ctypes.c_uint32, 1), - ( - 'RESERVED', ctypes.c_uint32, 27)] - - -class AbortRegisterFlags(ctypes.Union): - __doc__ = 'Mask for the abort register bits.\n\n Attributes:\n value: the value stored in the mask.\n ' - _anonymous_ = ('bit', ) - _fields_ = [ - ( - 'bit', AbortRegisterBits), - ( - 'value', ctypes.c_uint32)] - - -class ControlStatusRegisterBits(ctypes.LittleEndianStructure): - __doc__ = 'This class holds the different bit masks for the DP Control / Status\n Register bit assignments.\n\n Attributes:\n ORUNDETECT: if set, enables overrun detection.\n STICKYORUN: if overrun is enabled, is set when overrun occurs.\n TRNMODE: transfer mode for acess port operations.\n STICKYCMP: is set when a match occurs on a pushed compare or verify\n operation.\n STICKYERR: is set when an error is returned by an access port\n transaction.\n READOK: is set when the response to a previous access port or ``RDBUFF``\n was ``OK``.\n WDATAERR: set to ``1`` if a Write Data Error occurs.\n MASKLANE: bytes to be masked in pushed compare and verify operations.\n TRNCNT: transaction counter.\n RESERVED: reserved.\n CDBGRSTREQ: debug reset request.\n CDBGRSTACK: debug reset acknowledge.\n CDBGPWRUPREQ: debug power-up request.\n CDBGPWRUPACK: debug power-up acknowledge.\n CSYSPWRUPREQ: system power-up request\n CSYSPWRUPACK: system power-up acknowledge.\n\n See also:\n See the ARM documentation on the significance of these masks\n `here `_.\n ' - _fields_ = [ - ( - 'ORUNDETECT', ctypes.c_uint32, 1), - ( - 'STICKYORUN', ctypes.c_uint32, 1), - ( - 'TRNMODE', ctypes.c_uint32, 2), - ( - 'STICKYCMP', ctypes.c_uint32, 1), - ( - 'STICKYERR', ctypes.c_uint32, 1), - ( - 'READOK', ctypes.c_uint32, 1), - ( - 'WDATAERR', ctypes.c_uint32, 1), - ( - 'MASKLANE', ctypes.c_uint32, 4), - ( - 'TRNCNT', ctypes.c_uint32, 12), - ( - 'RESERVED', ctypes.c_uint32, 2), - ( - 'CDBGRSTREQ', ctypes.c_uint32, 1), - ( - 'CDBGRSTACK', ctypes.c_uint32, 1), - ( - 'CDBGPWRUPREQ', ctypes.c_uint32, 1), - ( - 'CDBGPWRUPACK', ctypes.c_uint32, 1), - ( - 'CSYSPWRUPREQ', ctypes.c_uint32, 1), - ( - 'CSYSPWRUPACK', ctypes.c_uint32, 1)] - - -class ControlStatusRegisterFlags(ctypes.Union): - __doc__ = 'Mask for the control/status register bits.\n\n Attributes:\n value: the value stored in the mask.\n ' - _anonymous_ = ('bit', ) - _fields_ = [ - ( - 'bit', ControlStatusRegisterBits), - ( - 'value', ctypes.c_uint32)] - - -class SelectRegisterBits(ctypes.LittleEndianStructure): - __doc__ = 'This class holds the different bit masks for the AP Select Register.\n\n Attributes:\n CTRLSEL: SW-DP debug port address bank select.\n RESERVED_A: reserved.\n APBANKSEL: selects the active four-word register window on the current\n access port.\n RESERVED_B: reserved.\n APSEL: selects the current access port.\n ' - _fields_ = [ - ( - 'CTRLSEL', ctypes.c_uint32, 1), - ( - 'RESERVED_A', ctypes.c_uint32, 3), - ( - 'APBANKSEL', ctypes.c_uint32, 4), - ( - 'RESERVED_B', ctypes.c_uint32, 16), - ( - 'APSEL', ctypes.c_uint32, 8)] - - -class SelectRegisterFlags(ctypes.Union): - __doc__ = 'Mask for the select register bits.\n\n Attributes:\n value: the value stored in the mask.\n ' - _anonymous_ = ('bit', ) - _fields_ = [ - ( - 'bit', SelectRegisterBits), - ( - 'value', ctypes.c_uint32)] - - -class MDMAPControlRegisterBits(ctypes.LittleEndianStructure): - __doc__ = 'This class holds the different bit masks for the MDM-AP Control\n Register.\n\n Attributes:\n flash_mass_erase: set to cause a mass erase, this is cleared\n automatically when a mass erase finishes.\n debug_disable: set to disable debug, clear to allow debug.\n debug_request: set to force the core to halt.\n sys_reset_request: set to force a system reset.\n core_hold_reset: set to suspend the core in reset at the end of reset\n sequencing.\n VLLDBGREQ: set to hold the system in reset after the next recovery from\n VLLSx (Very Low Leakage Stop).\n VLLDBGACK: set to release a system held in reset following a VLLSx\n (Very Low Leakage Stop) recovery.\n VLLSTATACK: set to acknowledge that the DAP LLS (Low Leakage Stop) and\n VLLS (Very Low Leakage Stop) status bits have read.\n ' - _fields_ = [ - ( - 'flash_mass_erase', ctypes.c_uint8, 1), - ( - 'debug_disable', ctypes.c_uint8, 1), - ( - 'debug_request', ctypes.c_uint8, 1), - ( - 'sys_reset_request', ctypes.c_uint8, 1), - ( - 'core_hold_reset', ctypes.c_uint8, 1), - ( - 'VLLDBGREQ', ctypes.c_uint8, 1), - ( - 'VLLDBGACK', ctypes.c_uint8, 1), - ( - 'VLLSTATACK', ctypes.c_uint8, 1)] - - -class MDMAPControlRegisterFlags(ctypes.Union): - __doc__ = 'Mask for the MDM-AP control register bits.\n\n Attributes:\n value: the value stored in the mask.\n ' - _anonymous_ = ('bit', ) - _fields_ = [ - ( - 'bit', MDMAPControlRegisterBits), - ( - 'value', ctypes.c_uint8)] - - -class MDMAPStatusRegisterBits(ctypes.LittleEndianStructure): - __doc__ = 'Holds the bit masks for the MDM-AP Status Register.\n\n Attributes:\n flash_mass_erase_ack: cleared after a system reset, indicates that a\n flash mass erase was acknowledged.\n flash_ready: indicates that flash has been initialized and can be\n configured.\n system_security: if set, system is secure and debugger cannot access the\n memory or system bus.\n system_reset: ``1`` if system is in reset, otherwise ``0``.\n mass_erase_enabled: ``1`` if MCU can be mass erased, otherwise ``0``.\n low_power_enabled: ``1`` if low power stop mode is enabled, otherwise ``0``.\n very_low_power_mode: ``1`` if device is in very low power mode.\n LLSMODEEXIT: indicates an exit from LLS mode has occurred.\n VLLSxMODEEXIT: indicates an exit from VLLSx mode has occured.\n core_halted; indicates core has entered debug halt mode.\n core_deep_sleep: indicates core has entered a low power mode.\n core_sleeping: indicates the core has entered a low power mode.\n\n Note:\n if ``core_sleeping & !core_deep_sleep``, then the core is in VLPW (very\n low power wait) mode, otherwise if ``core_sleeping & core_deep_sleep``,\n then it is in VLPS (very low power stop) mode.\n ' - _fields_ = [ - ( - 'flash_mass_erase_ack', ctypes.c_uint32, 1), - ( - 'flash_ready', ctypes.c_uint32, 1), - ( - 'system_security', ctypes.c_uint32, 1), - ( - 'system_reset', ctypes.c_uint32, 1), - ( - 'RESERVED_A', ctypes.c_uint32, 1), - ( - 'mass_erase_enabled', ctypes.c_uint32, 1), - ( - 'backdoor_access_enabled', ctypes.c_uint32, 1), - ( - 'low_power_enabled', ctypes.c_uint32, 1), - ( - 'very_low_power_mode', ctypes.c_uint32, 1), - ( - 'LLSMODEEXIT', ctypes.c_uint32, 1), - ( - 'VLLSxMODEEXIT', ctypes.c_uint32, 1), - ( - 'RESERVED_B', ctypes.c_uint32, 5), - ( - 'core_halted', ctypes.c_uint32, 1), - ( - 'core_deep_sleep', ctypes.c_uint32, 1), - ( - 'core_sleeping', ctypes.c_uint32, 1), - ( - 'RESERVED_C', ctypes.c_uint32, 13)] - - -class MDMAPStatusRegisterFlags(ctypes.Union): - __doc__ = 'Mask for the MDM-AP status register bits.\n\n Attributes:\n value: the value stored in the mask.\n ' - _anonymous_ = ('bit', ) - _fields_ = [ - ( - 'bit', MDMAPStatusRegisterBits), - ( - 'value', ctypes.c_uint32)] -# okay decompiling ./pylink/registers.pyc diff --git a/pylink/structs.py b/pylink/structs.py deleted file mode 100644 index 6dd8835..0000000 --- a/pylink/structs.py +++ /dev/null @@ -1,907 +0,0 @@ -# decompyle3 version 3.9.0 -# Python bytecode version base 3.7.0 (3394) -# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) -# [GCC 12.2.1 20220924] -# Embedded file name: pylink/structs.py -from . import enums -import ctypes - -class JLinkConnectInfo(ctypes.Structure): - __doc__ = 'J-Link connection info structure.\n\n Attributes:\n SerialNumber: J-Link serial number.\n Connection: type of connection (e.g. ``enums.JLinkHost.USB``)\n USBAddr: USB address if connected via USB.\n aIPAddr: IP address if connected via IP.\n Time: Time period (ms) after which UDP discover answer was received.\n Time_us: Time period (uS) after which UDP discover answer was received.\n HWVersion: Hardware version of J-Link, if connected via IP.\n abMACAddr: MAC Address, if connected via IP.\n acProduct: Product name, if connected via IP.\n acNickname: Nickname, if connected via IP.\n acFWString: Firmware string, if connected via IP.\n IsDHCPAssignedIP: Is IP address reception via DHCP.\n IsDHCPAssignedIPIsValid: True if connected via IP.\n NumIPConnections: Number of IP connections currently established.\n NumIPConnectionsIsValid: True if connected via IP.\n aPadding: Bytes reserved for future use.\n ' - _fields_ = [ - ( - 'SerialNumber', ctypes.c_uint32), - ( - 'Connection', ctypes.c_ubyte), - ( - 'USBAddr', ctypes.c_uint32), - ( - 'aIPAddr', ctypes.c_uint8 * 16), - ( - 'Time', ctypes.c_int), - ( - 'Time_us', ctypes.c_uint64), - ( - 'HWVersion', ctypes.c_uint32), - ( - 'abMACAddr', ctypes.c_uint8 * 6), - ( - 'acProduct', ctypes.c_char * 32), - ( - 'acNickname', ctypes.c_char * 32), - ( - 'acFWString', ctypes.c_char * 112), - ( - 'IsDHCPAssignedIP', ctypes.c_char), - ( - 'IsDHCPAssignedIPIsValid', ctypes.c_char), - ( - 'NumIPConnections', ctypes.c_char), - ( - 'NumIPConnectionsIsValid', ctypes.c_char), - ( - 'aPadding', ctypes.c_uint8 * 34)] - - def __repr__(self): - """Returns a representation of this class. - - Args: - self (JLinkConnectInfo): the ``JlinkConnectInfo`` instance - - Returns: - String representation of the class. - """ - return 'JLinkConnectInfo(%s)' % self.__str__() - - def __str__(self): - """Returns a string representation of the connection info. - - Args: - self (JLinkConnectInfo): the ``JLinkConnectInfo`` instance - - Returns: - String specifying the product, its serial number, and the type of - connection that it has (one of USB or IP). - """ - conn = 'USB' if self.Connection == 1 else 'IP' - return '%s ' % (self.acProduct.decode(), self.SerialNumber, conn) - - -class JLinkFlashArea(ctypes.Structure): - __doc__ = 'Definition for a region of Flash.\n\n Attributes:\n Addr: address where the flash area starts.\n Size: size of the flash area.\n ' - _fields_ = [ - ( - 'Addr', ctypes.c_uint32), - ( - 'Size', ctypes.c_uint32)] - - def __repr__(self): - """Returns a representation of the instance. - - Args: - self (FlashArea): the ``FlashArea`` instance - - Returns: - String representation of the Flash Area. - """ - return '%s(%s)' % (self.__class__.__name__, self.__str__()) - - def __str__(self): - """Returns a string representation of the instance. - - Args: - self (FlashArea): the ``FlashArea`` instance - - Returns: - String specifying address of flash region, and its size. - """ - return 'Address = 0x%x, Size = %s' % (self.Addr, self.Size) - - -class JLinkRAMArea(JLinkFlashArea): - __doc__ = 'Definition for a region of RAM.\n\n Attributes:\n Addr: address where the flash area starts.\n Size: size of the flash area.\n ' - - -class JLinkDeviceInfo(ctypes.Structure): - __doc__ = 'J-Link device information.\n\n This structure is used to represent a device that is supported by the\n J-Link.\n\n Attributes:\n SizeOfStruct: Size of the struct (DO NOT CHANGE).\n sName: name of the device.\n CoreId: core identifier of the device.\n FlashAddr: base address of the internal flash of the device.\n RAMAddr: base address of the internal RAM of the device.\n EndianMode: the endian mode of the device (0 -> only little endian,\n 1 -> only big endian, 2 -> both).\n FlashSize: total flash size in bytes.\n RAMSize: total RAM size in bytes.\n sManu: device manufacturer.\n aFlashArea: a list of ``JLinkFlashArea`` instances.\n aRamArea: a list of ``JLinkRAMArea`` instances.\n Core: CPU core.\n ' - _fields_ = [ - ( - 'SizeofStruct', ctypes.c_uint32), - ( - 'sName', ctypes.POINTER(ctypes.c_char)), - ( - 'CoreId', ctypes.c_uint32), - ( - 'FlashAddr', ctypes.c_uint32), - ( - 'RAMAddr', ctypes.c_uint32), - ( - 'EndianMode', ctypes.c_char), - ( - 'FlashSize', ctypes.c_uint32), - ( - 'RAMSize', ctypes.c_uint32), - ( - 'sManu', ctypes.POINTER(ctypes.c_char)), - ( - 'aFlashArea', JLinkFlashArea * 32), - ( - 'aRAMArea', JLinkRAMArea * 32), - ( - 'Core', ctypes.c_uint32)] - - def __init__(self, *args, **kwargs): - (super(JLinkDeviceInfo, self).__init__)(*args, **kwargs) - self.SizeofStruct = ctypes.sizeof(self) - - def __repr__(self): - """Returns a representation of this instance. - - Args: - self (JLinkDeviceInfo): the ``JLinkDeviceInfo`` instance - - Returns: - Returns a string representation of the instance. - """ - return 'JLinkDeviceInfo(%s)' % self.__str__() - - def __str__(self): - """Returns a string representation of this instance. - - Args: - self (JLinkDeviceInfo): the ``JLinkDeviceInfo`` instance - - Returns: - Returns a string specifying the device name, core, and manufacturer. - """ - manu = self.manufacturer - return '%s ' % (self.name, self.Core, manu) - - @property - def name(self): - """Returns the name of the device. - - Args: - self (JLinkDeviceInfo): the ``JLinkDeviceInfo`` instance - - Returns: - Device name. - """ - return ctypes.cast(self.sName, ctypes.c_char_p).value.decode() - - @property - def manufacturer(self): - """Returns the name of the manufacturer of the device. - - Args: - self (JLinkDeviceInfo): the ``JLinkDeviceInfo`` instance - - Returns: - Manufacturer name. - """ - buf = ctypes.cast(self.sManu, ctypes.c_char_p).value - if buf: - return buf.decode() - - -class JLinkHardwareStatus(ctypes.Structure): - __doc__ = 'Definition for the hardware status information for a J-Link.\n\n Attributes:\n VTarget: target supply voltage.\n tck: measured state of TCK pin.\n tdi: measured state of TDI pin.\n tdo: measured state of TDO pin.\n tms: measured state of TMS pin.\n tres: measured state of TRES pin.\n trst: measured state of TRST pin.\n ' - _fields_ = [ - ( - 'VTarget', ctypes.c_uint16), - ( - 'tck', ctypes.c_uint8), - ( - 'tdi', ctypes.c_uint8), - ( - 'tdo', ctypes.c_uint8), - ( - 'tms', ctypes.c_uint8), - ( - 'tres', ctypes.c_uint8), - ( - 'trst', ctypes.c_uint8)] - - def __repr__(self): - """Returns a string representation of the instance. - - Args: - self (JLinkHardwareStatus): the ``JlinkHardwareStatus`` instance - - Returns: - String representation of the instance. - """ - return '%s(VTarget=%dmV)' % (self.__class__.__name__, self.voltage) - - @property - def voltage(self): - """Returns the target supply voltage. - - This is an alias for ``.VTarget``. - - Args: - self (JLInkHardwareStatus): the ``JLinkHardwareStatus`` instance - - Returns: - Target supply voltage as an integer. - """ - return self.VTarget - - -class JLinkGPIODescriptor(ctypes.Structure): - __doc__ = 'Definition for the structure that details the name and capabilities of a\n user-controllable GPIO.\n\n Attributes:\n acName: name of the GPIO.\n Caps: bitfield of capabilities.\n ' - _fields_ = [ - ( - 'acName', ctypes.c_char * 32), - ( - 'Caps', ctypes.c_uint32)] - - def __repr__(self): - """Returns a string representation of the instance. - - Args: - self (JLinkGPIODescriptor): the ``JLinkGPIODescriptor`` instance - - Returns: - String representation of the instance. - """ - return '%s(%s)' % (self.__class__.__name__, self.__str__()) - - def __str__(self): - """Returns the GPIO name. - - Args: - self (JLinkGPIODescriptor): the ``JLInkGPIODescriptor`` instance - - Returns: - GPIO name. - """ - return self.acName.decode() - - -class JLinkMemoryZone(ctypes.Structure): - __doc__ = 'Represents a CPU memory zone.\n\n Attributes:\n sName: initials of the memory zone.\n sDesc: name of the memory zone.\n VirtAddr: start address of the virtual address space of the memory zone.\n abDummy: reserved for future use.\n ' - _fields_ = [ - ( - 'sName', ctypes.c_char_p), - ( - 'sDesc', ctypes.c_char_p), - ( - 'VirtAddr', ctypes.c_uint64), - ( - 'abDummy', ctypes.c_uint8 * 16)] - - def __repr__(self): - """Returns a string representation of the instance - - Args: - self: the ``JLinkMemoryZone`` instance - - Returns: - String representation of the instance. - """ - return '%s(%s)' % (self.__class__.__name__, self.__str__()) - - def __str__(self): - """Returns a formatted string describing the memory zone. - - Args: - self: the ``JLinkMemoryZone`` instance - - Returns: - String representation of the memory zone. - """ - return '%s ' % (self.sName, self.sDesc, self.VirtAddr) - - @property - def name(self): - """Alias for the memory zone name. - - Args: - self (JLinkMemoryZone): the ``JLinkMemoryZone`` instance - - Returns: - The memory zone name. - """ - return self.sName - - -class JLinkSpeedInfo(ctypes.Structure): - __doc__ = "Represents information about an emulator's supported speeds.\n\n The emulator can support all target interface speeds calculated by dividing\n the base frequency by atleast ``MinDiv``.\n\n Attributes:\n SizeOfStruct: the size of this structure.\n BaseFreq: Base frequency (in HZ) used to calculate supported speeds.\n MinDiv: minimum divider allowed to divide the base frequency.\n SupportAdaptive: ``1`` if emulator supports adaptive clocking, otherwise\n ``0``.\n " - _fields_ = [ - ( - 'SizeOfStruct', ctypes.c_uint32), - ( - 'BaseFreq', ctypes.c_uint32), - ( - 'MinDiv', ctypes.c_uint16), - ( - 'SupportAdaptive', ctypes.c_uint16)] - - def __init__(self): - super(JLinkSpeedInfo, self).__init__() - self.SizeOfStruct = ctypes.sizeof(self) - - def __repr__(self): - """Returns a string representation of the instance. - - Args: - self (JLinkSpeedInfo): the ``JLinkSpeedInfo`` instance - - Returns: - String representation of the instance. - """ - return self.__str__() - - def __str__(self): - """Returns this instance formatted as a string. - - Args: - self (JLinkSpeedInfo): the ``JLinkSpeedInfo`` instance - - Returns: - String formatted instance. - """ - return '%s(Freq=%sHz)' % (self.__class__.__name__, self.BaseFreq) - - -class JLinkSWOStartInfo(ctypes.Structure): - __doc__ = 'Represents configuration information for collecting Serial Wire Output\n (SWO) information.\n\n Attributes:\n SizeofStruct: size of the structure.\n Interface: the interface type used for SWO.\n Speed: the frequency used for SWO communication in Hz.\n\n Note:\n You should *never* change ``.SizeofStruct`` or ``.Interface``.\n ' - _fields_ = [ - ( - 'SizeofStruct', ctypes.c_uint32), - ( - 'Interface', ctypes.c_uint32), - ( - 'Speed', ctypes.c_uint32)] - - def __init__(self): - super(JLinkSWOStartInfo, self).__init__() - self.SizeofStruct = ctypes.sizeof(self) - self.Interface = enums.JLinkSWOInterfaces.UART - - def __repr__(self): - """Returns a representation of this instance. - - Args: - self (JLinkSWOStartInfo): the ``JLinkSWOStartInfo`` instance - - Returns: - The string representation of this instance. - """ - return self.__str__() - - def __str__(self): - """Returns a string representation of this instance. - - Args: - self (JLinkSWOStartInfo): the ``JLinkSWOStartInfo`` instance - - Returns: - The string representation of this instance. - """ - return '%s(Speed=%sHz)' % (self.__class__.__name__, self.Speed) - - -class JLinkSWOSpeedInfo(ctypes.Structure): - __doc__ = "Structure representing information about target's supported SWO speeds.\n\n To calculate the supported SWO speeds, the base frequency is taken and\n divide by a number in the range of ``[ MinDiv, MaxDiv ]``.\n\n Attributes:\n SizeofStruct: size of the structure.\n Interface: interface type for the speed information.\n BaseFreq: base frequency (Hz) used to calculate supported SWO speeds.\n MinDiv: minimum divider allowed to divide the base frequency.\n MaxDiv: maximum divider allowed to divide the base frequency.\n MinPrescale: minimum prescaler allowed to adjust the base frequency.\n MaxPrescale: maximum prescaler allowed to adjust the base frequency.\n\n Note:\n You should *never* change ``.SizeofStruct`` or ``.Interface``.\n " - _fields_ = [ - ( - 'SizeofStruct', ctypes.c_uint32), - ( - 'Interface', ctypes.c_uint32), - ( - 'BaseFreq', ctypes.c_uint32), - ( - 'MinDiv', ctypes.c_uint32), - ( - 'MaxDiv', ctypes.c_uint32), - ( - 'MinPrescale', ctypes.c_uint32), - ( - 'MaxPrescale', ctypes.c_uint32)] - - def __init__(self): - super(JLinkSWOSpeedInfo, self).__init__() - self.SizeofStruct = ctypes.sizeof(self) - self.Interface = enums.JLinkSWOInterfaces.UART - - def __repr__(self): - """Returns a representation of the instance. - - Args: - self (JLinkSWOSpeedInfo): the ``JLinkSWOSpeedInfo`` instance - - Returns: - ``None`` - """ - return self.__str__() - - def __str__(self): - """Returns a string representaton of the instance. - - Args: - self (JLinkSWOSpeedInfo): the ``JLinkSWOSpeedInfo`` instance - - Returns: - ``None`` - """ - return '%s(Interface=UART, Freq=%sHz)' % (self.__class__.__name__, self.BaseFreq) - - -class JLinkMOEInfo(ctypes.Structure): - __doc__ = 'Structure representing the Method of Debug Entry (MOE).\n\n The method of debug entry is a reason for which a CPU has stopped. At any\n given time, there may be multiple methods of debug entry.\n\n Attributes:\n HaltReason: reason why the CPU stopped.\n Index: if cause of CPU stop was a code/data breakpoint, this identifies\n the index of the code/data breakpoint unit which causes the CPU to\n stop, otherwise it is ``-1``.\n ' - _fields_ = [ - ( - 'HaltReason', ctypes.c_uint32), - ( - 'Index', ctypes.c_int)] - - def __repr__(self): - """Returns a string representation of the instance. - - Args: - self (JLinkMOEInfo): the ``JLinkMOEInfo`` instance - - Returns: - A string representation of the instance. - """ - return '%s(%s)' % (self.__class__.__name__, self.__str__()) - - def __str__(self): - """Returns a string representation of the instance. - - Args: - self (JLinkMOEInfo): the ``JLinkMOEInfo`` instance - - Returns: - A string representation of the instance. - """ - d = enums.JLinkHaltReasons.__dict__ - s = next((k for k, v in d.items() if v == self.HaltReason)) - if self.dbgrq(): - return s - return s.replace('_', ' ').title() - - def dbgrq(self): - """Returns whether this a DBGRQ. - - Args: - self (JLinkMOEInfo): the ``JLinkMOEInfo`` instance - - Returns: - ``True`` if this is a DBGRQ, otherwise ``False``. - """ - return self.HaltReason == enums.JLinkHaltReasons.DBGRQ - - def code_breakpoint(self): - """Returns whether this a code breakpoint. - - Args: - self (JLinkMOEInfo): the ``JLinkMOEInfo`` instance - - Returns: - ``True`` if this is a code breakpoint, otherwise ``False``. - """ - return self.HaltReason == enums.JLinkHaltReasons.CODE_BREAKPOINT - - def data_breakpoint(self): - """Returns whether this a data breakpoint. - - Args: - self (JLinkMOEInfo): the ``JLinkMOEInfo`` instance - - Returns: - ``True`` if this is a data breakpoint, otherwise ``False``. - """ - return self.HaltReason == enums.JLinkHaltReasons.DATA_BREAKPOINT - - def vector_catch(self): - """Returns whether this a vector catch. - - Args: - self (JLinkMOEInfo): the ``JLinkMOEInfo`` instance - - Returns: - ``True`` if this is a vector catch, otherwise ``False``. - """ - return self.HaltReason == enums.JLinkHaltReasons.VECTOR_CATCH - - -class JLinkBreakpointInfo(ctypes.Structure): - __doc__ = 'Class representing information about a breakpoint.\n\n Attributes:\n SizeOfStruct: the size of the structure (this should not be modified).\n Handle: breakpoint handle.\n Addr: address of where the breakpoint has been set.\n Type: type flags which were specified when the breakpoint was created.\n ImpFlags: describes the current state of the breakpoint.\n UseCnt: describes how often the breakpoint is set at the same address.\n ' - _fields_ = [ - ( - 'SizeOfStruct', ctypes.c_uint32), - ( - 'Handle', ctypes.c_uint32), - ( - 'Addr', ctypes.c_uint32), - ( - 'Type', ctypes.c_uint32), - ( - 'ImpFlags', ctypes.c_uint32), - ( - 'UseCnt', ctypes.c_uint32)] - - def __init__(self): - super(JLinkBreakpointInfo, self).__init__() - self.SizeOfStruct = ctypes.sizeof(self) - - def __repr__(self): - """Returns a formatted string describing the breakpoint. - - Args: - self (JLinkBreakpointInfo): the ``JLinkBreakpointInfo`` instance - - Returns: - Stirng representation of the breakpoint. - """ - return self.__str__() - - def __str__(self): - """Returns a formatted string describing the breakpoint. - - Args: - self (JLinkBreakpointInfo): the ``JLinkBreakpointInfo`` instance - - Returns: - Stirng representation of the breakpoint. - """ - name = self.__class__.__name__ - return '%s(Handle %d, Address %d)' % (name, self.Handle, self.Addr) - - def software_breakpoint(self): - """Returns whether this is a software breakpoint. - - Args: - self (JLinkBreakpointInfo): the ``JLinkBreakpointInfo`` instance - - Returns: - ``True`` if the breakpoint is a software breakpoint, otherwise - ``False``. - """ - software_types = [ - enums.JLinkBreakpoint.SW_RAM, - enums.JLinkBreakpoint.SW_FLASH, - enums.JLinkBreakpoint.SW] - return any((self.Type & stype for stype in software_types)) - - def hardware_breakpoint(self): - """Returns whether this is a hardware breakpoint. - - Args: - self (JLinkBreakpointInfo): the ``JLinkBreakpointInfo`` instance - - Returns: - ``True`` if the breakpoint is a hardware breakpoint, otherwise - ``False``. - """ - return self.Type & enums.JLinkBreakpoint.HW - - def pending(self): - """Returns if this breakpoint is pending. - - Args: - self (JLinkBreakpointInfo): the ``JLinkBreakpointInfo`` instance - - Returns: - ``True`` if the breakpoint is still pending, otherwise ``False``. - """ - return self.ImpFlags & enums.JLinkBreakpointImplementation.PENDING - - -class JLinkDataEvent(ctypes.Structure): - __doc__ = 'Class representing a data event.\n\n A data may halt the CPU, trigger SWO output, or trigger trace output.\n\n Attributes:\n SizeOfStruct: the size of the structure (this should not be modified).\n Type: the type of the data event (this should not be modified).\n Addr: the address on which the watchpoint was set\n AddrMask: the address mask used for comparision.\n Data: the data on which the watchpoint has been set.\n DataMask: the data mask used for comparision.\n Access: the control data on which the event has been set.\n AccessMask: the control mask used for comparison.\n ' - _fields_ = [ - ( - 'SizeOfStruct', ctypes.c_int), - ( - 'Type', ctypes.c_int), - ( - 'Addr', ctypes.c_uint32), - ( - 'AddrMask', ctypes.c_uint32), - ( - 'Data', ctypes.c_uint32), - ( - 'DataMask', ctypes.c_uint32), - ( - 'Access', ctypes.c_uint8), - ( - 'AccessMask', ctypes.c_uint8)] - - def __init__(self): - super(JLinkDataEvent, self).__init__() - self.SizeOfStruct = ctypes.sizeof(self) - self.Type = enums.JLinkEventTypes.BREAKPOINT - - def __repr__(self): - """Returns a string representation of the data event. - - Args: - self (JLinkDataEvent): the ``JLinkDataEvent`` instance - - Returns: - A string representation of the data event. - """ - return self.__str__() - - def __str__(self): - """Returns a string representation of the data event. - - Args: - self (JLinkDataEvent): the ``JLinkDataEvent`` instance - - Returns: - A string representation of the data event. - """ - name = self.__class__.__name__ - return '%s(Type %d, Address %d)' % (name, self.Type, self.Addr) - - -class JLinkWatchpointInfo(ctypes.Structure): - __doc__ = 'Class representing information about a watchpoint.\n\n Attributes:\n SizeOfStruct: the size of the structure (this should not be modified).\n Handle: the watchpoint handle.\n Addr: the address the watchpoint was set at.\n AddrMask: the address mask used for comparison.\n Data: the data on which the watchpoint was set.\n DataMask: the data mask used for comparision.\n Ctrl: the control data on which the breakpoint was set.\n CtrlMask: the control mask used for comparison.\n WPUnit: the index of the watchpoint unit.\n ' - _fields_ = [ - ( - 'SizeOfStruct', ctypes.c_uint32), - ( - 'Handle', ctypes.c_uint32), - ( - 'Addr', ctypes.c_uint32), - ( - 'AddrMask', ctypes.c_uint32), - ( - 'Data', ctypes.c_uint32), - ( - 'DataMask', ctypes.c_uint32), - ( - 'Ctrl', ctypes.c_uint32), - ( - 'CtrlMask', ctypes.c_uint32), - ( - 'WPUnit', ctypes.c_uint8)] - - def __init__(self): - super(JLinkWatchpointInfo, self).__init__() - self.SizeOfStruct = ctypes.sizeof(self) - - def __repr__(self): - """Returns a formatted string describing the watchpoint. - - Args: - self (JLinkWatchpointInfo): the ``JLinkWatchpointInfo`` instance - - Returns: - String representation of the watchpoint. - """ - return self.__str__() - - def __str__(self): - """Returns a formatted string describing the watchpoint. - - Args: - self (JLinkWatchpointInfo): the ``JLinkWatchpointInfo`` instance - - Returns: - String representation of the watchpoint. - """ - name = self.__class__.__name__ - return '%s(Handle %d, Address %d)' % (name, self.Handle, self.Addr) - - -class JLinkStraceEventInfo(ctypes.Structure): - __doc__ = 'Class representing the STRACE event information.\n\n Attributes:\n SizeOfStruct: size of the structure.\n Type: type of event.\n Op: the STRACE operation to perform.\n AccessSize: access width for trace events.\n Reserved0: reserved.\n Addr: specifies the load/store address for data.\n Data: the data to be compared for the operation for data access events.\n DataMask: bitmask for bits of data to omit in comparision for data access\n events.\n AddrRangeSize: address range for range events.\n ' - _fields_ = [ - ( - 'SizeOfStruct', ctypes.c_uint32), - ( - 'Type', ctypes.c_uint8), - ( - 'Op', ctypes.c_uint8), - ( - 'AccessSize', ctypes.c_uint8), - ( - 'Reserved0', ctypes.c_uint8), - ( - 'Addr', ctypes.c_uint64), - ( - 'Data', ctypes.c_uint64), - ( - 'DataMask', ctypes.c_uint64), - ( - 'AddrRangeSize', ctypes.c_uint32)] - - def __init__(self): - super(JLinkStraceEventInfo, self).__init__() - self.SizeOfStruct = ctypes.sizeof(self) - - def __repr__(self): - """Returns a formatted string describing the event info. - - Args: - self (JLinkStraceEventInfo): the ``JLinkStraceEventInfo`` instance - - Returns: - String representation of the event info. - """ - return self.__str__() - - def __str__(self): - """Returns a formatted string describing the event info. - - Args: - self (JLinkStraceEventInfo): the ``JLinkStraceEventInfo`` instance - - Returns: - String representation of the event information. - """ - name = self.__class__.__name__ - return '%s(Type=%d, Op=%d)' % (name, self.Type, self.Op) - - -class JLinkTraceData(ctypes.Structure): - __doc__ = 'Structure representing trace data returned by the trace buffer.\n\n Attributes:\n PipeStat: type of trace data.\n Sync: sync point in buffer.\n Packet: trace data packet.\n ' - _fields_ = [ - ( - 'PipeStat', ctypes.c_uint8), - ( - 'Sync', ctypes.c_uint8), - ( - 'Packet', ctypes.c_uint16)] - - def __repr__(self): - """Returns a string representation of the trace data instance. - - Args: - self (JLinkTraceData): the ``JLinkTraceData`` instance. - - Returns: - A string representation of the instance. - """ - return self.__str__() - - def __str__(self): - """Returns a string representation of the trace data instance. - - Args: - self (JLinkTraceData): the ``JLinkTraceData`` instance. - - Returns: - A string representation of the instance. - """ - return '%s(%d)' % (self.__class__.__name__, self.Packet) - - def instruction(self): - """Returns whether the data corresponds to an executed instruction. - - Args: - self (JLinkTraceData): the ``JLinkTraceData`` instance. - - Returns: - ``True`` if this is trace data for an executed instruction. - """ - return self.PipeStat == 0 - - def data_instruction(self): - """Returns whether the data corresponds to an data instruction. - - Args: - self (JLinkTraceData): the ``JLinkTraceData`` instance. - - Returns: - ``True`` if this is trace data for an data instruction. - """ - return self.PipeStat == 1 - - def non_instruction(self): - """Returns whether the data corresponds to an un-executed instruction. - - Args: - self (JLinkTraceData): the ``JLinkTraceData`` instance. - - Returns: - ``True`` if this is trace data for an un-executed instruction. - """ - return self.PipeStat == 2 - - def wait(self): - """Returns whether the data corresponds to a wait. - - Args: - self (JLinkTraceData): the ``JLinkTraceData`` instance. - - Returns: - ``True`` if this is trace data for a wait. - """ - return self.PipeStat == 3 - - def branch(self): - """Returns whether the data corresponds to a branch execution. - - Args: - self (JLinkTraceData): the ``JLinkTraceData`` instance. - - Returns: - ``True`` if this is trace data for a branch execution. - """ - return self.PipeStat == 4 - - def data_branch(self): - """Returns whether the data corresponds to a branch with data. - - Args: - self (JLinkTraceData): the ``JLinkTraceData`` instance. - - Returns: - ``True`` if this is trace data for a branch with data. - """ - return self.PipeStat == 5 - - def trigger(self): - """Returns whether the data corresponds to a trigger event. - - Args: - self (JLinkTraceData): the ``JLinkTraceData`` instance. - - Returns: - ``True`` if this is trace data for a trigger event. - """ - return self.PipeStat == 6 - - def trace_disabled(self): - """Returns whether the data corresponds to trace being disabled. - - Args: - self (JLinkTraceData): the ``JLinkTraceData`` instance. - - Returns: - ``True`` if this is trace data for the trace disabled event. - """ - return self.PipeStat == 7 - - -class JLinkTraceRegion(ctypes.Structure): - __doc__ = 'Structure describing a trace region.\n\n Attributes:\n SizeOfStruct: size of the structure.\n RegionIndex: index of the region.\n NumSamples: number of samples in the region.\n Off: offset in the trace buffer.\n RegionCnt: number of trace regions.\n Dummy: unused.\n Timestamp: timestamp of last event written to buffer.\n ' - _fields_ = [ - ( - 'SizeOfStruct', ctypes.c_uint32), - ( - 'RegionIndex', ctypes.c_uint32), - ( - 'NumSamples', ctypes.c_uint32), - ( - 'Off', ctypes.c_uint32), - ( - 'RegionCnt', ctypes.c_uint32), - ( - 'Dummy', ctypes.c_uint32), - ( - 'Timestamp', ctypes.c_uint64)] - - def __init__(self): - super(JLinkTraceRegion, self).__init__() - self.SizeOfStruct = ctypes.sizeof(self) - - def __repr__(self): - """Returns a string representation of the instance. - - Args: - self (JLinkTraceRegion): the ``JLinkTraceRegion`` instance. - - Returns: - String representation of the trace region. - """ - return self.__str__() - - def __str__(self): - """Returns a string representation of the instance. - - Args: - self (JLinkTraceRegion): the ``JLinkTraceRegion`` instance. - - Returns: - String representation of the trace region. - """ - return '%s(Index=%d)' % (self.__class__.__name__, self.RegionIndex) -# okay decompiling ./pylink/structs.pyc diff --git a/pylink/threads.py b/pylink/threads.py deleted file mode 100644 index 0c20d17..0000000 --- a/pylink/threads.py +++ /dev/null @@ -1,45 +0,0 @@ -# decompyle3 version 3.9.0 -# Python bytecode version base 3.7.0 (3394) -# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) -# [GCC 12.2.1 20220924] -# Embedded file name: pylink/threads.py -import threading - -class ThreadReturn(threading.Thread): - __doc__ = 'Implementation of a thread with a return value.\n\n See also:\n `StackOverflow `__.\n ' - - def __init__(self, daemon=False, *args, **kwargs): - """Initializes the thread. - - Args: - self (ThreadReturn): the ``ThreadReturn`` instance - daemon (bool): if the thread should be spawned as a daemon - args: optional list of arguments - kwargs: optional key-word arguments - - Returns: - ``None`` - """ - (super(ThreadReturn, self).__init__)(*args, **kwargs) - self.daemon = daemon - self._return = None - - def run(self): - """Runs the thread. - - Args: - self (ThreadReturn): the ``ThreadReturn`` instance - - Returns: - ``None`` - """ - target = getattr(self, '_Thread__target', getattr(self, '_target', None)) - args = getattr(self, '_Thread__args', getattr(self, '_args', None)) - kwargs = getattr(self, '_Thread__kwargs', getattr(self, '_kwargs', None)) - if target is not None: - self._return = target(*args, **kwargs) - - def join(self, *args, **kwargs): - (super(ThreadReturn, self).join)(*args, **kwargs) - return self._return -# okay decompiling ./pylink/threads.pyc diff --git a/pylink/util.py b/pylink/util.py deleted file mode 100644 index b1654cb..0000000 --- a/pylink/util.py +++ /dev/null @@ -1,157 +0,0 @@ -# decompyle3 version 3.9.0 -# Python bytecode version base 3.7.0 (3394) -# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49) -# [GCC 12.2.1 20220924] -# Embedded file name: pylink/util.py -from . import enums -import platform, sys - -def is_integer(val): - """Returns whether the given value is an integer. - - Args: - val (object): value to check - - Returns: - ``True`` if the given value is an integer, otherwise ``False``. - """ - try: - val += 1 - except TypeError: - return False - else: - return True - - -def is_natural(val): - """Returns whether the given value is a natrual number. - - Args: - val (object): value to check - - Returns: - ``True`` if the given value is a natural number, otherwise ``False``. - """ - return is_integer(val) and val >= 0 - - -def is_os_64bit(): - """Returns whether the current running platform is 64bit. - - Returns: - ``True`` if the platform is 64bit, otherwise ``False``. - """ - return platform.machine().endswith('64') - - -def noop(*args, **kwargs): - """No-op. Does nothing. - - Args: - args: list of arguments - kwargs: keyword arguments dictionary - - Returns: - ``None`` - """ - pass - - -def unsecure_hook_dialog(title, msg, flags): - """No-op that ignores the dialog. - - Args: - title (str): title of the unsecure dialog - msg (str): text of the unsecure dialog - flags (int): flags specifying which values can be returned - - Returns: - ``enums.JLinkFlags.DLG_BUTTON_NO`` - """ - return enums.JLinkFlags.DLG_BUTTON_NO - - -def progress_bar(iteration, total, prefix=None, suffix=None, decs=1, length=100): - """Creates a console progress bar. - - This should be called in a loop to create a progress bar. - - See `StackOverflow `__. - - Args: - iteration (int): current iteration - total (int): total iterations - prefix (str): prefix string - suffix (str): suffix string - decs (int): positive number of decimals in percent complete - length (int): character length of the bar - - Returns: - ``None`` - - Note: - This function assumes that nothing else is printed to the console in the - interim. - """ - if prefix is None: - prefix = '' - if suffix is None: - suffix = '' - format_str = '{0:.' + str(decs) + 'f}' - percents = format_str.format(100 * (iteration / float(total))) - filled_length = int(round(length * iteration / float(total))) - bar = '█' * filled_length + '-' * (length - filled_length) - prefix, suffix = prefix.strip(), suffix.strip() - sys.stdout.write('\r%s |%s| %s%s %s' % (prefix, bar, percents, '%', suffix)) - sys.stdout.flush() - if iteration == total: - sys.stdout.write('\n') - sys.stdout.flush() - - -def flash_progress_callback(action, progress_string, percentage): - """Callback that can be used with ``JLink.flash()``. - - This callback generates a progress bar in the console to show the progress - of each of the steps of the flash. - - Args: - action (str): the current action being invoked - progress_string (str): the current step in the progress - percentage (int): the percent to which the current step has been done - - Returns: - ``None`` - - Note: - This function ignores the compare action. - """ - if action.lower() != 'compare': - return progress_bar((min(100, percentage)), 100, prefix=action) - - -def calculate_parity(n): - """Calculates and returns the parity of a number. - - The parity of a number is ``1`` if the number has an odd number of ones - in its binary representation, otherwise ``0``. - - Args: - n (int): the number whose parity to calculate - - Returns: - ``1`` if the number has an odd number of ones, otherwise ``0``. - - Raises: - ValueError: if ``n`` is less than ``0``. - """ - if not is_natural(n): - raise ValueError('Expected n to be a positive integer.') - y = 0 - n = abs(n) - while n: - y += n & 1 - n = n >> 1 - - return y & 1 -# okay decompiling ./pylink/util.pyc diff --git a/requirements.txt b/requirements.txt index bcce11a..fe84cad 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,8 @@ psutil==5.9.5 +six==1.16.0 +pyserial==3.5 +pylink-square==0.5.0 +pycryptodome==3.9.8 +pycklink==0.1.1 +ecdsa==0.18.0 +pycryptoplus==0.0.1