Managing boot flows
This page describes how to configure and interact with the boot flow managed by IronSide SE, including secondary firmware setup, boot commands, the boot report, and register formats. For an overview of the hardware-level boot sequence, including what triggers a cold boot, the step-by-step startup order of all domains, and boot sequence diagrams, see nRF54H20 boot sequence.
This page covers the following topics:
Booting local domains
This section describes the default boot flow used by IronSide SE. For information about the alternative boot flow that uses the secondary firmware, see Booting a secondary firmware.
IronSide SE boots only the application core CPU. The application core then triggers the boot of other local domain CPUs, such as the radio core, through the IronSide SE CPUCONF service.
Application domain boot sequence
When booting the application domain, IronSide SE performs the following operations:
Sets the processor’s vector table address to the start of the application-owned memory region.
Verifies for firmware availability by reading the reset vector from the second 32-bit word of the vector table and comparing it to the erased value (
0xFFFFFFFF).Sets the secure vector table offset register (INITSVTOR) to point to the vector table address.
Enables the CPU with the appropriate start mode:
IronSide SE enables the CPU in halted mode if any of the following conditions are met:
No firmware is available.
Boot errors occurred.
The
DEBUGWAITboot command was issued.
Otherwise, IronSide SE enables and starts the CPU normally.
Updates CTRL_AP.BOOTSTATUS and writes the boot report to reflect any boot errors encountered during the initialization process.
For more information on the boot sequence, see nRF54H20 boot sequence.
Reset handling of local domains
When a local domain resets, IronSide SE detects the event in the RESETHUB peripheral and triggers a global system reset, reported as SECSREQ in the local domain RESETINFO.RESETREAS.GLOBAL.
Certain local domain reset reasons can trigger a boot into the secondary boot mode. For more information, see Configuring the secondary firmware.
Booting a secondary firmware
The secondary firmware feature provides an alternative boot path that can be triggered implicitly or explicitly. It can be used for different purposes, some examples are recovery firmware, analysis firmware, and DFU applications in systems that do not use dual banking.
For more information on the boot sequence, see nRF54H20 boot sequence.
Note
The term “primary firmware” is rarely used when describing the firmware that is booted by default by IronSide SE, as it is implicit when the term “secondary” is not specified.
Note
The term “secondary slot” and “secondary image” are used in the MCUboot context. This usage is unrelated to the “secondary firmware” described in this section.
Configuring the secondary firmware
To enable secondary firmware support, you must complete the following steps:
Enable UICR secondary configuration by adding the following to
sysbuild/uicr.conf:CONFIG_GEN_UICR_SECONDARY=y
Create a separate Zephyr application for your secondary firmware (for example in a
secondary/directory).Include this Zephyr application as an external project in
sysbuild.cmake:ExternalZephyrProject_Add( APPLICATION secondary SOURCE_DIR ${APP_DIR}/secondary )
Configure secondary firmware Kconfig: The secondary firmware image itself must enable the appropriate Kconfig option to indicate it is a secondary firmware. Add the following to your secondary firmware’s
prj.conf:CONFIG_IS_IRONSIDE_SE_SECONDARY_IMAGE=y
Configure secondary firmware placement: The secondary firmware image must be placed in the DT partition named
secondary_partition. Add the following to your secondary firmware’sapp.overlay:/ { chosen { zephyr,code-partition = &secondary_partition; }; };
Optional: Configure secondary firmware features: Additional features can be configured by adding more options to your
sysbuild/uicr.conf:For instance, if you want automatic triggering based on reset reasons, add trigger options:
CONFIG_GEN_UICR_SECONDARY_TRIGGER=y CONFIG_GEN_UICR_SECONDARY_TRIGGER_APPLICATIONLOCKUP=y
For more examples of secondary firmware configuration, see the samples in nrf/samples/ironside_se/:
Secondary boot - Basic secondary firmware configuration
Secondary boot with APPLICATIONLOCKUP trigger - Secondary firmware with automatic triggers
Triggering the secondary firmware
The secondary firmware can be triggered automatically, through CTRLAP.BOOTMODE or through an IPC service (ironside_bootmode service).
Any component that communicates with IronSide SE over IPC can leverage this service.
Setting bit 5 in CTRLAP.BOOTMODE will also trigger secondary firmware.
IronSide SE automatically triggers the secondary firmware in any of the following situations:
The integrity check of the memory specified in
CONFIG_GEN_UICR_PROTECTEDMEMfails.Any boot failure occurs, such as missing primary firmware or failure to apply UICR.PERIPHCONF configurations.
If
CONFIG_GEN_UICR_SECONDARY_TRIGGERis enabled, and a UICR-configurable trigger occurs. See the following table for UICR-configurable triggers:
Kconfig option |
Description |
|---|---|
Trigger on Application domain watchdog 0 reset |
|
Trigger on Application domain watchdog 1 reset |
|
Trigger on Application domain CPU lockup reset |
|
Trigger on Radio core watchdog 0 reset |
|
Trigger on Radio core watchdog 1 reset |
|
Trigger on Radio core CPU lockup reset |
Protecting the secondary firmware
The secondary firmware can be protected through integrity checks by enabling CONFIG_GEN_UICR_SECONDARY_PROTECTEDMEM.
The PERIPHCONF entries for the secondary firmware can also be placed in memory covered by CONFIG_GEN_UICR_SECONDARY_PROTECTEDMEM to create a fully immutable secondary firmware and configuration.
If the integrity check of the memory specified in this configuration fails, the secondary firmware will not be booted. Instead, IronSide SE will attempt to boot the primary firmware, and information about the failure is available in the boot report and boot status.
Updating the secondary firmware
As with the primary firmware, IronSide SE does not facilitate updating the secondary firmware.
The secondary image can be updated by other components as long as CONFIG_GEN_UICR_SECONDARY_PROTECTEDMEM is not set.
Using the secondary firmware as a bootloader capable of validating and updating a second image enables updating firmware in the secondary boot flow while having secure boot enabled through CONFIG_GEN_UICR_SECONDARY_PROTECTEDMEM.
Using the radio core for the secondary firmware
By default, the secondary firmware uses the application processor.
The radio core can be used instead by enabling the CONFIG_GEN_UICR_SECONDARY_PROCESSOR_RADIOCORE option.
Changing the secondary firmware location
You can customize the location of the secondary firmware by modifying the secondary_partition DT partition in both the UICR image and the secondary firmware image.
This is typically done by editing the relevant devicetree source files (such as nrf54h20dk_nrf54h20_common.dts or board-specific overlay files) in your application and UICR image projects.
IronSide SE boot report
The IronSide SE boot report contains device state information communicated from IronSide SE to the local domains. It is written to a reserved region in RAM20, which is accessible to the local domain in the default system configuration. There is one boot report per processor that is booted, either directly by IronSide SE or through the CPUCONF service.
The boot report contains the following information:
Magic value
IronSide SE version
IronSide SE recovery version
IronSide SE update status
UICR error description
Context data passed to the CPUCONF service
A fixed amount of random bytes generated by a CSPRNG
Universal Unique Identifier (UUID) data
Versions
The boot report includes version information for both IronSide SE and IronSide SE Recovery.
The regular version format consists of four fields: MAJOR.MINOR.PATCH.SEQNUM, with each field occupying 8 bits.
The first three fields follow semantic versioning, while the SEQNUM field is a wrapping sequence number that increments by one with each version.
The values 0 and 127 are reserved for SEQNUM.
An additional version field, referred to as the extra version, contains a null-terminated ASCII string with human-readable version information. This string is informational only, and no semantics should be attached to this part of the version.
IronSide SE update status
The IronSide SE boot ROM code (SDROM) reports the status of an IronSide SE update request through SICR.UROT.UPDATE.STATUS. The value of this register is copied to the IronSide SE update status field of the boot report.
Note
After an update is installed or attempted, IronSide SE resets the update status to 0xFFFFFFFF on the next boot.
This means that the update status is only valid for a single execution.
When updating IronSide SE Recovery, the status will always be 0xFFFFFFFF.
Verify that IronSide SE Recovery has updated to the desired version by checking the version field of the boot report.
UICR error description
This field indicates if any UICR error occurred.
Local domain context
This field is populated by the local domain that is invoking the CPUCONF service.
It is set to 0 for the application core which is booted by IronSide SE.
This service is used when one local domain boots another local domain.
The caller can populate this field with arbitrary data that will be made available to the local domain being booted.
Typical examples of data that could be passed include IPC buffer sizes or the application firmware version.
The unused parts of this field are set to 0.
Random data
This field is filled with random data generated by a CSPRNG. This data is suitable as a source of initial entropy.
UUID data
This field contains 16 bytes that represent the device’s unique identity.
The bytes are provided as a stream of 16 raw bytes, rather than in the standard 8-4-4-4-12 UUID format.
Register formats
This section describes the layout and bit fields of the following registers used during the boot process:
CTRLAP.MAILBOX.BOOTMODE
CTRLAP.BOOTSTATUS
CTRLAP.BOOTMODE register format
The format of the CTRLAP.MAILBOX.BOOTMODE register is described in the following table:
Bit numbers |
31-8 |
7 |
6 |
5 |
4 |
3-1 |
0 |
Field |
N/A |
DEBUGWAIT |
RFU |
SECONDARYMODE |
SAFEMODE (ROM) |
OPCODE |
MODE (ROM) |
CTRLAP.BOOTSTATUS register format
The general format of the CTRLAP.BOOTSTATUS register is described in the following table:
Bit numbers |
31-28 |
27-24 |
23-0 |
Field |
RFU |
BOOTSTAGE |
INFO |
Fields marked as RFU (Reserved for Future Use) are set to 0, unless otherwise specified. The BOOTSTAGE field indicates which component in the boot sequence encountered a failure.
If BOOTSTAGE is set to 0xC or 0xD, the register has the following format:
Bit numbers |
31-28 |
27-24 |
23-22 |
21-15 |
14-12 |
11-9 |
8 |
7-0 |
Field |
RFU |
BOOTSTAGE |
RFU |
FWVERSION |
CMDOPCODE |
CMDERROR |
SECONDARYMODE |
BOOTERROR |
This field can have one of the following values:
BOOTSTAGE value |
Description |
|---|---|
0x0 |
Unset (reset value) |
0x1 |
SysCtrl ROM |
0x2 |
Secure domain ROM |
0xB |
Secure domain firmware with SUIT (major version < 20) |
0xC |
Secure domain firmware (major version >= 20) |
0xD |
Secure domain recovery firmware (major version >= 20) |
Note
The value 0xB indicates a boot status error reported by the Secure Domain running a firmware version earlier than 20.
See IronSide SE ABI compatibility for more information.
The register is written by IronSide SE at the end of every cold boot sequence.
A value of 0 indicates that IronSide SE did not complete the boot process.
The following fields are reported by IronSide SE:
- FWVERSION
Reports the SEQNUM field of the IronSide SE version. The value reported in this field is incremented with each released version of the firmware. It can be used to distinguish between firmware versions within a specific release window.
- CMDOPCODE
The opcode of the boot command issued to IronSide SE in the CTRLAP.MAILBOX.BOOTMODE register. A value of
0indicates that no boot command has been issued.- CMDERROR
A code indicating the execution status of the boot command specified in CMDOPCODE:
A status value of
0indicates that the command was executed successfully.A non-zero value indicates that an error condition occurred during execution of the command. The error code
0x7means that an unexpected condition happened that might have prevented the command from executing. Other error codes must be interpreted based on the boot command in CMDOPCODE.
- SECONDARYMODE
Indicates whether the secondary firmware was booted. A value of
1indicates that the secondary firmware was booted, while a value of0indicates that the primary firmware was booted.- BOOTERROR
A code indicating the status of the application domain boot sequence:
A status value of
0indicates that the CPU was started normally.A non-zero value indicates that an error condition occurred, preventing the CPU from starting. Detailed information about the issue can be found in the boot report.
Boot commands
The debugger can instruct IronSide SE to perform an action during the boot sequence. These actions are called boot commands.
Boot commands are issued through the CTRLAP.MAILBOX.BOOTMODE register and are processed only during a cold boot. IronSide SE indicates that a boot command was executed by setting the CTRLAP.BOOTSTATUS register.
The recommended flow for issuing a boot command is the following:
Write the command opcode to the OPCODE field in CTRLAP.MAILBOX.BOOTMODE.
Trigger a global reset by setting CTRLAP.RESET = 1.
Note
Any global reset that does not involve a power cycle can be used in place of a CTRLAP reset here.
Wait for the command status to be acknowledged in CTRLAP.BOOTSTATUS.
Clear the command opcode by writing zeroes to the OPCODE field in CTRLAP.MAILBOX.BOOTMODE. As this register is retained across resets, it must be cleared to prevent the command from being re-executed on the next cold boot.
See the following table for a summary of the available boot commands:
Command name |
Opcode |
Description |
|---|---|---|
|
|
Erase all user data. |
|
|
Start the application CPU with |
The following chapters describe each command in detail.
ERASEALL command
The ERASEALL command instructs IronSide SE to erase all application-owned memory.
When executed, the ERASEALL command performs the following operations:
Erases all pages in MRAM10, from the first page immediately after the IronSide SE Recovery Firmware through the last page in the region.
Clears all global domain general-purpose RAM by writing zeros.
Erases page 0 of the MRAM10 NVR (excluding the BICR), which also clears the UICR.
Erases all non-NVR pages in MRAM11.
Note
Page 1 of the MRAM10 NVR is preserved and not erased.
To explicitly permit the ERASEALL command, disable erase protection by clearing the CONFIG_GEN_UICR_ERASEPROTECT field in the application’s UICR.
Erase protection prevents unauthorized device repurposing.
In production-ready devices, enabling both access-port protection (CONFIG_GEN_UICR_APPROTECT_APPLICATION_PROTECTED) and erase protection (CONFIG_GEN_UICR_ERASEPROTECT) prevents the device from re-entering the configuration state using a debugger.
Note
When an ERASEALL request is blocked by CONFIG_GEN_UICR_ERASEPROTECT, CTRLAP.BOOTSTATUS.CMDERROR is set to 0x1.
DEBUGWAIT command
The DEBUGWAIT command instructs IronSide SE to start the application core in a halted state by setting CPUCONF.CPUWAIT = 1.
This prevents the CPU from executing any instructions until the CPUWAIT register is cleared by a connected debugger.
Use this command to begin debugging at the very first instruction or to program flash memory safely without concurrent CPU access.
The DEBUGWAIT command does not define any command-specific values for the CTRLAP.BOOTSTATUS.CMDERROR field.
Note
You can also use the cpuconf service to set CPUWAIT when booting other cores.
Configuring IronSide SE SPU MRAMC feature
IronSide SE configures the SPU.FEATURES.MRAMC registers with default settings for both MRAMC110 and MRAMC111. Local domains have access to the READY/READYNEXT status registers for monitoring the status of the MRAM controller. All other MRAMC features (like WAITSTATES and AUTODPOWERDOWN) are managed by IronSide SE, with all configurations locked at boot time.