Skip to content

Conversation

@zycz
Copy link
Contributor

@zycz zycz commented Nov 24, 2025

Add idle relocated TCM multicore test for nRF54H20

Introduce a new sample demonstrating a multicore idle test
with firmware relocated to the radio core's TCM.
The test showcases the radio loader pattern, where firmware
is loaded from MRAM to TCM at runtime, ensuring efficient execution.

Add changes in sysbuild required to allow building radio TCM loader with sysbuild and mcuboot.

Copilot AI review requested due to automatic review settings November 24, 2025 07:32
@zycz zycz requested review from a team as code owners November 24, 2025 07:32
@NordicBuilder NordicBuilder added doc-required PR must not be merged without tech writer approval. manifest changelog-entry-required Update changelog before merge. Remove label if entry is not needed or already added. labels Nov 24, 2025
@zycz zycz added this to the 3.2.0 milestone Nov 24, 2025
@NordicBuilder
Copy link
Contributor

NordicBuilder commented Nov 24, 2025

The following west manifest projects have changed revision in this Pull Request:

Name Old Revision New Revision Diff

All manifest checks OK

Note: This message is automatically posted and updated by the Manifest GitHub Action.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a new multicore idle test sample for the nRF54H20 platform that demonstrates firmware relocation to the radio core's TCM (Tightly Coupled Memory). The implementation introduces a radio loader pattern where firmware is copied from MRAM to TCM at runtime for optimal performance. The PR also extends the sysbuild infrastructure to support building the radio TCM loader with MCUboot integration.

Key Changes:

  • Introduces a two-stage boot process for the radio core using a loader that copies firmware from MRAM to TCM
  • Adds sysbuild infrastructure (radioloader.cmake, Kconfig.radioloader) to integrate the radio loader automatically
  • Implements automatic firmware relocation using Zephyr's CONFIG_BUILD_OUTPUT_ADJUST_LMA feature via devicetree chosen nodes

Reviewed changes

Copilot reviewed 28 out of 28 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
west.yml Updates Zephyr revision to pull request branch
sysbuild/radioloader.cmake Adds radio loader sysbuild integration
sysbuild/Kconfig.radioloader Defines Kconfig options for radio loader
sysbuild/Kconfig.netcore Adds custom radio option to netcore choices
sysbuild/Kconfig.sysbuild Includes radioloader Kconfig file
sysbuild/CMakeLists.txt Includes radioloader CMake file
samples/nrf54h20/radio_loader/src/main.c Implements loader that copies firmware from MRAM to TCM
samples/nrf54h20/radio_loader/CMakeLists.txt Build configuration for radio loader
samples/nrf54h20/idle_relocated_tcm/* New sample demonstrating multicore idle with TCM relocation
cmake/sysbuild/sign_nrf54h20.cmake Updates to support fw-to-relocate chosen node
cmake/modules/kconfig.cmake Adds support for fw-to-relocate in variant image configuration

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@@ -137,11 +142,13 @@ config NETCORE_IMAGE_NAME
default "rpc_host" if NETCORE_RPC_HOST
default "802154_rpmsg" if NETCORE_802154_RPMSG
default "ipc_radio" if NETCORE_IPC_RADIO
default "remote_rad" if CUSTOM_RADIO
help
Name of netcore image.

config NETCORE_IMAGE_PATH
string
Copy link

Copilot AI Nov 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate string type declaration. Line 150 should be removed as the type and prompt are correctly defined on line 151.

Suggested change
string

Copilot uses AI. Check for mistakes.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that string "..." if OPTION will be enough.
i've seen similar thing here: https://github.com/nrfconnect/sdk-nrf/blob/main/subsys/dult/Kconfig#L181

@NordicBuilder
Copy link
Contributor

NordicBuilder commented Nov 24, 2025

CI Information

To view the history of this post, click the 'edited' button above
Build number: 14

Inputs:

Sources:

sdk-nrf: PR head: 5d0da1b2cb47a78ff3fde291d95c77fcfffa0c70

more details

sdk-nrf:

PR head: 5d0da1b2cb47a78ff3fde291d95c77fcfffa0c70
merge base: ffc451ead6217c35ebd99ad8ac6d2df45e82c7cd
target head (main): 6983362cc851474d8d61b7641b6b19f21e3d8f90
Diff

Github labels

Enabled Name Description
ci-disabled Disable the ci execution
ci-all-test Run all of ci, no test spec filtering will be done
ci-force-downstream Force execution of downstream even if twister fails
ci-run-twister Force run twister
ci-run-zephyr-twister Force run zephyr twister
List of changed files detected by CI (35)
CODEOWNERS
cmake
│  ├── modules
│  │  │ kconfig.cmake
│  ├── sysbuild
│  │  │ sign_nrf54h20.cmake
doc
│  ├── nrf
│  │  ├── releases_and_maturity
│  │  │  ├── releases
│  │  │  │  │ release-notes-changelog.rst
│  │  ├── samples
│  │  │  │ other.rst
samples
│  ├── nrf54h20
│  │  ├── idle_relocated_tcm
│  │  │  ├── CMakeLists.txt
│  │  │  ├── Kconfig.sysbuild
│  │  │  ├── README.rst
│  │  │  ├── boards
│  │  │  │  ├── memory_map.overlay
│  │  │  │  │ nrf54h20dk_nrf54h20_cpuapp.overlay
│  │  │  ├── prj.conf
│  │  │  ├── remote
│  │  │  │  ├── CMakeLists.txt
│  │  │  │  ├── prj.conf
│  │  │  │  ├── src
│  │  │  │  │  │ main.c
│  │  │  ├── src
│  │  │  │  │ main.c
│  │  │  ├── sysbuild.conf
│  │  │  ├── sysbuild
│  │  │  │  ├── mcuboot.overlay
│  │  │  │  ├── radio_loader
│  │  │  │  │  ├── boards
│  │  │  │  │  │  │ nrf54h20dk_nrf54h20_cpurad.overlay
│  │  │  │  │  │ prj.conf
│  │  │  │  ├── radio_loader_secondary_app.overlay
│  │  │  │  ├── remote_rad
│  │  │  │  │  ├── boards
│  │  │  │  │  │  │ nrf54h20dk_nrf54h20_cpurad.overlay
│  │  │  │  │  │ prj.conf
│  │  │  │  │ remote_rad_secondary_app.overlay
│  │  │  │ testcase.yaml
│  │  ├── radio_loader
│  │  │  ├── CMakeLists.txt
│  │  │  ├── app.overlay
│  │  │  ├── prj.conf
│  │  │  ├── src
│  │  │  │  │ main.c
│  │  │  │ testcase.yaml
soc
│  ├── nordic
│  │  ├── nrf54h
│  │  │  ├── Kconfig.defconfig
│  │  │  │ Kconfig.defconfig.nrf54h20_cpurad
sysbuild
│  ├── CMakeLists.txt
│  ├── Kconfig.radioloader
│  ├── Kconfig.sysbuild
│  │ radioloader.cmake

Outputs:

Toolchain

Version: 964ddb2c70
Build docker image: docker-dtr.nordicsemi.no/sw-production/ncs-build:964ddb2c70_5ea73affbf

Test Spec & Results: ✅ Success; ❌ Failure; 🟠 Queued; 🟡 Progress; ◻️ Skipped; ⚠️ Quarantine

  • ◻️ Toolchain - Skipped: existing toolchain is used
  • ✅ Build twister - Skipped: Skipping Build & Test as it succeeded in a previous run: 13
  • ❌ Integration tests
    • ✅ test-sdk-audio - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ desktop52_verification - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-fw-nrfconnect-apps - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test_ble_nrf_config - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-fw-nrfconnect-ble_mesh - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-fw-nrfconnect-ble_samples
    • ✅ test-fw-nrfconnect-chip - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-fw-nrfconnect-nfc - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-fw-nrfconnect-nrf-iot_libmodem-nrf - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-fw-nrfconnect-nrf-iot_zephyr_lwm2m - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-fw-nrfconnect-nrf-iot_samples - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-fw-nrfconnect-nrf-iot_lwm2m - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-fw-nrfconnect-nrf-iot_thingy91 - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-fw-nrfconnect-nrf_crypto - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-fw-nrfconnect-rpc - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-fw-nrfconnect-rs - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-fw-nrfconnect-fem - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-fw-nrfconnect-tfm - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-fw-nrfconnect-thread-main - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-sdk-find-my - Skipped: Job was skipped as it succeeded in a previous run
    • ❌ test-fw-nrfconnect-nrf_lrcs_positioning
    • ✅ test-sdk-wifi - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-low-level - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-sdk-mcuboot - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-sdk-dfu - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-fw-nrfconnect-ps-main - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-secdom-samples-public - Skipped: Job was skipped as it succeeded in a previous run

Note: This message is automatically posted and updated by the CI

sysbuild: true
tags:
- ci_build
- ci_tests_benchmarks_multicore
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wrong CI tag, it must follow path where tests/sample is located e.g. ci_samples_nrf54h20
This means, new tags should be created.

@zycz zycz requested review from a team and tejlmand November 24, 2025 08:22
Copy link
Contributor

@mkapala-nordic mkapala-nordic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some initial comments

@@ -0,0 +1,70 @@
/*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a reason why the optimized radio_loader configuration (prj.conf) is not already present here?
it would be nice to have it optimized from the start or to have reference how to configure it here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed it as it will never be used anyway as you have to place it in app/sysbuild/radio_loader/prj.conf - I don't want to duplicate configuration - but if you think it is worth doing I can add it back there.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume that there is no way to source this prj.conf always and just overlying it in the app if needed?
Do we need to modify prj.conf file in the app or the DTS overlay is enough?
Can't we apply only the overlay for it in the same way as sysbuild/radio_loader_secondary_app.overlay?

@zycz
Copy link
Contributor Author

zycz commented Nov 24, 2025

Rebased

Copilot AI review requested due to automatic review settings November 24, 2025 12:30
@zycz zycz requested a review from a team as a code owner November 24, 2025 12:30
@NordicBuilder NordicBuilder removed the changelog-entry-required Update changelog before merge. Remove label if entry is not needed or already added. label Nov 24, 2025
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 30 out of 30 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@zycz zycz requested a review from nordic-piks November 24, 2025 12:36
@github-actions
Copy link

@NordicBuilder
Copy link
Contributor

NordicBuilder commented Nov 25, 2025

Memory footprint analysis revealed the following potential issues

applications.nrf_desktop.zdebug.usb_next[nrf52840gmouse/nrf52840]: ROM size increased by 640[B] in comparison to the main[b708336] branch. - link (cc: @nrfconnect/ncs-si-bluebagel)
applications.nrf_desktop.zdebug_wwcb[nrf52840dk/nrf52840]: ROM size increased by 612[B] in comparison to the main[b708336] branch. - link (cc: @nrfconnect/ncs-si-bluebagel)
applications.nrf_desktop.zdebug[nrf52840gmouse/nrf52840]: ROM size increased by 608[B] in comparison to the main[b708336] branch. - link (cc: @nrfconnect/ncs-si-bluebagel)
applications.nrf_desktop.zdebug_dongle.usb_next[nrf52840dk/nrf52840]: ROM size increased by 684[B] in comparison to the main[b708336] branch. - link (cc: @nrfconnect/ncs-si-bluebagel)
applications.nrf_desktop.zdebug_fast_pair.gmouse[nrf52840gmouse/nrf52840]: ROM size increased by 576[B] in comparison to the main[b708336] branch. - link (cc: @nrfconnect/ncs-si-bluebagel)
applications.nrf_desktop.zdebug_mcuboot_smp[nrf52840dk/nrf52840]: ROM size increased by 604[B] in comparison to the main[b708336] branch. - link (cc: @nrfconnect/ncs-si-bluebagel)
applications.nrf_desktop.zdebug[nrf52833dk/nrf52833]: ROM size increased by 712[B] in comparison to the main[b708336] branch. - link (cc: @nrfconnect/ncs-si-bluebagel)
applications.nrf_desktop.zdebug_nrf21540ek_multicore[nrf5340dk/nrf5340/cpuapp]: ROM size increased by 560[B] in comparison to the main[b708336] branch. - link (cc: @nrfconnect/ncs-si-bluebagel)
applications.nrf_desktop.zdebug_nrf21540ek[nrf52840dk/nrf52840]: ROM size increased by 608[B] in comparison to the main[b708336] branch. - link (cc: @nrfconnect/ncs-si-bluebagel)
applications.nrf_desktop.zdebug[nrf52840dk/nrf52840]: ROM size increased by 608[B] in comparison to the main[b708336] branch. - link (cc: @nrfconnect/ncs-si-bluebagel)
applications.nrf_desktop.zdebugwithshell[nrf52840dk/nrf52840]: ROM size increased by 572[B] in comparison to the main[b708336] branch. - link (cc: @nrfconnect/ncs-si-bluebagel)
applications.nrf_desktop.zdebug_dongle[nrf52840dk/nrf52840]: ROM size increased by 664[B] in comparison to the main[b708336] branch. - link (cc: @nrfconnect/ncs-si-bluebagel)
applications.nrf_desktop.zdebug.usb_next[nrf52840dk/nrf52840]: ROM size increased by 608[B] in comparison to the main[b708336] branch. - link (cc: @nrfconnect/ncs-si-bluebagel)
applications.hpf.gpio.icbmsg[nrf54l15dk/nrf54l15/cpuflpr]: High RAM usage: 12744[B] - link (cc: @nrfconnect/ncs-ll-ursus)
applications.hpf.gpio.icbmsg[nrf54l15dk/nrf54l15/cpuflpr]: High ROM usage: 9492[B] - link (cc: @nrfconnect/ncs-ll-ursus)
applications.hpf.gpio.icmsg[nrf54l15dk/nrf54l15/cpuflpr]: High RAM usage: 9102[B] - link (cc: @nrfconnect/ncs-ll-ursus)
applications.hpf.gpio.icmsg[nrf54l15dk/nrf54l15/cpuflpr]: High ROM usage: 5858[B] - link (cc: @nrfconnect/ncs-ll-ursus)
applications.nrf_desktop.zdebug[nrf52833dongle/nrf52833]: ROM size increased by 712[B] in comparison to the main[b708336] branch. - link (cc: @nrfconnect/ncs-si-bluebagel)
applications.nrf_desktop.zdebug.usb_next[nrf52840dongle/nrf52840]: ROM size increased by 720[B] in comparison to the main[b708336] branch. - link (cc: @nrfconnect/ncs-si-bluebagel)
applications.nrf_desktop.zdebug[nrf5340dk/nrf5340/cpuapp]: ROM size increased by 560[B] in comparison to the main[b708336] branch. - link (cc: @nrfconnect/ncs-si-bluebagel)
applications.nrf_desktop.zdebug[nrf52840dongle/nrf52840]: ROM size increased by 700[B] in comparison to the main[b708336] branch. - link (cc: @nrfconnect/ncs-si-bluebagel)
applications.nrf_desktop.zdebug_4llpmconn[nrf52840dongle/nrf52840]: ROM size increased by 604[B] in comparison to the main[b708336] branch. - link (cc: @nrfconnect/ncs-si-bluebagel)
applications.nrf_desktop.zdebug_mcuboot_qspi[nrf52840dk/nrf52840]: ROM size increased by 608[B] in comparison to the main[b708336] branch. - link (cc: @nrfconnect/ncs-si-bluebagel)

Note: This message is automatically posted and updated by the CI (latest/sdk-nrf/PR-25737/13)

Update sdk-zephyr revision and enhance Kconfig handling.
If the 'fw-to-relocate' chosen node exists, the firmware will:
-  automatically calculate the Load Memory Address (LMA)
adjustment for firmware relocation.
- Modified Kconfig handling in cmake modules to accommodate
  a new property "fw-to-relocate".
- Ensured backward compatibility by
  falling back to "zephyr,code-partition"
if ther is not property "fw-to-relocate".

JIRA: NCSDK-36461

Signed-off-by: Jan Zyczkowski <[email protected]>
Copilot AI review requested due to automatic review settings November 26, 2025 07:25
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 35 out of 35 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +51 to +57
dt_chosen(fw_to_relocate_property PROPERTY "fw-to-relocate")
if("${line}" MATCHES "^CONFIG_FLASH_LOAD_OFFSET=.*$")
string(REGEX REPLACE "CONFIG_FLASH_LOAD_OFFSET=(.*)" "CONFIG_FLASH_LOAD_OFFSET=${code_partition_offset}" line ${line})
# Change the CONFIG_FLASH_LOAD_OFFSET value only if the fw_to_relocate_property is empty - meaning that the firmware is not being relocated.
if("${fw_to_relocate_property}" STREQUAL "")
string(REGEX REPLACE "CONFIG_FLASH_LOAD_OFFSET=(.*)" "CONFIG_FLASH_LOAD_OFFSET=${code_partition_offset}" line ${line})
endif()
endif()
Copy link

Copilot AI Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dt_chosen() call for fw_to_relocate_property is executed inside the loop for every line in dotconfig_content. This is inefficient as the chosen node value doesn't change between iterations. Move the dt_chosen(fw_to_relocate_property PROPERTY \"fw-to-relocate\") call outside the loop, before line 50.

Copilot uses AI. Check for mistakes.
@KAGA164
Copy link

KAGA164 commented Nov 26, 2025

My first approach to this feature was the same like here. However there is more better way to handle this. Overall, apart of redefining sram partition and changing zephyr, code partition the CONFIG_XIP kconfig option can be disabled and then this implementation can be simplified. Also the ram data section won't be copied twice and MPU will be set correctly. Additionally one commit from upstream Zephyr is mandatory to disable the CONFIG_XIP kconfig option: zephyrproject-rtos/zephyr@0dc2e0c

Hi, @KAGA164

Please provide proposed changes here so that there is no doubt that we can use them

It is very simple actually. You can disable CONFIG_XIP for image that is relocated to RAM memory. Then Zephyr build system will build image which is automatically linked against the zephyr,sram chosen property and no additional overlays with splitted RAM partitions are needed. What is more RAM data section won't be copied twice like now. First, it is copied with image from mram to ram then the image copies it second time from RAM to RAM on startup.

Comment on lines 27 to 28
#. Radio Loader - A small bootloader that runs on the radio core, copies firmware from MRAM to TCM, and jumps to it.
#. Remote Firmware - The actual application that runs from TCM after being loaded.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#. Radio Loader - A small bootloader that runs on the radio core, copies firmware from MRAM to TCM, and jumps to it.
#. Remote Firmware - The actual application that runs from TCM after being loaded.
* Radio Loader - A small bootloader that runs on the radio core, copies firmware from MRAM to TCM, and jumps to it.
* Remote Firmware - The actual application that runs from TCM after being loaded.

Comment on lines 81 to 92
#. TCM regions:

.. code-block:: devicetree
cpurad_ram0: sram@23000000 {
compatible = "mmio-sram";
reg = <0x23000000 0x20000>; /* 128 KB for code */
};
cpurad_data_ram: sram@23020000 {
compatible = "mmio-sram";
reg = <0x23020000 0x10000>; /* 64 KB for data */
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#. TCM regions:
.. code-block:: devicetree
cpurad_ram0: sram@23000000 {
compatible = "mmio-sram";
reg = <0x23000000 0x20000>; /* 128 KB for code */
};
cpurad_data_ram: sram@23020000 {
compatible = "mmio-sram";
reg = <0x23020000 0x10000>; /* 64 KB for data */
};
#. TCM regions:
.. code-block:: devicetree
cpurad_ram0: sram@23000000 {
compatible = "mmio-sram";
reg = <0x23000000 0x20000>; /* 128 KB for code */
};
cpurad_data_ram: sram@23020000 {
compatible = "mmio-sram";
reg = <0x23020000 0x10000>; /* 64 KB for data */
};

This doesn't render as expected.

Comment on lines 211 to 215
#. Build the firmware for the secondary app slot, increase the version number in the :file:`prj.conf` file (uncomment the line):

.. code-block:: kconfig
CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION="0.0.1+0"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#. Build the firmware for the secondary app slot, increase the version number in the :file:`prj.conf` file (uncomment the line):
.. code-block:: kconfig
CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION="0.0.1+0"
#. Build the firmware for the secondary app slot, increase the version number in the :file:`prj.conf` file (uncomment the line):
.. code-block:: kconfig
CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION="0.0.1+0"

* - zephyr,loaded-fw-dst: Destination region in RAM
*/

#define LOADED_FW_NVM_NODE DT_CHOSEN(zephyr_loaded_fw_src)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How this application recognized if the image should be copied from primary or secondary slot?

Copy link
Contributor Author

@zycz zycz Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the secondary slot image has dts.overlay which sets chosen node to correct address.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In a follow-up PR we'll update the Radio image to log the address of the slot it loaded from to demonstrate the correct one was used.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can just detect slot here apart of making overlays for secondary slot images. As reference you can check how application core boots radio core on nRF54h20

Copy link
Contributor

@grochu grochu Nov 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean to use the cpuapp_slot1_partition node like here: https://github.com/nrfconnect/sdk-zephyr/blob/main/soc/nordic/nrf54h/soc.c#L213?

memcpy((void *)LOADED_FW_RAM_ADDR, (void *)LOADED_FW_NVM_ADDR, LOADED_FW_NVM_SIZE);

/* Extract reset handler from ARM Cortex-M vector table (entry 1) */
uint32_t *vector_table = (uint32_t *)LOADED_FW_RAM_ADDR;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about MCUboot header, in some cases it is added at the beginning of the image and vector table is shifted? For example 800 bytes is reserved for nRF54H20

Copy link
Contributor Author

@zycz zycz Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't understand.

here we have MCUboot in direct-xip with merged slots so header is at the beginning of first image - in this case app - image

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Handling split slot required changes here to handle it, see draft PR 75048fa#diff-b40b584714f96c16fd14e46fe04bec2174736e6b2339c583d99fbc90eee41379R50

BOARD ${SB_CONFIG_NRF_RADIO_LOADER_BOARD}
BOARD_REVISION ${BOARD_REVISION}
)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it no needed?

Suggested change
set_target_properties(${radio_loader} PROPERTIES
IMAGE_CONF_SCRIPT ${ZEPHYR_BASE}/share/sysbuild/image_configurations/MAIN_image_default.cmake
)

Copy link
Contributor Author

@zycz zycz Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is only needed in case of split slot variant (see draft PR 75048fa#diff-11840703ce5ba60c7bd4cde5441eccec624524bcf41f016843ac38c0bdbb9711R22)

@grochu
Copy link
Contributor

grochu commented Nov 27, 2025

My first approach to this feature was the same like here. However there is more better way to handle this. Overall, apart of redefining sram partition and changing zephyr, code partition the CONFIG_XIP kconfig option can be disabled and then this implementation can be simplified. Also the ram data section won't be copied twice and MPU will be set correctly. Additionally one commit from upstream Zephyr is mandatory to disable the CONFIG_XIP kconfig option: zephyrproject-rtos/zephyr@0dc2e0c

Hi, @KAGA164
Please provide proposed changes here so that there is no doubt that we can use them

It is very simple actually. You can disable CONFIG_XIP for image that is relocated to RAM memory. Then Zephyr build system will build image which is automatically linked against the zephyr,sram chosen property and no additional overlays with splitted RAM partitions are needed. What is more RAM data section won't be copied twice like now. First, it is copied with image from mram to ram then the image copies it second time from RAM to RAM on startup.

This PR will remain in this default configuration. The optimization removing the CONFIG_XIP option will be added in another PR for NCS 3.2.0.

@shanthanordic
Copy link

Pr not ready, moved out of 3.2.0 scope

@shanthanordic shanthanordic removed this from the 3.2.0 milestone Nov 27, 2025
Copy link

@KAGA164 KAGA164 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving for speed-up integration. I would like to have support for splitted slots and simplified version with disabled CONFIG_XIP in NCS3.2.0

Copilot AI review requested due to automatic review settings November 27, 2025 12:04
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.


The overlay defines:

#. TCM regions:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#. TCM regions:
#. TCM regions:

Introduce a new sample demonstrating a multicore idle test
with firmware relocated to the radio core's TCM.
The test showcases the radio loader pattern, where firmware
is loaded from MRAM to TCM at runtime, ensuring efficient execution.

JIRA: NCSDK-36461

Signed-off-by: Jan Zyczkowski <[email protected]>
Copy link
Contributor

@tejlmand tejlmand left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Besides the misuse of kconf.cmake, then several warnings are seens when building this example:

CMake Warning:
  Manually-specified variables were not used by the project:

    EXTRA_KCONFIG_TARGETS
    FORCED_CONF_FILE

and

warning: UPDATEABLE_IMAGE_NUMBER (defined at
/projects/github/review/nrf/modules/../samples/common/mcumgr_bt_ota_dfu/Kconfig:87,
subsys/dfu/Kconfig:96) was assigned the value '1' but got the value ''. Check these unsatisfied
dependencies: (((BOARD_THINGY53_NRF5340_CPUAPP || BOARD_THINGY53_NRF5340_CPUAPP_NS) &&
SOC_SERIES_NRF53X && NCS_SAMPLE_MCUMGR_BT_OTA_DFU) || (!MCUBOOT && IMG_MANAGER)) (=n). See
http://docs.zephyrproject.org/latest/kconfig.html#CONFIG_UPDATEABLE_IMAGE_NUMBER and/or look up
UPDATEABLE_IMAGE_NUMBER in the menuconfig/guiconfig interface. The Application Development Primer,
Setting Configuration Values, and Kconfig - Tips and Best Practices sections of the manual might be
helpful too.


warning: MCUBOOT_UPDATE_FOOTER_SIZE (defined at subsys/dfu/Kconfig:55) was assigned the value '0x50'
but got the value ''. Check these unsatisfied dependencies: MCUBOOT_IMG_MANAGER (=n), IMG_MANAGER
(=n). See http://docs.zephyrproject.org/latest/kconfig.html#CONFIG_MCUBOOT_UPDATE_FOOTER_SIZE and/or
look up MCUBOOT_UPDATE_FOOTER_SIZE in the menuconfig/guiconfig interface. The Application
Development Primer, Setting Configuration Values, and Kconfig - Tips and Best Practices sections of
the manual might be helpful too.
warning: MCUBOOT_BOOTLOADER_USES_SHA512 (defined at modules/Kconfig.mcuboot:370) was assigned the
value 'y' but got the value 'n'. Check these unsatisfied dependencies: BOOTLOADER_MCUBOOT (=n). See
http://docs.zephyrproject.org/latest/kconfig.html#CONFIG_MCUBOOT_BOOTLOADER_USES_SHA512 and/or look
up MCUBOOT_BOOTLOADER_USES_SHA512 in the menuconfig/guiconfig interface. The Application Development
Primer, Setting Configuration Values, and Kconfig - Tips and Best Practices sections of the manual
might be helpful too.

the EXTRA_KCONFIG_TARGETS and FORCED_CONF_FILE warnings are probably unrelated to this PR, but the Kconfig errors seems related to this PR.

Comment on lines +32 to +36
dt_chosen(code_partition PROPERTY "fw-to-relocate")
if("${code_partition}" STREQUAL "")
dt_chosen(code_partition PROPERTY "zephyr,code-partition")
endif()

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but you're using devicetree to adjust Kconfig behind the scenes.

This file is kconfig.cmake, and kconfig.cmake is for kconfig handling and not intended for a devicetree handling / adjustments.

And before you start replying that devicetree is already done in this file, then I would like to direct to this PR #23562 .

This commit introduces a (probably temporary) way of fixing passing Kconfigs to a variant image.
...
Note: there were attempts to make a non-hack, clean fix in zephyr:
...
A quick solution for 3.1.0 is needed, as we already get complains about the issue

Starting to manipulate n-kconfig settings depending on featureA, featureB, featureC, ... etc is not scalable, and definitely not making it easier for NCS customers to adjust the solution to their needs without patching NCS itself.

Please take a look at the original implemetation for variant image e4be060 and notice how clean that is as it doesn't need special treatment for xyz settings.

just because something was introduced as a quick fix for 3.1 doesn't mean it's a proper way to do things.

@ahasztag why wasn't #23562 followed up after 3.1 was done ?

@grochu
Copy link
Contributor

grochu commented Dec 1, 2025

Will be substituted by #25891

@grochu grochu closed this Dec 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

doc-required PR must not be merged without tech writer approval.

Projects

None yet

Development

Successfully merging this pull request may close these issues.