Skip to content

Commit 61040fd

Browse files
committed
samples: boards: nordic: add sample for secondary boot
Add a sample that demonstrates how a secondary boot image could be built. Signed-off-by: Sebastian Bøe <[email protected]>
1 parent 7f7a8cb commit 61040fd

File tree

10 files changed

+242
-0
lines changed

10 files changed

+242
-0
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#
2+
# Copyright (c) 2025 Nordic Semiconductor ASA
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
cmake_minimum_required(VERSION 3.13.1)
8+
9+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
10+
11+
project(secondary_boot_primary)
12+
13+
target_sources(app PRIVATE
14+
src/main.c
15+
)
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
.. zephyr:code-sample:: secondary_boot_corruption
2+
:name: Secondary Boot Corruption Sample
3+
4+
Demonstrate secondary image boot after primary image corruption
5+
6+
Overview
7+
********
8+
9+
This sample demonstrates the secondary boot functionality on nRF54H20DK when the
10+
primary image is corrupted. The sample consists of two applications that work
11+
together to show how the system can recover from primary image corruption by
12+
booting a secondary image.
13+
14+
The sample uses UICR (User Information Configuration Registers) to
15+
enable and configure secondary boot and protected memory regions, then
16+
intentionally corrupts the primary image to trigger a reboot to the
17+
secondary image.
18+
19+
Architecture
20+
************
21+
22+
The sample consists of three components:
23+
24+
* **Primary Image**: Runs initially on the application core (cpuapp), prints a
25+
hello world message, corrupts protected memory, and reboots the system.
26+
27+
* **Secondary Image**: Runs on the same application core (cpuapp) after the
28+
primary image corruption triggers a reboot. Prints its own hello world message
29+
and continues running with periodic heartbeat messages.
30+
31+
* **UICR Build**: Generates UICR configuration that enables secondary boot and
32+
protected memory regions.
33+
34+
Requirements
35+
************
36+
37+
* nRF54H20DK board
38+
39+
Building and Running
40+
********************
41+
42+
This sample uses :ref:`sysbuild` to build multiple images. The ``--sysbuild``
43+
flag is required.
44+
45+
Build the sample:
46+
47+
.. zephyr-app-commands::
48+
:zephyr-app: samples/boards/nordic/nrf_ironside/secondary_boot_corruption
49+
:board: nrf54h20dk/nrf54h20/cpuapp
50+
:west-args: --sysbuild
51+
:goals: build
52+
53+
Flash the sample:
54+
55+
.. zephyr-app-commands::
56+
:zephyr-app: samples/boards/nordic/nrf_ironside/secondary_boot_corruption
57+
:board: nrf54h20dk/nrf54h20/cpuapp
58+
:west-args: --sysbuild
59+
:goals: flash
60+
61+
Sample Output
62+
*************
63+
64+
When the sample runs successfully, you should see output similar to the following:
65+
66+
.. code-block:: console
67+
68+
*** Booting Zephyr OS build v4.2.99 ***
69+
=== Hello World from Primary Image ===
70+
Rebooting
71+
*** Booting Zephyr OS build v4.2.99 ***
72+
=== Hello World from Secondary Image ===
73+
Secondary image heartbeat
74+
Secondary image heartbeat
75+
...
76+
77+
How It Works
78+
************
79+
80+
1. The primary image starts and prints a hello world message.
81+
82+
2. The primary image intentionally corrupts protected memory regions by writing
83+
specific values to memory addresses. This is only possible because the MPU
84+
(Memory Protection Unit) is disabled in the configuration.
85+
86+
3. The primary image triggers a system reset.
87+
88+
4. During the next boot, the system detects the corruption and boots the
89+
secondary image instead of the primary image.
90+
91+
5. The secondary image starts and prints its own hello world message, then
92+
continues running with periodic heartbeat messages.
93+
94+
Dependencies
95+
************
96+
97+
This sample uses the following Zephyr subsystems:
98+
99+
* :ref:`sysbuild` for multi-image builds
100+
* UICR generation system for configuration
101+
* Device tree for memory layout configuration
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#
2+
# Copyright (c) 2025 Nordic Semiconductor ASA
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
# Disable the MPU to allow the sample to corrupt itself
8+
CONFIG_ARM_MPU=n
9+
10+
CONFIG_ASSERT=y
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
sample:
2+
name: Secondary Boot Corruption Sample
3+
description: |
4+
Demonstrates secondary image boot after primary image corruption on nRF54H20DK.
5+
The primary image corrupts protected memory and reboots, triggering the system
6+
to boot the secondary image instead.
7+
8+
common:
9+
sysbuild: true
10+
harness: console
11+
harness_config:
12+
type: multi_line
13+
regex:
14+
- "=== Hello World from Primary Image ==="
15+
- "=== Hello World from Secondary Image ==="
16+
17+
tests:
18+
sample.boards.nordic.nrf_ironside.secondary_boot_corruption:
19+
tags:
20+
- sysbuild
21+
- nrf_ironside
22+
platform_allow:
23+
- nrf54h20dk/nrf54h20/cpuapp
24+
integration_platforms:
25+
- nrf54h20dk/nrf54h20/cpuapp
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Copyright (c) 2025 Nordic Semiconductor ASA
2+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
3+
4+
cmake_minimum_required(VERSION 3.13.1)
5+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
6+
project(secondary_boot_secondary)
7+
8+
# Create marker file to identify this as secondary firmware for gen_uicr.py
9+
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/is_secondary_firmware.txt "")
10+
11+
target_sources(app PRIVATE src/main.c)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#
2+
# Copyright (c) 2025 Nordic Semiconductor ASA
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
# NB: Must match secondary_partition in DT
8+
# Secondary partition is at 0x1b0000
9+
CONFIG_FLASH_LOAD_OFFSET=0x1b0000
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/kernel.h>
8+
#include <zephyr/sys/printk.h>
9+
10+
int main(void)
11+
{
12+
printk("=== Hello World from Secondary Image ===\n");
13+
14+
while (1) {
15+
k_msleep(3000);
16+
printk("Secondary image heartbeat\n");
17+
}
18+
19+
return 0;
20+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/kernel.h>
8+
#include <zephyr/sys/printk.h>
9+
#include <zephyr/sys/reboot.h>
10+
#include <zephyr/linker/linker-defs.h>
11+
#include <string.h>
12+
13+
int main(void)
14+
{
15+
printk("=== Hello World from Primary Image ===\n");
16+
17+
__ASSERT((uint32_t)__rom_region_start == 0xe030000,
18+
"For nRF54H20 the protectedmem starts at 0xe030000");
19+
20+
printk("Corrupting the PROTECTEDMEM\n");
21+
/* (This is only possible because we have disabled CONFIG_ARM_MPU). */
22+
23+
*((volatile uint32_t *)__rom_region_start + 0) = 0x5EB0;
24+
*((volatile uint32_t *)__rom_region_start + 4) = 0x5EB0;
25+
*((volatile uint32_t *)__rom_region_start + 8) = 0x5EB0;
26+
*((volatile uint32_t *)__rom_region_start + 12) = 0x5EB0;
27+
28+
printk("Rebooting\n");
29+
30+
sys_reboot(SYS_REBOOT_COLD);
31+
32+
return 0;
33+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Copyright (c) 2025 Nordic Semiconductor ASA
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
ExternalZephyrProject_Add(
5+
APPLICATION secondary
6+
SOURCE_DIR ${APP_DIR}/secondary
7+
BOARD nrf54h20dk/nrf54h20/cpuapp
8+
)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Copyright (c) 2025 Nordic Semiconductor ASA
2+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
3+
4+
# Configuration overlay for uicr image
5+
# Enable UICR.SECONDARY.ENABLE
6+
CONFIG_GEN_UICR_SECONDARY=y
7+
8+
# Enable UICR protected memory
9+
CONFIG_GEN_UICR_PROTECTEDMEM=y
10+
CONFIG_GEN_UICR_PROTECTEDMEM_SIZE_BYTES=4096

0 commit comments

Comments
 (0)