def write_image( cpu_params: CpuParams, image_file_name: str, img: BootImgRT, otpmk_bee_regions: Tuple[BeeFacRegion, ...] = tuple()) -> None: """Write image to the external flash The method behaviour depends on TEST_IMG_CONTENT: - if True (TEST MODE), the method generates the image and compare with previous version - if False (PRODUCTION), the method generates the image and burn into FLASH :param cpu_params: processor specific parameters of the test :param image_file_name: of the image to be written (including file extension) :param img: image instance to be written :param otpmk_bee_regions: optional list of BEE regions for BEE OTPMK encryption """ path = os.path.join(cpu_params.data_dir, OUTPUT_IMAGES_SUBDIR, image_file_name) debug_info = DebugInfo() # use zulu datetime for test purposes only, to produce stable output; remove the parameter for production zulu = datetime(year=2020, month=4, day=8, hour=5, minute=54, second=33, tzinfo=timezone.utc) img_data = img.export(dbg_info=debug_info, zulu=zulu) assert len(img_data) == img.size write_dbg_log(cpu_params.data_dir, image_file_name, debug_info.lines, TEST_IMG_CONTENT) if TEST_IMG_CONTENT: assert img.info() # quick check info prints non-empty output compare_bin_files(path, img_data) # compare no-padding if NO_PADDING and img.fcb.enabled and isinstance( img.fcb, PaddingFCB) and not img.bee_encrypted: img.fcb.enabled = False compare_bin_files(path.replace('.bin', '_nopadding.bin'), img.export(zulu=zulu)) img.fcb.enabled = False # test that parse image will return same content if img.fcb.enabled and not img.bee_encrypted: compare_bin_files(path, BootImgRT.parse(img_data).export()) # test that size matches len of exported data assert img.size == len(img_data) else: with open(path, 'wb') as f: f.write(img_data) if NO_PADDING and img.fcb.enabled and isinstance( img.fcb, PaddingFCB) and not img.bee_encrypted: with open(path.replace('.bin', '_nopadding.bin'), 'wb') as f: f.write(img_data[img.ivt_offset:]) if img.ivt_offset == BootImgRT.IVT_OFFSET_NOR_FLASH: _burn_image_to_flash(cpu_params, img, img_data, otpmk_bee_regions) else: assert len(otpmk_bee_regions) == 0 _burn_image_to_sd(cpu_params, img, img_data)
def init_flashloader(cpu_params: CpuParams) -> McuBoot: """Load an execute flash-loader binary in i.MX-RT The function signs the flashloader if needed (if HAB enabled) :param cpu_params: processor specific parameters of the test :return: McuBoot instance to communicate with flash-loader :raises ConnectionError: if connection cannot be established """ devs = mboot_scan_usb(cpu_params.com_processor_name ) # check whether flashloader is already running if len(devs) == 0: # if flash-loader not running yet, it must be downloaded to RAM and launched flshldr_img = BootImgRT.parse( load_binary(cpu_params.data_dir, 'ivt_flashloader.bin')) devs = sdp_scan_usb(cpu_params.com_processor_name) if len(devs) != 1: raise ConnectionError('Cannot connect to ROM bootloader') with SDP(devs[0], cmd_exception=True) as sd: assert sd.is_opened try: sd.read(INT_RAM_ADDR_CODE, 4) # dummy read to receive response except SdpCommandError: # there is an exception if HAB is locked, cause read not supported pass if (sd.status_code == StatusCode.HAB_IS_LOCKED) and (sd.response_value == ResponseValue.LOCKED): auth_flshldr_img = BootImgRT(flshldr_img.address, BootImgRT.IVT_OFFSET_OTHER) _to_authenticated_image( cpu_params, auth_flshldr_img, flshldr_img.app.data, 0, flshldr_img.ivt.app_address ) # entry addr cannot be detected from img else: auth_flshldr_img = flshldr_img assert sd.write_file(auth_flshldr_img.address, auth_flshldr_img.export()) try: assert sd.jump_and_run(auth_flshldr_img.address + auth_flshldr_img.ivt_offset) except SdpCommandError: pass # SDP may return an exception if HAB locked for _ in range(10): # wait 10 sec until flash-loader is inited sleep(1) # Scan for MCU-BOOT device devs = mboot_scan_usb(cpu_params.com_processor_name) if len(devs) == 1: break if len(devs) != 1: raise ConnectionError('Cannot connect to Flash-Loader') result = McuBoot(devs[0], cmd_exception=True) result.open() assert result.is_opened result.reopen = False # reopen not supported for RT1050??? return result
def test_bootimage_rt10xx_basic(): """Simple test for BootImgRT""" img = BootImgRT(0x60000000) assert img.info() dbg_info = DebugInfo() img_data = img.export(dbg_info=dbg_info) # test parser returns same result dbg_info2 = DebugInfo() img_data2 = BootImgRT.parse(img_data).export(dbg_info=dbg_info2) assert dbg_info.lines == dbg_info2.lines assert img_data == img_data2
def main() -> None: """Main function.""" # Create Boot Image instance img = BootImgRT(address=0x20000000, version=0x40) # Add DCD segment with open(f"{DATA_DIR}/dcd.txt", "r") as f_txt: img.dcd = SegDCD.parse_txt(f_txt.read()) # Add application segment with open(f"{DATA_DIR}/plain_load_ivt_flashloader.bin", "rb") as f_bin: img.add_image(data=f_bin.read()) # Print image info print(img.info()) # Save into file with open(f"{DATA_DIR}/flashloader.imx", "wb") as f: f.write(img.export())
def test_invalid_export(): img = BootImgRT(address=0x60000000) img.dek_key = b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" with pytest.raises(SPSDKError): img.export()