cancel
Showing results for 
Search instead for 
Did you mean: 

STM32U5A5 Jump to Bootloader from ThreadX Application with TrustZone enabled

SDSigma
Associate

I'm currently using a NUCEO-U5A5ZJ-Q development board and having an issue jumping from the Application code into the Bootloader. Two major issues are the Application is running ThreadX, and the board has the TrustZone enabled.

Through experimentation, I've determined how to successfully jump into the bootloader when the TrustZone is disabled. Effectively, the code to jump into the bootloader must be done BEFORE executing the "MX_ThreadX_Init( )" instruction in main.c. Any attempt to jump into the bootloader after the MX_ThreadX_Init call results in a HardFault during the execution (initialization?) of the bootloader code.

However, now with the TrustZone enabled, I have been unsuccessful at bringing up the bootloader code without a HardFault being generated. The jump into the System Memory bootloader at 0x0BF90000 is successful, but always results in a HardFault due to trying to access a NULL value during the execution (initialization?) of the bootloader code.

Is there any advice you can give me to on how to get this to work?

Some questions I have:

  • does the application code that contains the bootloader jump instructions need to be in the secure section, nonsecure section, or a mix of both?
  • are there additional processor registers that must be initialized before the jump?
  • are there any special settings needed in either the Option Bytes or the STM32CubeMX configuration?

Thank you!

Steve.

5 REPLIES 5
STea
ST Employee

Hello @SDSigma ,

are you attempting to jump from bootloader from secure or non-secure context?
can you share the sequence in which you attempt the jump as this can be related to security constrains.
Regards 

 

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

I have tried to jump to the bootloader from both the main.c in the secure side and also from main.c in the nonsecure side with similar results. The bootloader is entered using either method as I can step through the System Memory Bootloader assembly code within the STM32CubeIDE debugger, however both always end in a HardFault when allowed to run.

The code being used to jump to the bootloader is as follows:

 

 

void jump_to_bootloader( void )
{
    uint32_t ndx;

    void (*SysMemBootJump)( void );     /* Prototype for the jump function */

    /* Disable all interrupts */
    __disable_irq();

    /* Disable Systick timer */
    SysTick->CTRL = 0;

    /* Set the clock to the default state */
    HAL_RCC_DeInit();

    /* De-initialize all peripherals */
    HAL_DeInit();

    /* Clear Interrupt Enable Register & Interrupt Pending Register */
    for( ndx = 0; ndx < sizeof(NVIC->ICER) / sizeof(NVIC->ICER[0]); ndx++ )
    {
        NVIC->ICER[ndx] = 0xFFFFFFFF;
        NVIC->ICPR[ndx] = 0xFFFFFFFF;
    }

    /* Re-enable all interrupts */
    __enable_irq();

    /* Set up the jump to bootloader address + 4 */
    SysMemBootJump = (void (*)(void))(*(uint32_t *)(BOOTLOADER_ADDRESS + 4));

    /* Set the main stack pointer to the boot loader stack */
    __set_MSP(*(uint32_t *)BOOTLOADER_ADDRESS);

    /* Call the function to jump to boot loader location */
    SysMemBootJump();

    /* Should never get here */
    for( ; ; ) { }
}

 

 

The two places I've tried calling the function:

 

// From main.c in the secure project

int main(void)
{
  /* SAU/IDAU, FPU and interrupts secure/non-secure allocation setup done */
/* in SystemInit() based on partition_stm32u5a5xx.h file's definitions. */

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the System Power */
  SystemPower_Config();
  /* GTZC initialisation */
  MX_GTZC_S_Init();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_SPI2_Init();
  /* USER CODE BEGIN 2 */

  /* Jump to the bootloader BEFORE initializing the nonsecure code */
  jump_to_bootloader();

  /* USER CODE END 2 */

  /*************** Setup and jump to non-secure *******************************/

  NonSecure_Init();

 

 

 

// From main.c on the nonsecure project

int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_ICACHE_Init();
  MX_SPI1_Init();
  /* USER CODE BEGIN 2 */

    /* Call to jump to bootloader here BEFORE calling the ThreadX init */
    jump_to_bootloader();

  /* USER CODE END 2 */

  MX_ThreadX_Init();

 

 

STea
ST Employee

Hello @SDSigma ,

"The bootloader is entered using either method as I can step through the System Memory Bootloader assembly code within the STM32CubeIDE debugger"
you are able to jump to bootloader and execute then a hardfault occurs can you give more details about the hardfault and what caused it as this is not related to the jump process if i get you right just note that Products with security using TrustZone isolation - Boot_V3 including the U5 series
a) Boot depending on TrustZone value - Boot_V3_1 (see Figure 11) When TZEN is enabled, some constraints are added to the BL functionalities:
> Boot timing is different from the TZEN disabled use case
> Before jumping to the BL, the SFSP maps all the needed resources by the BL
to the non-secure domain. A jump from the BL (“Go” command) to an application using other resources does not work.
> Some secure option bytes are not accessible as the bootloader is non-secure. Some APIs are added on the SFSP to guarantee that the BL can modify them on open products states (Open, RDP L0).
> Some parts of the SRAM are used by the SFSP and remain on Secure domain when jumping to the BL, so are not accessible by the customer through BL
see section 4.10 of AN2606
 for more details.
Regards

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
olivierxpmetal
Associate

Hello,

I may be mistaken, but I believe I read in the reference manual that when TZ is active, the bootloader present in the MCU's ROM may no longer be accessible.

For security reasons, the MCU is forced to boot from address SECBOOTADD0 or within the RSS zone. This information also depends on the RDP level, which can prevent access to the RSS.

You can find this information in section 3 of the reference manual RM0456, pages 191 and 192.

SDSigma
Associate

Thank you to all that have replied to this topic.

Since the software solution looks to be difficult (or maybe not possible), we have instead decided on a hardware/software solution to get the unit into bootloader mode. 

Hardware portion:

  • Install a 10uF capacitor in parallel with the 10K ohm pull-down resistor to the BOOT0 pin. Note the 10K is existing on the NUCLEO-U5A5JZ-Q dev board and the 10uF cap was one I had available. For the production hardware, the capacitance will be reduced and the pull-down resistance increased.

Software portion:

  • Configure the BOOT0 pin as a GPIO output with the initial value set low.
  • To jump into the bootloader:
    • Assert a high signal on the BOOT0 pin.
    • Wait about a second for the capacitor to charge.
    • Issue a NVIC_SystemReset() call to reset the processor.

When the processor resets, the BOOT0 pin will still be high so it will jump into the bootloader.

After a number of seconds, the capacitor will discharge so any subsequent resets will return to normal boots.