RW61x Bootable Image#
Bootable image is primarily intended for booting from the external memories. Bootable image encapsulates the executable application images and adds additional data processed by the bootROM that are needed for boot, like for example configuration of the flash memories. The bootable image might consists of:
Keyblob for data decryption
Keystore
FlexSPI Configuration Block (FCB)
External Memory Configuration Data (XMCD)
Device Configuration Data (DCD) - The DCD contains configuration data to configure any peripherals.
Application Image - It might contain plain application image, High Assurance Boot (HAB), Advanced High Assurance Boot (AHAB) image or MBI.
1. Prerequisites#
SPSDK is needed with examples extension.
pip install spsdk[examples]
(Please refer to the installation documentation.)
# Initialization cell
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
WORKSPACE = "workspace/" # change this to path to your workspace
INPUTS = "inputs/"
INTERFACE = "pyocd" # choose debug interface
FAMILY = "rw612" # choose family
env: JUPYTER_SPSDK=1
Created `%!` as an alias for `%execute`.
2. Master Boot Image (MBI)#
We will need Master Boot Image (MBI) as a one part of bootable image.
We use the nxpimage tool for image conversion. Plain binary file can be used directly for the unsecure boot. To ensure security, we need to generate (MBI). MBI can in addtion to raw binary contain CRC checksum, certificates and ARM TrustZone configuration.
There are three types of MBI based on the authentication type: Plain, CRC and Signed and two variants of CRC and Signed images based on the execution target, either XIP (Executed in place) or in RAM.
In this example we will use plain MBI.
2.1 Prepare MBI Configuration file#
Generation of MBI is done with the nxpimage tool. First, we need to get the configuration template that will be used as a starting point.
Let’s begin by creating a template configuration file using the nxpimage mbi get-templates
command. To simplify this example, we have already prepared configuration, which can be found in the rw612_xip_plain.yaml file. Below, we’ll compare the differences between the template and our customized example to highlight the additions we’ve made.
# Get difference of template and user YAML configuration
YamlDiffWidget("inputs/rw612_mbi.diffc").html
nxpimage mbi get-templates -f rw612 -o workspace/ --force
Creating workspace\rw612_xip_plain.yaml template file.
Creating workspace\rw612_xip_crc.yaml template file.
Creating workspace\rw612_xip_signed.yaml template file.
Creating workspace\rw612_load_to_ram_plain.yaml template file.
Creating workspace\rw612_load_to_ram_crc.yaml template file.
Creating workspace\rw612_load_to_ram_signed.yaml template file.
2.2 MBI generation#
So now it’s time to create an MBI.
# Generate MBI
%! nxpimage mbi export -c inputs/rw612_xip_plain.yaml
nxpimage mbi export -c inputs/rw612_xip_plain.yaml
Success. (Master Boot Image: workspace\mbi.bin created.)
Now we have a working MBI that we will use in next steps
3. Create bootable image#
Generation of bootable image is done with the nxpimage tool. First, we need to get the configuration template that will be used as a starting point.
Let’s begin by creating a template configuration file using the nxpimage bootable-image get-templates
command. To simplify this example, we have already prepared configuration, which can be found in the bootimg_rw612_flexspi_nor.yaml file. Below, we’ll compare the differences between the template and our customized example to highlight the additions we’ve made.
# Get difference of template and user YAML configuration
YamlDiffWidget("inputs/rw612_bootimg.diffc").html
In order to create the final bootable image, we need to call nxpimage bootable-image merge
command. This command will put together all needed parts such as: MBI, FCB etc.
# Create the bootable image
%! nxpimage bootable-image merge -c inputs/bootimg_rw612_flexspi_nor.yaml -o workspace/bootable_image.bin
nxpimage bootable-image merge -c inputs/bootimg_rw612_flexspi_nor.yaml -o workspace/bootable_image.bin
Success. (Bootable Image: workspace\bootable_image.bin created)
4. Device preparation#
Now it’s time to prepare the device. In this example we will use FRDM-RW612 board.
Prepare device and use app nxpdevscan to check if the device is connected to the PC in In-System Programming (ISP) mode. The nxpdevscan must shown connected UART device with type “mboot” device. In following example the nxpdebugmbox is used to force device to ISP mode.
# force device to ISP mode
%! nxpdebugmbox -i $INTERFACE -f $FAMILY cmd ispmode -m 1
# check if the device is connected and detected by PC
%! nxpdevscan
nxpdebugmbox -i pyocd -f rw612 cmd ispmode -m 1
# Interface Id Description
-------------------------------------------------------
0 PyOCD 1069211762 Segger J-Link MCU-Link
Entering into ISP mode succeeded
nxpdevscan
-------- Connected NXP USB Devices --------
-------- Connected NXP UART Devices --------
Port: COM119
Type: mboot device
-------- Connected NXP SIO Devices --------
-------- Connected NXP UUU Devices --------
# determine the interface connection based on the result from nxpdevscan
UART = "-p COM119"
5. Running image#
Run the command nxpmemcfg blhost-script
, which generates a blhost script for the used chip memory on development board and this script called by blhost
application configure a external flexSPI NOR memory in MCU.
# Generate memory configuration
%! nxpmemcfg blhost-script -f $FAMILY -p flexspi_nor -m W25QxxxJV -i quad_spi --output workspace/script.txt --force
# Configure memory
%! blhost $UART batch workspace/script.txt
# Check the configured memory
%! blhost $UART list-memory
nxpmemcfg blhost-script -f rw612 -p flexspi_nor -m W25QxxxJV -i quad_spi --output workspace/script.txt --force
Loaded option words: Opt0: 0xC0000207
Exported blhost script.
blhost -p COM119 batch workspace/script.txt
Response status = 0 (0x0) Success.
Response status = 0 (0x0) Success.
blhost -p COM119 list-memory
Internal Flash:
Internal RAM:
Region 0: 0x10000000 - 0x1012FFFF; Total Size: 1.2 MiB
Region 1: 0x00000000 - 0x0012FFFF; Total Size: 1.2 MiB
Region 2: 0x20000000 - 0x2012FFFF; Total Size: 1.2 MiB
Region 3: 0x30000000 - 0x3012FFFF; Total Size: 1.2 MiB
External Memories:
FLEX-SPI-NOR:
Start Address = 0x08000000 Total Size = 64.0 MiB Page Size = 256 Sector Size = 4096 Block Size = 65536
SPI-MEM:
Not Configured
Next step is to:
Erase flash on used blocks
Write the exported applications on correct place
# Erase memory
%! blhost $UART flash-erase-region 0x0800_0000 0x10_000
# Write bootable image
%! blhost $UART write-memory 0x0800_0000 workspace/bootable_image.bin
blhost -p COM119 flash-erase-region 0x0800_0000 0x10_000
Response status = 0 (0x0) Success.
blhost -p COM119 write-memory 0x0800_0000 workspace/bootable_image.bin
Writing memory
Response status = 0 (0x0) Success.
Response word 1 = 22340 (0x5744)
In this step we load the prepared configuration of shadow registers where the proper boot source is enabled and proper lifecycle.
# Write the shadow registers and reset
%! shadowregs -i $INTERFACE -f $FAMILY loadconfig -c inputs/shadow.yaml
%! shadowregs -i $INTERFACE -f $FAMILY reset
shadowregs -i pyocd -f rw612 loadconfig -c inputs/shadow.yaml
# Interface Id Description
-------------------------------------------------------
0 PyOCD 1069211762 Segger J-Link MCU-Link
WARNING:spsdk.debuggers.utils:The test address is not specified. The standard address that doesn't fit all devices is used: 0x2000_0000 (3348ms since start, utils.py:138)
WARNING:spsdk.apps.shadowregs:Verification is not possible on the rw612, it won't be performed. (3393ms since start, shadowregs.py:229)
The Shadow registers has been loaded by configuration in inputs/shadow.yaml YAML file
shadowregs -i pyocd -f rw612 reset
# Interface Id Description
-------------------------------------------------------
0 PyOCD 1069211762 Segger J-Link MCU-Link
The target has been reset.
6. Final result#
At the end, the onboard led should be blinking