Code relocation to the external flash with Mcuboot

Hello,

I am using edge impulse library to achieve on-device classification. I now want to put the edge impulse related code to the external flash and use XIP function there rather than placing them inside my internal flash. I have learned something from the code relocation sample from NCS and zephyr. I now have my own linker script, modified CMakeList and prj.conf, which I show below. For cmakelist: 

zephyr_code_relocate(FILES src/feature/gait_analysis.c LOCATION EXTFLASH_TEXT NOCOPY)
zephyr_code_relocate(FILES src/feature/gait_analysis.c LOCATION EXTFLASH_RODATA NOCOPY)
For linker script: 
#include <zephyr/linker/sections.h>
#include <zephyr/devicetree.h>
#include <zephyr/linker/linker-defs.h>
#include <zephyr/linker/linker-tool.h>

MEMORY
{
    /* XIP region for Edge Impulse model code + rodata */
    EXTFLASH (rx) : ORIGIN = 0x10120000, LENGTH = 0x00400000
}
#include <zephyr/arch/arm/cortex_m/scripts/linker.ld>
and for prj.conf: 
CONFIG_CODE_DATA_RELOCATION=y
CONFIG_XIP=y
CONFIG_NORDIC_QSPI_NOR_XIP=y
CONFIG_HAVE_CUSTOM_LINKER_SCRIPT=y
CONFIG_CUSTOM_LINKER_SCRIPT="linker_arm_nocopy.ld"
. The build process can show part of the code is indeed placed into our external flash partition. But it is complaining about this: Error: Image size (0x10110be8) + trailer (0x630) exceeds requested size 0xe0000. I suspect this is because the relocated section is still included in the mcuboot binary image. We will need to keep mcuboot because we want to use dfu-util on our host machine for firmware upgrade. Is there a way to solve this issue? 

Parents Reply Children
  • Hi there,

    The error you’re seeing:

    Image size (0x10110be8) + trailer (0x630) exceeds requested size 0xe0000

    comes from the way MCUboot calculates the image size. It uses the lowest and highest load addresses in the linked image (__rom_start__ and __rom_end__).

    Because your XIP sections are linked into external flash at 0x10120000, the linker now thinks your application image runs from internal flash up to 0x1012xxxx, so the “image size” becomes enormous. That’s why it no longer fits into the configured slot (0xE0000).

    MCUboot doesn’t support a single signed image that spans both internal flash and an external XIP region like that. The usual patterns are:

    1. Keep the MCUboot-managed image entirely in internal flash, and treat the QSPI/XIP region as a separate asset that you program/update independently.

    2. Use NCS Partition Manager to define an external-flash partition and build the XIP code as another image or artifact, updated via a second DFU alt-setting or a custom mechanism.

    If you must keep MCUboot + dfu-util, the simplest fix is to move your XIP code out of the MCUboot image: don’t let the external flash MEMORY and sections extend __rom_end__. Keep the MCUboot app confined to internal flash, and handle the model/QSPI content separately.

    HTH

    GL :-) PJ :v:

Related