2025-06-16 9:47 AM - edited 2025-06-16 11:14 AM
Hello,
I have been modifying the OEMUROT_Boot application and associated build scripts in ROT provisioning to complement our custom firmware project. (See my previous post on this topic for details). This is for the STM32N6, using the DK discovery kit.
I have gotten to the point where the builds all seem to work, I program the external memory on the DK board with the bootloader and my custom firmware, and attempt to launch.
The OEMUROT_Boot traces do show up in Tera Term:
[INF] TAMPER Activated
[INF] Starting bootloader OEMuROT 00000001
[INF] Primary image: magic=bad, swap_type=0x3, copy_done=0x2, image_ok=0x2
[INF] Scratch: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
[INF] Boot source: none
[INF] Swap type: perm
[INF] 1, 7e, cf, 18, ef, 4e , 89 ,a7,
[INF] f7, ac, f6, 5a, 4f, 91 , ac ,d5,
[INF] Image version 0 : 01000000
[INF] Counter 0 get 0x0
[INF] verify counter 0 0 0
[INF] counter 0 : ok
[INF] verify sig key id 0
[INF] checking public key 46 5b
[INF] verifying signature hlen 20
[INF] signature OK
[INF] Image upgrade secondary slot -> primary slot
[INF] Erasing the primary slot
[INF] Copying the secondary slot to the primary slot: 0x10000 bytes
[INF] Counter 0 set to 0x0
[INF] Counter 0 set to 0x0
[INF] Starting validation of primary slot(s)
[INF] Image version 0 : 01000000
[INF] Counter 0 get 0x0
[INF] verify counter 0 0 0
[INF] counter 0 : ok
[INF] verify sig key id 0
[INF] checking public key 46 5b
[INF] verifying signature hlen 20
[INF] signature OK
[INF] Bootloader chainload address offset: 0x80000
[INF] Jumping to the first image slot
However, my custom application (a test project built using CMake that blinks the user LED) does not seem to launch.
When I import the blinky app as a STM32 Executable into CubeIDE, I can launch a debug session and see the LED blinking so I believe the firmware works. I think that maybe I have misconfigured the bootloader and it is jumping to the wrong location and want to debug this.
The boot traces indicate that it is jumping to address offset 0x80000, but the information I see in the linker script and flash_layout.h, region_defs.h files look much different. I understand why the value is 0x80000, for the BL2 define, but am not sure where to begin investigating what the application jump address is and confirming that it is jumping to the correct location.
flash_layout.h:
/* Flash layout configuration : begin ****************************************/
#define NO_LOAD_AND_RUN (0) /* OEMuROT_Boot uses "Execute In Place" */
#define LOAD_AND_RUN_INT_RAM (1) /* OEMuROT_Boot uses "Load & Run" with internal RAM memory */
#define LOAD_AND_RUN_EXT_RAM (2) /* OEMuROT_Boot uses "Load & Run" with external RAM memory */
#define OEMUROT_LOAD_AND_RUN LOAD_AND_RUN_INT_RAM /* Flag configuring the feature "Load and Run" */
//#define MCUBOOT_OVERWRITE_ONLY /* Defined: the FW installation uses overwrite method.
// Undefined: The FW installation uses swap mode. */
#define MCUBOOT_S_DATA_IMAGE_NUMBER 0 /* 1: S data image for S application.
0: No S data image. */
#define MCUBOOT_NS_DATA_IMAGE_NUMBER 0 /* 1: NS data image for NS application.
0: No NS data image. */
/* Flash layout configuration : end ******************************************/
/* Use image hash reference to reduce boot time (signature check bypass) */
#define MCUBOOT_USE_HASH_REF
#define MCUBOOT_USE_MCE /* The external flash is protected by MCE */
/* Total number of images */
#define MCUBOOT_APP_IMAGE_NUMBER 1 /* Two separated images for S and NS application binaries */
#define MCUBOOT_IMAGE_NUMBER (MCUBOOT_APP_IMAGE_NUMBER + MCUBOOT_S_DATA_IMAGE_NUMBER + MCUBOOT_NS_DATA_IMAGE_NUMBER)
/* Flash layout info for BL2 bootloader */
#define EXT_FLASH_SECTOR_SIZE (0x10000) /* External Flash: 64 KB */
#define EXT_FLASH_TOTAL_SIZE (0x08000000) /* External Flash: 128 MBytes */
#define EXT_FLASH_BASE_ADDRESS (0x70000000) /* External Flash (XSPI2 + MCE2 - AES) */
#define EXT_RAM_BASE_ADDRESS (0x90000000) /* External RAM (XSPI1 + MCE1 - AES) */
#define FLASH_AREA_IMAGE_SECTOR_SIZE EXT_FLASH_SECTOR_SIZE /* External Flash: 64 KB */
#define FLASH_BASE_ADDRESS EXT_FLASH_BASE_ADDRESS
, region_defs.h:
/* BL2 regions */
#define BL2_OFFSET (0x80000)
#define BL2_CODE_OFFSET (BL2_OFFSET + BOOTROM_HEADER_SIZE)
#define BL2_CODE_START (S_RAM_ALIAS(BL2_CODE_OFFSET))
#define BL2_CODE_SIZE (FLASH_AREA_BL2_SIZE - BL2_JUMP_CODE_SIZE \
- BOOTROM_HEADER_SIZE)
#define BL2_CODE_LIMIT (BL2_CODE_START + BL2_CODE_SIZE - 1)
...
#elif (OEMUROT_LOAD_AND_RUN == LOAD_AND_RUN_INT_RAM)
/* Secure regions */
#define S_CODE_START (S_RAM_ALIAS(0))
#define S_DATA_START (S_RAM_ALIAS(0xE0000))
#define S_DATA2_START (S_RAM_ALIAS(0xF0000))
/* Non-secure regions */
#define NS_CODE_START (NS_RAM_ALIAS(0x64000))
#define NS_DATA_START (NS_RAM_ALIAS(0xE4000))
#define NS_DATA2_START (NS_RAM_ALIAS(0xF0000))
STM32N657XX_LRUN.ld
CODE_S_ADDRESS = 0x34100400; /* This define is updated automatically from OEMuROT_Boot project */
CODE_S_SIZE = 0x10000; /* This define is updated automatically from OEMuROT_Boot project */
DATA_S_ADDRESS = 0x341e0000; /* This define is updated automatically from OEMuROT_Boot project */
DATA_S_SIZE = 0x10000; /* This define is updated automatically from OEMuROT_Boot project */
IMAGE_HEADER_SIZE = 0x400; /* mcuboot header size */
TRAILER_MAX_SIZE = 0x2000; /* mcuboot trailer max size */
/* Entry Point */
ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */
_sstack = _estack - _Min_Stack_Size;
_Min_Heap_Size = 0x200; /* required amount of heap */
_Min_Stack_Size = 0x900; /* required amount of stack */
/* Memories definition */
MEMORY
{
ROM (rx) : ORIGIN = CODE_S_ADDRESS, LENGTH = CODE_S_SIZE - IMAGE_HEADER_SIZE - TRAILER_MAX_SIZE
RAM (rwx) : ORIGIN = DATA_S_ADDRESS, LENGTH = DATA_S_SIZE
}
I referenced flash_programming.sh to determine where to flash the bootloader and application binaries:
flash_programming.sh
# Data updated with the postbuild of OEMuROT-Boot
bootaddress=0x70000000
appli_s_address=0x700B0000
data_s_address=0x0
appli_ns_address=0x700C0000
data_ns_address=0x0
s_data_image_number=0x0
ns_data_image_number=0x0
last_sector=16
So I used STM32CubeProgrammer to flash the OEMUROT_Boot_Trusted.bin to 0x70000000, my application firmware to 0x700B0000. I moved BOOT1 back to 0 (low), and then un-plugged and re-plugged the board from power (USB to my PC).
If anyone could give me a hint on how to figure out why my application is not running, I would be very thankful!
Best regards.
2025-06-16 10:57 AM - edited 2025-06-16 11:13 AM
I added some debugging prints to the do_boot() function in bl2_main.c:
if (rsp->br_hdr->ih_flags & IMAGE_F_RAM_LOAD) {
/* The image has been copied to SRAM, find the vector table
* at the load address instead of image's address in flash
*/
vt = (struct boot_arm_vector_table *)(rsp->br_hdr->ih_load_addr +
rsp->br_hdr->ih_hdr_size);
BOOT_LOG_INF("Image copied to SRAM, vt->reset addr 0x%x", vt->reset);
} else {
/* Using the flash address as not executing in SRAM */
vt = (struct boot_arm_vector_table *)(flash_base +
rsp->br_image_off +
rsp->br_hdr->ih_hdr_size);
BOOT_LOG_INF("Using flash address (should not happen)");
}
It printed the flash address string. This led me to realizing that IMAGE_F_RAM_LOAD is defined but the flag is never set, and that MCUBOOT_RAM_LOAD is not defined. Seems I need to figure out why it is not and then enable it. Maybe in mcuboot_config.h or another location?
2025-06-16 11:51 AM - edited 2025-06-16 12:02 PM
I defined the symbol MCUBOOT_RAM_LOAD in mcuboot_config.h:
// RAM_START from region_defs.h _SRAM2_AXI_BASE_S
#define IMAGE_EXECUTABLE_RAM_START (0x34100000)
// RAM_SIZE from region_defs.h _SRAM2_AXI_SIZE
#define IMAGE_EXECUTABLE_RAM_SIZE (0x100000)
#define MCUBOOT_RAM_LOAD
along with the symbols mentioned in the MCUboot documentation. I am still looking for the best place in the build scripts to modify and add the --load-addr option.
However, that may be a moot point, because when I tried to build to OEMUROT_Boot project, there is an error generated in bootutil_priv.h, around line 195, indicating that image encryption is not supported.
C\Users\my_user\STM32Cube\Repository\STM32Cube_FW_N6_V1.1.1\Middlewares\Third_Party\mcuboot\boot\bootutil\src\bootutil_priv.h
#if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD)
#define ARE_SLOTS_EQUIVALENT() 0
#else
#define ARE_SLOTS_EQUIVALENT() 1
#if (BOOT_IMAGE_NUMBER != 1)
#error "The MCUBOOT_DIRECT_XIP and MCUBOOT_RAM_LOAD mode only supports single-image boot (MCUBOOT_IMAGE_NUMBER=1)."
#endif
#ifdef MCUBOOT_ENC_IMAGES
#error "Image encryption (MCUBOOT_ENC_IMAGES) is not supported when MCUBOOT_DIRECT_XIP or MCUBOOT_RAM_LOAD mode is selected."
#endif
#endif /* MCUBOOT_DIRECT_XIP || MCUBOOT_RAM_LOAD */
However, the ST wiki page for OEMuRoT for STM32N6 gives me the impression that encryption is indeed supported.
I have not fully gone through the tutorial steps in Security:How to start with OEMuRoT on STM32N6 MCUs - stm32mcu as I do not have IAR EWARM. I could try going through using STM32CubeIDE to build the projects maybe, though I would need to modify my env.sh and postbuild.sh scripts to use the OEMUROT_Appli project instead of our custom firmware application.
I guess my question is, is image encryption truly not supported if using the RAM load mode?
And, can we only have 1 application image then? Only secure application, none of [secure data, non-secure application, non-secure data].
2025-06-16 1:18 PM - edited 2025-06-16 1:24 PM
I cloned the STM32N6 firmware package from GitHub, then went through the steps in How to start with OEMuRoT on STM32N6 MCUs using STM32CubeIDE. Everything built and ran out of the box, and I successfully updated the non-secure application. I did notice that the bootloader chain address offset is also 0x80000 in this case as well.
I noticed that bootutil_priv.h file is the same, and in this case MCUBOOT_IMAGE_NUMBER is 4 (1 secure app + 1 non-secure app + 1 secure data + 1 non-secure data). Neither MCUBOOT_DIRECT_XIP or MCUBOOT_RAM_LOAD are defined as well. The symbol ARE_SLOTS_EQUIVALENT() is defined to be 0, and the rest of that block is greyed out in CubeIDE, so I know the two symbols are not defined.
#ifdef MCUBOOT_IMAGE_NUMBER
#define BOOT_IMAGE_NUMBER MCUBOOT_IMAGE_NUMBER
#else
#define BOOT_IMAGE_NUMBER 1
#endif
_Static_assert(BOOT_IMAGE_NUMBER > 0, "Invalid value for BOOT_IMAGE_NUMBER");
#if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD)
#define ARE_SLOTS_EQUIVALENT() 0
#else
#define ARE_SLOTS_EQUIVALENT() 1
#if (BOOT_IMAGE_NUMBER != 1)
#error "The MCUBOOT_DIRECT_XIP and MCUBOOT_RAM_LOAD mode only supports single-image boot (MCUBOOT_IMAGE_NUMBER=1)."
#endif
#ifdef MCUBOOT_ENC_IMAGES
#error "Image encryption (MCUBOOT_ENC_IMAGES) is not supported when MCUBOOT_DIRECT_XIP or MCUBOOT_RAM_LOAD mode is selected."
#endif
#endif /* MCUBOOT_DIRECT_XIP || MCUBOOT_RAM_LOAD */
What this is telling me is that:
I also am unclear on the difference between the app images and the data images, if anybody can shed light on that?
Thank you.
2025-06-16 4:00 PM
In the call to boot_platform_quit(vt); I have confirmed that the address pointed to by vt->reset is 0x3410b8bd. I copied over the linker script from the example OEMUROT_Appli (and needed to add a + 8K to the ROM region otherwise it overflowed) to make them the same. So that confirms it's running in RAM (AXISRAM2 specifically), even though OEMUROT_Boot is not configured for RAM load mode.
I also confirmed that MCUBOOT_RAM_LOAD is not defined in the out-of-box example OEMUROT_Boot.