i.MXRT118x Signed AHAB Example#
This example demonstrates how to create a signed AHAB container for i.MXRT118x devices. The aim of this Jupyter notebook is to show how to create a signed AHAB container for an application based on the SDK. The nxpmemcfg
tool is demonstrated to generate the FCB block for the external memory populated on the RT1180-EVK board. The resulting image must be programmed into the external memory via the blhost
tool.
1. Prerequisites#
SPSDK is needed with examples extension.
pip install spsdk[examples]
(Please refer to the installation documentation.)This example uses RT1180 EVK board
import os
from spsdk.utils.jupyter_utils import YamlDiffWidget
# This env variable sets colored logger output to STDOUT
%env JUPYTER_SPSDK=1
# Set a magic for command execution and echo
%alias execute echo %l && %l
%alias_magic ! execute
env: JUPYTER_SPSDK=1
Created `%!` as an alias for `%execute`.
WORKSPACE = "workspace/" # change this to path to your workspace
INPUTS = "inputs/"
VERBOSITY = (
"" # verbosity of commands, might be -v or -vv for debug or blank for no additional info
)
BIMG_FILE = (
INPUTS + "bootimg_rt118x_flexspi_nor.yaml"
) # Boot image yaml file. Used to generate bootable image
SRKH_BATCH_FILE = (
WORKSPACE + "signed_ahab_oem0_srk0_hash_blhost.bcf"
) # batch file for SRKH progamming
BOOTABLE_IMAGE = WORKSPACE + "bootable_img.bin" # Final Bootable image contains SIGNED_AHAB + FCB
FLASHLOADER_FILE = "../rt118x_signed_flashloader/workspace/flashloader.bin" # Path to Flashloader
CFG_MEM_FILE = WORKSPACE + "config_mem.bls" # Configure memory template
FCB_FILE = WORKSPACE + "fcb.bin" # Firmware Configuration block file
1.1 Compile an Application#
Hello_word XiP application is used in this example.
To use a custom application follow the steps:
Download the NXP MCUXpresso SDK from NXP web site (https://mcuxpresso.nxp.com/)
Open the example in your favorite IDE.
Compile your application using the corresponding target. The resulting binary must be copied at input folder and renamed in regards to specific target XiP FlexSPI1/2, CTCM, OCRAM, Multicore. to make it running with this example.
fspi1_xip_cm33_img.bin (default)
fspi2_xip_cm33_img.bin
ctcm_cm33_img.bin
ocram_cm33_img.yaml
fspi1_multicore_img.bin
fspi2_multicore_img.bin
2. Generate Keys#
The AHAB is using asymmetric algorithm for image authentication which requires keys generated according to PKI for operation. The example uses pre-generated ECC-256 keys. To generate your own keys please refer to How-to-get-keys-using-nxpcrypto example.
3. Sign NXP Flashloader#
On secured device all SW executed on the device must be authenticated, including NXP Flashloader. The example uses pre-generated ECC-256 keys to sign the Flashloader. To generate your own keys please refer to the Flashloader example:
4. Create Signed AHAB Container for Application#
In the previous steps, we generated a signed AHAB container for the NXP Flashloader. We need to perform similar steps for the application that will run on secured devices. The SPSDK tool, nxpimage
, is specifically designed to create bootable images, including AHAB containers for the RT118x family. The ahab
subcommand is used to generate an AHAB container for an application.
A YAML file for the RT118x can be generated using the following command. The steps below guide you on which fields need to be reconfigured. The resulting YAML file is available in the input folder, so manual updates are not necessary.
YamlDiffWidget("inputs/rt118x_secure_boot.diffc").html
4.1 Modify the Template Configuration File for AHAB#
To create an AHAB container for your application, follow these steps to modify the template configuration file:
I. Change the Output File Name: The target memory is standard by default, representing the memory from which the RT118x will boot.
II. General Settings of AHAB Container:
- Remove the signature provider definition.
- Configure the path to the pre-generated private signing key.
- Set the use_srk_id
field to align with the signing_key
index:
- use_srk_id=0
corresponds to srk0_ecc256.pem
- use_srk_id=1
corresponds to srk1_ecc256.pem
- use_srk_id=2
corresponds to srk2_ecc256.pem
- use_srk_id=3
corresponds to srk3_ecc256.pem
III. Define the Image Executable:
- Set the application offset to 0xA000
to align with the SDK linker files. This offset allows for the inclusion of the base ELE firmware (32KB).
- Ensure load_address
and entry_point
fields match the start address defined in the linker file for the application. Both usually point to the same address unless there are data placed before the image vector table (e.g., dual-core applications).
- The hash
parameter is mandatory for AHAB. Integrity checks are always performed during boot:
- In OEM_OPEN, an invalid hash reports a warning but allows the image to boot.
- In OEM_CLOSED, an invalid hash prevents the firmware from booting.
The example below is for an XiP target executed from NOR memory connected to FlexSPI 1. Examples for other bootable images (FlexSPI2, OCRAM, CTCM, and multicore) are also available in the inputs folder:
config_signed_fspi1.yaml
(demonstrated)config_signed_fspi2.yaml
config_signed_ctcm.yaml
config_signed_ocram.yaml
config_signed_multicore_fspi1.yaml
config_signed_multicore_fspi2.yaml
IV. Define the SRK (Super Root Keys) Array: - Use local pre-generated public keys.
V. Remove Unused Parts: - Remove unused sections for AHAB Certificate and Encryption blob from the YAML file.
To export AHAB container is designed SPSDK tool in ‘nxpimage’ under ‘ahab’ sub commands group.
# For this example, signed xip application from FlexSPI 1 is used by default
AHAB_CONFIG = INPUTS + "config_signed_fspi1.yaml" # Prepared AHAB configuration file
# AHAB_CONFIG = INPUTS + "config_signed_fspi2.yaml" # Prepared AHAB configuration file
# AHAB_CONFIG = INPUTS + "config_signed_ctcm.yaml" # Prepared AHAB configuration file
# AHAB_CONFIG = INPUTS + "config_signed_ocram.yaml" # Prepared AHAB configuration file
# AHAB_CONFIG = INPUTS + "config_signed_multicore_fspi1.yaml" # Prepared AHAB configuration file
# AHAB_CONFIG = INPUTS + "config_signed_multicore_fspi2.yaml" # Prepared AHAB configuration file
assert os.path.exists(AHAB_CONFIG)
# Export AHAB container using nxpimage
%! nxpimage $VERBOSITY ahab export -c $AHAB_CONFIG
nxpimage ahab export -c inputs/config_signed_fspi1.yaml
Success. (AHAB: workspace/signed_ahab.bin created.)
Generated file containing SRK hash: workspace/signed_ahab_oem0_srk0_hash.txt
Generated script for writing fuses for container 0: workspace/signed_ahab_oem0_srk0_hash_blhost.bcf
5. Program the image into external memory.#
RT118x requires boot from an external memory. To build a valid bootable image, another structures must be placed into external memory depending on bootable image type. For signed AHAB, ony FCB is required besides ahab and image itself. See the figure below for information:
The SPSDK contains commands group that simplify whole operation with bootable images under ‘nxpimage’.
I. Configure external memory. SPDSK contains tool called “nxpmemcfg” which contains database of supported memories and utilities to supports creation, extraction, parsing of FCB etc.
# Print out all supported memories
%! nxpmemcfg family-info
nxpmemcfg family-info
List of all supported peripherals and its instances:
╔════╦════════════╦═════════════╦══════════╦══════════════╦══════════╦═══════════╦════════════════════════════════════════════════╦════════╦════════╗
║ # ║ Family ║ flexspi_nor ║ xspi_nor ║ flexspi_nand ║ semc_nor ║ semc_nand ║ spi_nor ║ mmc ║ sd ║
╠════╬════════════╬═════════════╬══════════╬══════════════╬══════════╬═══════════╬════════════════════════════════════════════════╬════════╬════════╣
║ 0 ║ lpc5502 ║ N/A ║ N/A ║ N/A ║ N/A ║ N/A ║ [3] ║ N/A ║ N/A ║
║ 1 ║ lpc5504 ║ N/A ║ N/A ║ N/A ║ N/A ║ N/A ║ [3] ║ N/A ║ N/A ║
║ 2 ║ lpc5506 ║ N/A ║ N/A ║ N/A ║ N/A ║ N/A ║ [3] ║ N/A ║ N/A ║
║ 3 ║ lpc5512 ║ N/A ║ N/A ║ N/A ║ N/A ║ N/A ║ [3] ║ N/A ║ N/A ║
║ 4 ║ lpc5514 ║ N/A ║ N/A ║ N/A ║ N/A ║ N/A ║ [3] ║ N/A ║ N/A ║
║ 5 ║ lpc5516 ║ N/A ║ N/A ║ N/A ║ N/A ║ N/A ║ [3] ║ N/A ║ N/A ║
║ 6 ║ lpc5526 ║ N/A ║ N/A ║ N/A ║ N/A ║ N/A ║ [3] ║ N/A ║ N/A ║
║ 7 ║ lpc5528 ║ N/A ║ N/A ║ N/A ║ N/A ║ N/A ║ [3] ║ N/A ║ N/A ║
║ 8 ║ lpc55s04 ║ N/A ║ N/A ║ N/A ║ N/A ║ N/A ║ [3] ║ N/A ║ N/A ║
║ 9 ║ lpc55s06 ║ N/A ║ N/A ║ N/A ║ N/A ║ N/A ║ [3] ║ N/A ║ N/A ║
║ 10 ║ lpc55s14 ║ N/A ║ N/A ║ N/A ║ N/A ║ N/A ║ [3] ║ N/A ║ N/A ║
║ 11 ║ lpc55s16 ║ N/A ║ N/A ║ N/A ║ N/A ║ N/A ║ [3] ║ N/A ║ N/A ║
║ 12 ║ lpc55s26 ║ N/A ║ N/A ║ N/A ║ N/A ║ N/A ║ [3] ║ N/A ║ N/A ║
║ 13 ║ lpc55s28 ║ N/A ║ N/A ║ N/A ║ N/A ║ N/A ║ [3] ║ N/A ║ N/A ║
║ 14 ║ lpc55s36 ║ Yes ║ N/A ║ N/A ║ N/A ║ N/A ║ [0, 1, 3, 8] ║ N/A ║ N/A ║
║ 15 ║ lpc55s66 ║ N/A ║ N/A ║ N/A ║ N/A ║ N/A ║ [3] ║ N/A ║ N/A ║
║ 16 ║ lpc55s69 ║ N/A ║ N/A ║ N/A ║ N/A ║ N/A ║ [3] ║ N/A ║ N/A ║
║ 17 ║ mcxn235 ║ N/A ║ N/A ║ N/A ║ N/A ║ N/A ║ [7] ║ N/A ║ N/A ║
║ 18 ║ mcxn236 ║ N/A ║ N/A ║ N/A ║ N/A ║ N/A ║ [7] ║ N/A ║ N/A ║
║ 19 ║ mimxrt1010 ║ Yes ║ N/A ║ N/A ║ N/A ║ N/A ║ N/A ║ N/A ║ N/A ║
║ 20 ║ mimxrt1015 ║ Yes ║ N/A ║ Yes ║ N/A ║ N/A ║ [1, 2, 3, 4] ║ N/A ║ N/A ║
║ 21 ║ mimxrt1020 ║ Yes ║ N/A ║ Yes ║ Yes ║ Yes ║ [1, 2, 3, 4] ║ [1, 2] ║ [1, 2] ║
║ 22 ║ mimxrt1024 ║ Yes ║ N/A ║ Yes ║ Yes ║ Yes ║ [1, 2, 3, 4] ║ [1, 2] ║ [1, 2] ║
║ 23 ║ mimxrt1040 ║ Yes ║ N/A ║ Yes ║ Yes ║ Yes ║ [1, 2, 3, 4] ║ [1, 2] ║ [1, 2] ║
║ 24 ║ mimxrt1050 ║ Yes ║ N/A ║ Yes ║ Yes ║ Yes ║ [1, 2, 3, 4] ║ [1, 2] ║ [1, 2] ║
║ 25 ║ mimxrt1060 ║ [1, 2] ║ N/A ║ Yes ║ Yes ║ Yes ║ [1, 2, 3, 4] ║ [1, 2] ║ [1, 2] ║
║ 26 ║ mimxrt1064 ║ Yes ║ N/A ║ Yes ║ Yes ║ Yes ║ [1, 2, 3, 4] ║ [1, 2] ║ [1, 2] ║
║ 27 ║ mimxrt1165 ║ [1, 2] ║ N/A ║ [1, 2] ║ Yes ║ Yes ║ [1, 2, 3, 4] ║ [1, 2] ║ [1, 2] ║
║ 28 ║ mimxrt1166 ║ [1, 2] ║ N/A ║ [1, 2] ║ Yes ║ Yes ║ [1, 2, 3, 4] ║ [1, 2] ║ [1, 2] ║
║ 29 ║ mimxrt1171 ║ [1, 2] ║ N/A ║ [1, 2] ║ Yes ║ Yes ║ [1, 2, 3, 4] ║ [1, 2] ║ [1, 2] ║
║ 30 ║ mimxrt1172 ║ [1, 2] ║ N/A ║ [1, 2] ║ Yes ║ Yes ║ [1, 2, 3, 4] ║ [1, 2] ║ [1, 2] ║
║ 31 ║ mimxrt1173 ║ [1, 2] ║ N/A ║ [1, 2] ║ Yes ║ Yes ║ [1, 2, 3, 4] ║ [1, 2] ║ [1, 2] ║
║ 32 ║ mimxrt1175 ║ [1, 2] ║ N/A ║ [1, 2] ║ Yes ║ Yes ║ [1, 2, 3, 4] ║ [1, 2] ║ [1, 2] ║
║ 33 ║ mimxrt1176 ║ [1, 2] ║ N/A ║ [1, 2] ║ Yes ║ Yes ║ [1, 2, 3, 4] ║ [1, 2] ║ [1, 2] ║
║ 34 ║ mimxrt1181 ║ [1, 2] ║ N/A ║ [1, 2] ║ Yes ║ Yes ║ [1, 2, 4, 5] ║ [1, 2] ║ [1, 2] ║
║ 35 ║ mimxrt1182 ║ [1, 2] ║ N/A ║ [1, 2] ║ Yes ║ Yes ║ [1, 2, 4, 5] ║ [1, 2] ║ [1, 2] ║
║ 36 ║ mimxrt1187 ║ [1, 2] ║ N/A ║ [1, 2] ║ Yes ║ Yes ║ [1, 2, 4, 5] ║ [1, 2] ║ [1, 2] ║
║ 37 ║ mimxrt1189 ║ [1, 2] ║ N/A ║ [1, 2] ║ Yes ║ Yes ║ [1, 2, 4, 5] ║ [1, 2] ║ [1, 2] ║
║ 38 ║ mimxrt533s ║ [0, 1] ║ N/A ║ [0, 1] ║ N/A ║ N/A ║ [0, 1, 2, 3, 4, 5, 6, 7] ║ [0, 1] ║ [0, 1] ║
║ 39 ║ mimxrt555s ║ [0, 1] ║ N/A ║ [0, 1] ║ N/A ║ N/A ║ [0, 1, 2, 3, 4, 5, 6, 7] ║ [0, 1] ║ [0, 1] ║
║ 40 ║ mimxrt595s ║ [0, 1] ║ N/A ║ [0, 1] ║ N/A ║ N/A ║ [0, 1, 2, 3, 4, 5, 6, 7] ║ [0, 1] ║ [0, 1] ║
║ 41 ║ mimxrt685s ║ [0, 1] ║ N/A ║ [0, 1] ║ N/A ║ N/A ║ [0, 1, 2, 3, 4, 5, 6, 7] ║ [0, 1] ║ [0, 1] ║
║ 42 ║ mimxrt798s ║ N/A ║ [0, 1] ║ N/A ║ N/A ║ N/A ║ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] ║ [0, 1] ║ [0, 1] ║
║ 43 ║ rw610 ║ Yes ║ N/A ║ N/A ║ N/A ║ N/A ║ [0, 1, 2, 3, 4] ║ N/A ║ N/A ║
║ 44 ║ rw612 ║ Yes ║ N/A ║ N/A ║ N/A ║ N/A ║ [0, 1, 2, 3, 4] ║ N/A ║ N/A ║
╚════╩════════════╩═════════════╩══════════╩══════════════╩══════════╩═══════════╩════════════════════════════════════════════════╩════════╩════════╝
List of all known memory configuration option words:
╔════╦══════╦══════════════════════╦══════════════╦═════════════╦════════════════════════════════════╦════════╗
║ # ║ Type ║ Name ║ Manufacturer ║ Interface ║ Option words ║ Tested ║
╠════╬══════╬══════════════════════╬══════════════╬═════════════╬════════════════════════════════════╬════════╣
║ 0 ║ nor ║ W25QxxxJV ║ Winbond ║ quad_spi ║ Opt0: 0xC0000207 ║ ║
║ 1 ║ nor ║ W35T51NW ║ Winbond ║ octal_spi ║ Opt0: 0xC0603005 ║ ║
║ 2 ║ nor ║ MX25Uxxx32F ║ Macronix ║ quad_spi ║ Opt0: 0xC0000007 ║ * ║
║ 3 ║ nor ║ MX25Lxxx45G ║ Macronix ║ quad_spi ║ Opt0: 0xC0000007 ║ * ║
║ 4 ║ nor ║ MX25UMxxx45G ║ Macronix ║ octal_spi ║ Opt0: 0xC0403037 ║ ║
║ 5 ║ nor ║ MX66UMxxx45G ║ Macronix ║ octal_spi ║ Opt0: 0xC0403037 ║ ║
║ 6 ║ nor ║ MX25LMxxx45G ║ Macronix ║ octal_spi ║ Opt0: 0xC0403037 ║ ║
║ 7 ║ nor ║ MX25UM51345G ║ Macronix ║ octal_spi ║ Opt0: 0xC0403037 ║ ║
║ 8 ║ nor ║ MX25UM51345G_2nd ║ Macronix ║ octal_spi ║ Opt0: 0xC1503051, Opt1: 0x20000014 ║ ║
║ 9 ║ nor ║ GD25QxxxC ║ GigaDevice ║ quad_spi ║ Opt0: 0xC0000406 ║ ║
║ 10 ║ nor ║ GD25LBxxxE ║ GigaDevice ║ quad_spi ║ Opt0: 0xC0000007 ║ ║
║ 11 ║ nor ║ GD25LTxxxE ║ GigaDevice ║ quad_spi ║ Opt0: 0xC0000008 ║ ║
║ 12 ║ nor ║ GD25LXxxxE ║ GigaDevice ║ quad_spi ║ Opt0: 0xC0603008 ║ ║
║ 13 ║ nor ║ IS25LPxxxA ║ ISSI ║ quad_spi ║ Opt0: 0xC0000007 ║ ║
║ 14 ║ nor ║ IS25WPxxxA ║ ISSI ║ quad_spi ║ Opt0: 0xC0000007 ║ ║
║ 15 ║ nor ║ IS25LXxxx ║ ISSI ║ octal_spi ║ Opt0: 0xC0603005 ║ ║
║ 16 ║ nor ║ IS25WXxxx ║ ISSI ║ octal_spi ║ Opt0: 0xC0603005 ║ ║
║ 17 ║ nor ║ IS26KSxxxS ║ ISSI ║ hyper_flash ║ Opt0: 0xC0233007 ║ ║
║ 18 ║ nor ║ IS26KLxxxS ║ ISSI ║ hyper_flash ║ Opt0: 0xC0233007 ║ ║
║ 19 ║ nor ║ MT25QLxxxA ║ Micron ║ quad_spi ║ Opt0: 0xC0000007 ║ ║
║ 20 ║ nor ║ RW303-MT35XUxxxABA1G ║ Micron ║ octal_spi ║ Opt0: 0xC0603005 ║ ║
║ 21 ║ nor ║ RW304-MT35XUxxxABA2G ║ Micron ║ octal_spi ║ Opt0: 0xC0633005 ║ ║
║ 22 ║ nor ║ MT28EW128ABA ║ Micron ║ parallel ║ Opt0: 0xD0000600 ║ ║
║ 23 ║ nor ║ MT28UG128ABA ║ Micron ║ parallel ║ Opt0: 0xD0000601 ║ ║
║ 24 ║ nor ║ AT25SFxxxA ║ Adesto ║ quad_spi ║ Opt0: 0xC0000007 ║ ║
║ 25 ║ nor ║ ATXPxxx ║ Adesto ║ octal_spi ║ Opt0: 0xC0803007 ║ ║
║ 26 ║ nor ║ S25FSxxxS ║ Cypress ║ quad_spi ║ Opt0: 0xC0000007 ║ ║
║ 27 ║ nor ║ S25FLxxxS ║ Cypress ║ quad_spi ║ Opt0: 0xC0000007 ║ ║
║ 28 ║ nor ║ S26KSxxxS ║ Cypress ║ hyper_flash ║ Opt0: 0xC0233007 ║ ║
║ 29 ║ nor ║ S26KLxxxS ║ Cypress ║ hyper_flash ║ Opt0: 0xC0233007 ║ ║
║ 30 ║ nor ║ SST26VFxxxB ║ Microchip ║ quad_spi ║ Opt0: 0xC0000005 ║ ║
║ 31 ║ nor ║ FM25Qxxx ║ FudanMicro ║ quad_spi ║ Opt0: 0xC0000205 ║ ║
║ 32 ║ nor ║ BY25QxxxBS ║ BoyaMicro ║ quad_spi ║ Opt0: 0xC0000405 ║ ║
║ 33 ║ nor ║ XM25QHxxxB ║ XMC ║ quad_spi ║ Opt0: 0xC0000007 ║ ║
║ 34 ║ nor ║ XM25QUxxxB ║ XMC ║ quad_spi ║ Opt0: 0xC0000007 ║ ║
║ 35 ║ nor ║ X25FxxxB ║ XTXtech ║ quad_spi ║ Opt0: 0xC0000407 ║ ║
║ 36 ║ nor ║ X25QxxxD ║ XTXtech ║ quad_spi ║ Opt0: 0xC0000407 ║ ║
║ 37 ║ nor ║ P25QxxxLE ║ Puya ║ quad_spi ║ Opt0: 0xC0000405 ║ ║
║ 38 ║ nor ║ P25QxxxH ║ Puya ║ quad_spi ║ Opt0: 0xC0000405 ║ ║
║ 39 ║ nor ║ P25QxxxU ║ Puya ║ quad_spi ║ Opt0: 0xC0000405 ║ ║
║ 40 ║ nor ║ A25LQxxx ║ AMIC ║ quad_spi ║ Opt0: 0xC0000105 ║ ║
╚════╩══════╩══════════════════════╩══════════════╩═════════════╩════════════════════════════════════╩════════╝
║ 41 ║ nand ║ W25N01G ║ Winbond ║ quad_spi ║ Opt0: 0xC1010026, Opt1: 0x000000EF ║ ║
║ 42 ║ nand ║ W25N02K ║ Winbond ║ quad_spi ║ Opt0: 0xC1020026, Opt1: 0x000000EF ║ ║
║ 43 ║ nand ║ MX35UF1G ║ Macronix ║ quad_spi ║ Opt0: 0xC1010026, Opt1: 0x000000C2 ║ ║
║ 44 ║ nand ║ MX35LF1G ║ Macronix ║ quad_spi ║ Opt0: 0xC1010026, Opt1: 0x000000C2 ║ ║
║ 45 ║ nand ║ MX35UF2G ║ Macronix ║ quad_spi ║ Opt0: 0xC1020026, Opt1: 0x000000C2 ║ ║
║ 46 ║ nand ║ MX35LF2G ║ Macronix ║ quad_spi ║ Opt0: 0xC1020026, Opt1: 0x000000C2 ║ ║
║ 47 ║ nand ║ GD5F1GQ5 ║ GigaDevice ║ quad_spi ║ Opt0: 0xC1010026, Opt1: 0x000000C8 ║ ║
║ 48 ║ nand ║ GD5F2GQ5 ║ GigaDevice ║ quad_spi ║ Opt0: 0xC1020026, Opt1: 0x000000C8 ║ ║
║ 49 ║ nand ║ MT29F1G01AA ║ Micron ║ quad_spi ║ Opt0: 0xC1011022, Opt1: 0x0000002C ║ ║
║ 50 ║ nand ║ MT29F2G01AA ║ Micron ║ quad_spi ║ Opt0: 0xC1021022, Opt1: 0x0000002C ║ ║
║ 51 ║ nand ║ PN26Q01A ║ Paragon ║ quad_spi ║ Opt0: 0xC1010026, Opt1: 0x000000A1 ║ ║
║ 52 ║ nand ║ PN26G01A ║ Paragon ║ quad_spi ║ Opt0: 0xC1010026, Opt1: 0x000000A1 ║ ║
║ 53 ║ nand ║ PN26Q02A ║ Paragon ║ quad_spi ║ Opt0: 0xC1020026, Opt1: 0x000000A1 ║ ║
║ 54 ║ nand ║ PN26G02A ║ Paragon ║ quad_spi ║ Opt0: 0xC1020026, Opt1: 0x000000A1 ║ ║
╚════╩══════╩══════════════════════╩══════════════╩═════════════╩════════════════════════════════════╩════════╝
║ 55 ║ sd ║ 1bit_sdr12 ║ General ║ instance_0 ║ Opt0: 0xD0000000 ║ ║
║ 56 ║ sd ║ 1bit_sdr12 ║ General ║ instance_1 ║ Opt0: 0xD0000001 ║ ║
║ 57 ║ sd ║ 1bit_sdr12 ║ General ║ instance_2 ║ Opt0: 0xD0000002 ║ ║
║ 58 ║ sd ║ 1bit_sdr12 ║ General ║ instance_3 ║ Opt0: 0xD0000003 ║ ║
╚════╩══════╩══════════════════════╩══════════════╩═════════════╩════════════════════════════════════╩════════╝
# How to use the blhost-script
%! nxpmemcfg blhost-script
nxpmemcfg blhost-script
Usage: nxpmemcfg blhost-script [OPTIONS]
Export the configuration option words to blhost script.
Options:
Known chip select. Alternative to known chip is YAML configuration '-c': [all_or_none]
-f, --family [lpc5502|lpc5504|lpc5506|lpc5512..., and more. Use 'get-families' command to show all.]
Select the chip family.
-p, --peripheral [flexspi_nor|xspi_nor|flexspi_nand|semc_nor|semc_nand|spi_nor|mmc|sd]
Choose the peripheral of the input option
words
-m, --memory-chip TEXT Select supported memory chip name. Use
family-info command to get the known names.
-i, --interface TEXT Select supported memory chip interface. Use
family-info command to get the known
interfaces.
-c, --config FILE Option word configuration YAML file, in case
that known chip has not been used
-ix, --instance INTEGER Instance of peripheral if applicable
--fcb PATH Optional filename of FCB block generated by
HW and read back to PC. Be aware that script
will contain also erase of 4KB on base
address.
--secure-addresses If defined, the secure address will be used
in case of generating FCB block.
-o, --output FILE Name of BLHOST script. If not specified, the
script will be printed to command line
--force Force overwriting of existing files.
--help Show this message and exit.
# Generate script to configure FlexSPI interface for the specific memory and extract FCB.
%! nxpmemcfg blhost-script -f mimxrt1189 -m W25QxxxJV -i quad_spi -p flexspi_nor -ix 1 -o $CFG_MEM_FILE --force --fcb $FCB_FILE --secure-addresses
assert os.path.exists(CFG_MEM_FILE)
nxpmemcfg blhost-script -f mimxrt1189 -m W25QxxxJV -i quad_spi -p flexspi_nor -ix 1 -o workspace/config_mem.bls --force --fcb workspace/fcb.bin --secure-addresses
Loaded option words: Opt0: 0xC0000007
WARNING:spsdk.memcfg.memcfg:FCB block read back script has been generated. Be aware that s 4KB block at base address will be erased to avoid cumulative write! (375ms since start, memcfg.py:434)
Exported blhost script.
EVK Board Overview#
The following picture describes connector placement of RT1180 EVK.#
Serial Downloader Protocol Mode:#
Configure Boot Mode Switch to : 1/2/3-OFF, 4-ON
Connect micro USB cable into USB OTG1 - J33
Connect micro USB cable into Debug USB Port - J53
Internal Boot Mode:#
Configure Boot Mode Switch to :1-OFF, 2-ON, 3-OFF, 4-OFF
Connect micro USB cable into Debug USB Port - J53
# The board must be in SDP mode
# Configure Boot Mode Switch to : 1/2/3-OFF, 4-ON
# Connect micro USB cable into USB OTG1 - J33
# Connect micro USB cable into Debug USB Port - J53
# Parameters for BLHOST. USB PID/VID for ROM Flashloader and NXP Flashloader
COMPAR = "-u" # USB
BLHOST_CONNECT_ROM = "0x1fc9,0x014c" # PID/VID of ROM
BLHOST_CONNECT_FLDR = "0x15A2,0x0073" # PID/VID of NXP Flashloader
# To use tha UART compar parameter must be change, COMxx must be replaced by the name of your COM port, 115200 is default baudrate.
# compar="-p" # UART
# BLHOST_CONNECT_ROM="COMxx,115200" # COM port, baudrate
# BLHOST_CONNECT_FLDR="COMxx,115200" # COM port, baudrate
assert os.path.exists(FLASHLOADER_FILE)
# Load flashloader
%! blhost $VERBOSITY $COMPAR $BLHOST_CONNECT_ROM get-property 1
%! blhost $VERBOSITY $COMPAR $BLHOST_CONNECT_ROM load-image $FLASHLOADER_FILE
blhost -u 0x1fc9,0x014c get-property 1
Response status = 0 (0x0) Success.
Response word 1 = 1258487809 (0x4b030001)
Current Version = K3.0.1
blhost -u 0x1fc9,0x014c load-image ../rt118x_signed_flashloader/workspace/flashloader.bin
Loading image
Response status = 0 (0x0) Success.
# Ping the RT1180
%! blhost $VERBOSITY $COMPAR $BLHOST_CONNECT_FLDR get-property 7
# Ping the RT1180
%! blhost $VERBOSITY $COMPAR $BLHOST_CONNECT_FLDR get-property 1
# Execute the commands generated by "blhost-script". This script will configure flash,
# program FCB into the external memory and reads back the binary data. Be aware tha erase of the first sector must be done.
# The script can be executed only once to read FCB.
%! blhost $COMPAR $BLHOST_CONNECT_FLDR batch $CFG_MEM_FILE
assert os.path.exists(FCB_FILE)
blhost -u 0x15A2,0x0073 get-property 7
Response status = 0 (0x0) Success.
Response word 1 = 364511 (0x58fdf)
Available Commands = ['FlashEraseAll', 'FlashEraseRegion', 'ReadMemory', 'WriteMemory', 'FillMemory', 'GetProperty', 'ReceiveSBFile', 'Execute', 'Call', 'Reset', 'SetProperty', 'FlashReadResource', 'ConfigureMemory', 'GenerateKeyBlob']
blhost -u 0x15A2,0x0073 get-property 1
Response status = 0 (0x0) Success.
Response word 1 = 1258424320 (0x4b020800)
Current Version = K2.8.0
blhost -u 0x15A2,0x0073 batch workspace/config_mem.bls
Response status = 0 (0x0) Success.
Response status = 0 (0x0) Success.
Response status = 0 (0x0) Success.
Response status = 0 (0x0) Success.
Response status = 0 (0x0) Success.
Response status = 0 (0x0) Success.
Response status = 0 (0x0) Success.
Reading memory
Response status = 0 (0x0) Success.
Response word 1 = 512 (0x200)
Read 512 of 512 bytes.
5.1 Create the bootable image#
YamlDiffWidget("inputs/rt118x_secure_boot_bimg.diffc").html
nxpimage bootable-image get-templates -f mimxrt1189 -o workspace --force
Creating workspace/bootimg_mimxrt1189_serial_downloader.yaml template file.
Creating workspace/bootimg_mimxrt1189_flexspi_nor.yaml template file.
Creating workspace/bootimg_mimxrt1189_flexspi_nand.yaml template file.
Creating workspace/bootimg_mimxrt1189_semc_nand.yaml template file.
Creating workspace/bootimg_mimxrt1189_emmc.yaml template file.
Creating workspace/bootimg_mimxrt1189_sd.yaml template file.
Export the final bootable image
# Export bootable image
%! nxpimage $VERBOSITY bootable-image merge -c $BIMG_FILE -o $BOOTABLE_IMAGE
# Assert os.path.exists(BOOTABLE_IMAGE)
assert os.path.isfile(BOOTABLE_IMAGE)
nxpimage bootable-image merge -c inputs/bootimg_rt118x_flexspi_nor.yaml -o workspace/bootable_img.bin
Success. (Bootable Image: workspace/bootable_img.bin created)
5.2 Program the image into external memory#
# Base address of FlexSPI 1
# FLASH_ADDRESS = "0x28000000"
FLASH_ADDRESS = "0x38000000" # Secure alias
# Base address of FlexSPI 2
# FLASH_ADDRESS = "0x04000000"
# Size of external memory to erase
ERASE_SIZE = "0x50000"
# Erase flash
%! blhost $VERBOSITY $COMPAR $BLHOST_CONNECT_FLDR flash-erase-region $FLASH_ADDRESS $ERASE_SIZE
# Write image - 0x38000000
%! blhost $VERBOSITY $COMPAR $BLHOST_CONNECT_FLDR write-memory $FLASH_ADDRESS $BOOTABLE_IMAGE
# Switch the board into internal boot and reset.
# Configure Boot Mode Switch to :1-OFF, 2-ON, 3-OFF, 4-OFF
# Connect micro USB cable into Debug USB Port - J53
# Open Serial Terminal (115200)
# Reset the board
# The "hello_world" with time should be printed on the terminal:
# hello world new 14:36:56
blhost -u 0x15A2,0x0073 flash-erase-region 0x38000000 0x50000
Response status = 0 (0x0) Success.
blhost -u 0x15A2,0x0073 write-memory 0x38000000 workspace/bootable_img.bin
Writing memory
Response status = 0 (0x0) Success.
Response word 1 = 61440 (0xf000)
6. Burn Super Root Key Hash (SRKH) and Manage Lifecycle.#
After successful validation of previous steps we can proceed with final security enablement. SRKH must be programmed into corresponding fuses to establish root of trust. On RT118x the dedicated ELE command must be used to move lifecycle to OEM_CLOSED which enforces security.
Only authenticated FW images will be executed. Debug features will be limited and must be unlocked by debug mailbox feature.
Debug mailbox example is located HERE.
WARNING!!! This step is destructive operation (updating life cycle)
# The board must be in SDP mode
# Configure Boot Mode Switch to : 1/2/3-OFF, 4-ON
# Connect micro USB cable into USB OTG1 - J33
# Connect micro USB cable into Debug USB Port - J53
from time import sleep
assert os.path.exists(FLASHLOADER_FILE)
assert os.path.exists(SRKH_BATCH_FILE)
# To enable this script, set the variable below to 1
enable_script = 0
if enable_script:
# Ping ROM flashloader
%! blhost $VERBOSITY $COMPAR $BLHOST_CONNECT_ROM get-property 1
# Load flashloader
%! blhost $VERBOSITY $COMPAR $BLHOST_CONNECT_ROM load-image $FLASHLOADER_FILE
sleep(3)
# Ping flashloader
%! blhost $VERBOSITY $COMPAR $BLHOST_CONNECT_FLDR get-property 1
# Execute batch command to program SRKH
%! blhost $VERBOSITY $COMPAR $BLHOST_CONNECT_FLDR batch $SRKH_BATCH_FILE
# OEM lifecycle statuses
# 8 - oem_closed: Update to OEM Closed
ELE_LIFECYCLE = 8
# Change Lifecycle to OEM_CLOSED
%! blhost $VERBOSITY $COMPAR $BLHOST_CONNECT_FLDR update-life-cycle $ELE_LIFECYCLE
# Switch the board into internal boot and reset.
# Configure Boot Mode Switch to :1-OFF, 2-ON, 3-OFF, 4-OFF
# Connect micro USB cable into Debug USB Port - J53
# Open Serial Terminal (115200)
# Reset the board
# The "hello_world" with time should be printed on the terminal:
# hello world new 14:36:56