cancel
Showing results for 
Search instead for 
Did you mean: 

H753ZI board unaccessible after download of incomplete secure boot

EBonv
Associate III

Hello,

I want to integrate a secure boot and secure software update (SBSFU) on a nucleo H753ZI board.

I downloaded the software from https://www.st.com/en/embedded-software/x-cube-sbsfu.html and followed the steps to compile the three programs (SECore, SBSFU and UserApp) proposed in the "projects" folder using the 1-image version of the SBSFU.

The next step was to program the SBSFU application on the board which I tried to do using STM32CubeProgrammer. However, the program has not been completely installed. The first image below shows the device memory after the introduction of the application and the second image shows what should have been programmed. You can observe that the code abruptly stops after the address 0x08000100 while it should continue.0693W00000APJdCQAX.png0693W00000APJd7QAH.png 

I suspect that something went wrong when I prepared the board and that the region after 0x08000100 has been mistakenly let as an area protected against writing.

My problem is that since this incomplete code has been inserted inside the board, I can not access it in normal mode using STM32CubeProgrammer, I get a  DEV_TARGET_NOT_HALTED error. The only way I can connect to the board is through hot plug mode. But from there I am unable to change any configuration, erase the memory or program anything else on the board.

Is there any way to somehow reset the board, or force it to clean anything that has been programmed on it to put it out from its idle and non-available state?

Any suggestions are welcome.

Thank you in advance.

1 ACCEPTED SOLUTION

Accepted Solutions
alister
Lead

X-CUBE-SBSFU is an example. You need to integrate your requirements, remove the parts you don't want, fix its problems and debug it.

Suggest separate it into Debug and Release builds, and use a different key and configure no protections for your Debug builds.

Use STM32CubeProgrammer or similar to clear any protections

Build, load and debug your Debug SBSFU using the debugger. Satisfy yourself that it's executing, checking there's nothing to install and checking there's no active UserApp to execute.

Then build load and debug your UserApp with the debugger. Satisfy yourself that the UserApp is executing and performing something you can measure.

When you're satisfied both the SBSFU and the UserApp are excuting ok, prepare an image of the UserApp and load it into the install region (slot #1), and load SBSFU using the debugger and check it installs it correctly.

Note, after loading an image into slot #1, any reset will cause the SBSFU to install it. So you want the SBSFU in flash to not execute until you've loaded it with the debugger. You can do that by adding some code like this to its main() function:

int startWait = 1;
int main(void)
{
  while (startWait);
  ...

On reset, the SBSFU will loop and do nothing.

But when you load the SBSFU with the debugger, you zero the startWait variable to allow it to execute.

View solution in original post

13 REPLIES 13
alister
Lead

X-CUBE-SBSFU is an example. You need to integrate your requirements, remove the parts you don't want, fix its problems and debug it.

Suggest separate it into Debug and Release builds, and use a different key and configure no protections for your Debug builds.

Use STM32CubeProgrammer or similar to clear any protections

Build, load and debug your Debug SBSFU using the debugger. Satisfy yourself that it's executing, checking there's nothing to install and checking there's no active UserApp to execute.

Then build load and debug your UserApp with the debugger. Satisfy yourself that the UserApp is executing and performing something you can measure.

When you're satisfied both the SBSFU and the UserApp are excuting ok, prepare an image of the UserApp and load it into the install region (slot #1), and load SBSFU using the debugger and check it installs it correctly.

Note, after loading an image into slot #1, any reset will cause the SBSFU to install it. So you want the SBSFU in flash to not execute until you've loaded it with the debugger. You can do that by adding some code like this to its main() function:

int startWait = 1;
int main(void)
{
  while (startWait);
  ...

On reset, the SBSFU will loop and do nothing.

But when you load the SBSFU with the debugger, you zero the startWait variable to allow it to execute.

As stated in the original question, my problem is that I can not access the board anymore in a mode other than hot plug mode as the board never halts.

Unfortunately, in this mode I do not seem to be able to clear the protections using STM32CubeProgrammer and I am unable to program anything else on the board. Using the debugger does not help either.

>The next step was to program the SBSFU application on the board which I tried to do using STM32CubeProgrammer.

This is enthusiastic and trusting. My post describes cautious steps. I've only developed custom boards. I can imagine if software purports to exactly support your dev board you may expect it to work. Even so, X-CUBE-SBSFU is example code.

>However, the program has not been completely installed. The first image below shows the device memory after the introduction of the application

The terms program, install and application may be ambiguous. Anything I say is guessing. Maybe something here will help.

X-CUBE-SBSFU uses the term "install" to describe the decrypting and writing the application into slot#0; the active region. But your first image is of STM32CubeProgrammer with the SBSFU.elf loaded. That's the boot code and not the application. So you've programmed only the SBSFU.elf to flash?

>My problem is that since this incomplete code has been inserted inside the board,

STM32CubeProgrammer would completely program the SBSFU.elf to flash, else it should have thrown an error, or the SBSFU.elf is incomplete and was programmed successfully. Perhaps inspect your link map file or elf file to ascertain if the SBSFU is good/complete. If you didn't output a map file, you might use "objdump.exe -t SBSFU.elf". Look for the addresses and sizes of each of the protections. You will find their symbol names in the code.

>My problem is that since this incomplete code has been inserted inside the board, I can not access it in normal mode using STM32CubeProgrammer, I get a DEV_TARGET_NOT_HALTED error. The only way I can connect to the board is through hot plug mode. But from there I am unable to change any configuration, erase the memory or program anything else on the board.

Perhaps check https://community.st.com/s/article/FAQ-Unable-to-connect-to-STM32H7-devices for ideas. It mentions ST-Link Utility and I've had to use that over STM32CubeProgrammer in the past.

EBonv
Associate III

Thank you very much for the detailed answer.

To be precise about my statement concerning programming the SBSFU, I refer to the step 4 of the "how to use section" at the end of the README I join to this reply. They indeed use the term "load" and a I used the wrong term. This README is the one I followed but things did not work as expected after this step 4.

  • I am unable to connect the board through Tera Term (I actually use minicom as I am on Ubuntu but it should still work the same). I do not get the welcome information which should show up if the SBSFU is correctly loaded.
  • The green LED does not blink in any manner described in the README.

I do realize that X-CUBE-SBSFU is an example. But correct me if I'm wrong (I may very well have misunderstood something, I am not used to the STM products), here is what I think:

  • The SBSFU is the application that is used to set up a secure boot environment on the board.
  • The UserApp is the example application which just makes a few LEDs blink.

So far, I only loaded the SBSFU and I should use minicom to load the UserApp as an example (before loading the real code I want to use).

I do think the SBSFU has been incompletely loaded. The SBSFU application is 2,6MB large and should have modified the memory of the board from the address 0x08000000 to 0x080050BF. However, in the board memory, only the bytes from address 0x08000000 to 0x080000FF have been modified to the correct values. The rest is set to 0. In the two images I linked to the first post, the first ones displays that only zeros are written beyond 0x080000FF while SBSFU.elf has non-zero values beyond that point.

I also had a look at https://community.st.com/s/article/FAQ-Unable-to-connect-to-STM32H7-devices but it seems that I am not able to connect to the board through STLINK either.

>SBSFU is the application

It'd help me and probably others if we called the SBSFU the SBSFU or the boot code, and use application only for the application. That's old school.

>So far, I only loaded the SBSFU and I should use minicom to load the UserApp as an example (before loading the real code I want to use).

See my first post.

My first impression when I read this'd been built and programmed without debugging and without complete knowledge was "what the heck".

But I don't drive formula 1 either.

>The SBSFU application is 2,6MB large and should have modified the memory of the board from the address 0x08000000 to 0x080050BF.

That address range is 20672 bytes. 2,6MB would be elf file's size and is meaningless.

>I do think the SBSFU has been incompletely loaded. <snip> only the bytes from address 0x08000000 to 0x080000FF have been modified to the correct values. 

But later you say " it seems that I am not able to connect to the board through STLINK either".

You must have "connected" to ascertain "only the bytes from address 0x08000000 to 0x080000FF have been modified".

You haven't provided any new information to help me assist.

Guessing... PCROP regions are 0x100-byte aligned and possibly STM32CubeProgrammer incorrectly displays 0s for unsuccessful read accesses.

In my second post I said "Look for the addresses and sizes of each of the protections". Inspect the code and its outputs. What protections does your SBSFU configure? What are their addresses/sizes?

You'll need to complete these steps:

  1. recover your board
  2. determine why the SBSFU doesn't work
  3. fix it

1 and 2 may be performed in any order. But if you do 1 without learning everything, your 3 may be incomplete or low quality.

Using (an old version) STM32CubeProgrammer and selecting verbosity level 3, an ST-LINK/V2 and an STM32H7 board, this is what it logs for me:

09:46:49 : STM32CubeProgrammer API v2.3.0
09:46:52 : ST-LINK SN : 52FF71065185525314290187
09:46:52 : ST-LINK FW : V2J35S7
09:46:52 : Voltage : 3.20V
09:46:52 : SWD freq : 4000 KHz
09:46:52 : Connect mode: Normal
09:46:52 : Reset mode : Software reset
09:46:52 : Device ID : 0x450
09:46:52 : UPLOADING OPTION BYTES DATA ...
09:46:52 : Bank : 0x00
09:46:52 : Address : 0x5200201c
09:46:52 : Size : 308 Bytes
09:46:52 : UPLOADING ...
09:46:52 : Size : 1024 Bytes
09:46:52 : Address : 0x8000000
09:46:52 : Read progress:
09:46:52 : Data read successfully
09:46:52 : Time elapsed during the read operation is: 00:00:00.007
09:47:53:425 : Disconnected from device.
09:47:54:315 : STLinkUSBDriver.dll loaded
09:47:54:315 : STLinkUSBDriver.dll loaded
09:47:54:316 : ST-LINK SN : 52FF71065185525314290187
09:47:54:316 : ST-LINK FW : V2J35S7
09:47:54:316 : Voltage : 3.21V
09:47:54:320 : SWD freq : 4000 KHz
09:47:54:320 : Connect mode: Normal
09:47:54:320 : Reset mode : Software reset
09:47:54:396 : Device ID : 0x450
09:47:54:545 : Buffer program...
09:47:54:547 : w ap 0 @0x580244F4 0x00000004 bytes
09:47:54:547 : Reading data...
09:47:54:547 : r ap 0 @0x58000528 0x00000004 bytes
09:47:54:547 : Buffer program...
09:47:54:549 : w ap 0 @0x580244F4 0x00000004 bytes
09:47:54:549 : Reading data...
09:47:54:551 : r ap 0 @0x58000528 0x00000004 bytes
09:47:54:551 : Buffer program...
09:47:54:551 : w ap 0 @0x580244F4 0x00000004 bytes
09:47:54:551 : Reading data...
09:47:54:553 : r ap 0 @0x58000528 0x00000004 bytes
09:47:54:553 : Buffer program...
09:47:54:554 : w ap 0 @0x580244F4 0x00000004 bytes
09:47:54:554 : Reading data...
09:47:54:556 : r ap 0 @0x58000528 0x00000004 bytes
09:47:54:557 : Reading data...
09:47:54:557 : r ap 0 @0x1FF1E880 0x00000004 bytes
09:47:54:557 : Database: Config 3 is active.
09:47:54:558 : flash loader C:\Program Files\STMicroelectronics\STM32Cube\STM32CubeProgrammer\bin/FlashLoader/0x450.stldr is loaded
09:47:54:560 : Reading data...
09:47:54:562 : r ap 0 @0x1FF1E880 0x00000004 bytes
09:47:54:724 : UPLOADING OPTION BYTES DATA ...
09:47:54:724 : Bank : 0x00
09:47:54:724 : Address : 0x5200201c
09:47:54:725 : Size : 308 Bytes
09:47:54:725 : Reading data...
09:47:54:725 : r ap 0 @0x5200201C 0x00000134 bytes
09:47:54:725 : UPLOADING OPTION BYTES DATA ...
09:47:54:725 : Bank : 0x00
09:47:54:726 : Address : 0x5200201c
09:47:54:726 : Size : 308 Bytes
09:47:54:726 : Reading data...
09:47:54:726 : r ap 0 @0x5200201C 0x00000134 bytes
09:47:54:727 : UPLOADING ...
09:47:54:727 : Size : 1024 Bytes
09:47:54:727 : Address : 0x8000000
09:47:54:727 : Read progress:
09:47:54:727 : Reading data...
09:47:54:728 : r ap 0 @0x08000000 0x00000400 bytes
09:47:54:728 : Data read successfully
09:47:54:728 : Time elapsed during the read operation is: 00:00:00.007

Please post yours so we can see what "not able to connect" means.

EBonv
Associate III

> My first impression when I read this'd been built and programmed without debugging and without complete knowledge was "what the heck".

Yeah, I am out of my comfort zone with this secure boot. Which is why I tried to stick to the example projects provided by STM first. You have to start somewhere, right? But I guess debugging would have been much better.

> But later you say " it seems that I am not able to connect to the board through STLINK either". You must have "connected" to ascertain "only the bytes from address 0x08000000 to 0x080000FF have been modified".

To clarify, there are a few modes in which you can connect to the board using STM32CubeProgrammer. The mode in which I want to connect is the "normal mode" but I am unable to connect to the board in this mode since I loaded the SBSFU. However, I can connect to the board in "hot plug" mode which allows me to inspect the memory but does not allow me to change option bytes or to erase parts of the memory.

> PCROP regions are 0x100-byte aligned and possibly STM32CubeProgrammer incorrectly displays 0s for unsuccessful read accesses.

PCROP regions are definitely 0x100-byte aligned (see screenshot below).

0693W00000APtHqQAL.png 

> Please post yours so we can see what "not able to connect" means.

Here is my output when I try to connect in normal mode, the DEV_TARGET_NOT_HALTED error shows up:

17:36:52 : STM32CubeProgrammer API v2.7.0
  17:37:02:823 : STLinkUSBDriver.dll loaded
  17:37:02:844 : STLinkUSBDriver.dll loaded
  17:37:02:844 : ST-LINK SN  : 0036003B3137511039383538
  17:37:02:845 : ST-LINK FW  : V3J8M3
  17:37:02:845 : Board       : NUCLEO-H753ZI
  17:37:02:845 : Voltage     : 3,29V
  17:37:04:005 : ST-LINK error (DEV_TARGET_NOT_HALTED)
  17:37:04:006 : STLinkUSBDriver.dll loaded
  17:37:04:009 : ST-LINK SN  : 0036003B3137511039383538
  17:37:04:009 : ST-LINK FW  : V3J8M3
  17:37:04:009 : Board       : NUCLEO-H753ZI
  17:37:04:009 : Voltage     : 3,29V
  17:37:06:005 : Error: ST-LINK error (DEV_TARGET_NOT_HALTED)

> In my second post I said "Look for the addresses and sizes of each of the protections". Inspect the code and its outputs. What protections does your SBSFU configure? What are their addresses/sizes?

I have the following linker script, is it what you were refering to? It seems that no secure region is defined before 0x08000400.

/*
*****************************************************************************
**
 
**  File        : LinkerScript.ld
**
**  Abstract    : Linker script for STM32H753ZITx Device with
**                2048KByte FLASH, 128KByte RAM
**
**                Set heap size, stack size and stack location according
**                to application requirements.
**
**                Set memory bank area and size if external memory is used.
**
**  Target      : STMicroelectronics STM32
**
**
**  Distribution: The file is distributed as is, without any warranty
**                of any kind.
**
**  (c)Copyright Ac6.
**  You may use this file as-is or modify it according to the needs of your
**  project. Distribution of this file (unmodified or modified) is not
**  permitted. Ac6 permit registered System Workbench for MCU users the
**  rights to distribute the assembled, compiled & linked contents of this
**  file as part of an application binary file, provided that it is built
**  using the System Workbench for MCU toolchain.
**
*****************************************************************************
*/
 
VECTOR_SIZE = 0x400;
 
/* SE Code region protected by MPU isolation */
__ICFEDIT_SE_Code_region_ROM_start__       = 0x08000000 + VECTOR_SIZE;
__ICFEDIT_SE_CallGate_region_ROM_start__   = __ICFEDIT_SE_Code_region_ROM_start__ + 0x4;
__ICFEDIT_SE_CallGate_region_ROM_end__     = __ICFEDIT_SE_Code_region_ROM_start__ + 0x1FF;
 
/* SE key region protected by MPU isolation */
__ICFEDIT_SE_Key_region_ROM_start__        = __ICFEDIT_SE_CallGate_region_ROM_end__ + 0x1;
__ICFEDIT_SE_Key_region_ROM_end__          = __ICFEDIT_SE_Key_region_ROM_start__ + 0x2FF;  /* H7: The minimum PCROP area that can be set is 16 Flash words, that is 512 bytes. */
 
/* SE Startup */
__ICFEDIT_SE_Startup_region_ROM_start__    = __ICFEDIT_SE_Key_region_ROM_end__ + 0x1;
__ICFEDIT_SE_Code_nokey_region_ROM_start__ = __ICFEDIT_SE_Startup_region_ROM_start__ + 0x100;
/* Aligned SE End at the end of the 1st 32Kbytes of flash, MPU protection isolation constraints */
__ICFEDIT_SE_Code_region_ROM_end__         = 0x08007FFF;
 
/* SE IF ROM: used to locate Secure Engine interface code out of MPU isolation     */
/* 
 * We must be out of Region 2 to allow unprivileged access 
 * With the current settings Region 2 starts from 0x08000000 and covers 32kB of code (0x8000)
 */
__ICFEDIT_SE_IF_region_ROM_start__         = 0x08000000 + 0x8000; 
__ICFEDIT_SE_IF_region_ROM_end__           = __ICFEDIT_SE_IF_region_ROM_start__ + 0x8FF;
 
/* Secure memory activation code - initialization area */
__ICFEDIT_SB_HDP_region_ROM_start__        = __ICFEDIT_SE_IF_region_ROM_end__ + 1;
__ICFEDIT_SB_HDP_region_ROM_end__          = __ICFEDIT_SB_HDP_region_ROM_start__ + 0xFF;
 
/* SBSFU Code region */
__ICFEDIT_SB_region_ROM_start__            = __ICFEDIT_SB_HDP_region_ROM_end__ + 1;
/* Aligned SBSFU end at the end of the 1st 128Kbytes of FLASH, MPU protection constraints */
__ICFEDIT_SB_region_ROM_end__              =  0x0801FFFF;
 
SE_Entry_Secure_ROM_Region_Length = __ICFEDIT_SE_CallGate_region_ROM_end__ - __ICFEDIT_SE_CallGate_region_ROM_start__ + 1;
SE_Key_region_ROM_Length          = __ICFEDIT_SE_Key_region_ROM_end__ - __ICFEDIT_SE_Key_region_ROM_start__ + 1;
SE_Startup_region_ROM_Length      = __ICFEDIT_SE_Code_nokey_region_ROM_start__ - __ICFEDIT_SE_Startup_region_ROM_start__ ;
SE_ROM_region_Length              = __ICFEDIT_SE_Code_region_ROM_end__ - __ICFEDIT_SE_Code_nokey_region_ROM_start__ + 1;
SE_IF_region_ROM_Length           = __ICFEDIT_SE_IF_region_ROM_end__ - __ICFEDIT_SE_IF_region_ROM_start__ + 1;
SB_HDP_ROM_region_Length          = __ICFEDIT_SB_HDP_region_ROM_end__ - __ICFEDIT_SB_HDP_region_ROM_start__ + 1;
SB_ROM_region_Length              = __ICFEDIT_SB_region_ROM_end__ - __ICFEDIT_SB_region_ROM_start__ + 1;
 
/* RAM section */
/* SE RAM1 region protected by firewall */
/* SE stack is placed 1st in RAM, stack overflow does not write on other RAM area */
__ICFEDIT_SE_region_RAM_start__     = 0x20000000;
__ICFEDIT_SE_region_RAM_stack_top__ = 0x20000400;
__ICFEDIT_SE_region_RAM_end__       = 0x20000FFF;
 
/* Secure memory activation code area - execution in RAM */
__ICFEDIT_SB_HDP_Code_region_RAM_start__ = __ICFEDIT_SE_region_RAM_end__ + 1;
__ICFEDIT_SB_HDP_Code_region_RAM_end__   = __ICFEDIT_SB_HDP_Code_region_RAM_start__ + 0xFF;
 
/* SBSFU RAM1 region */
__ICFEDIT_SB_region_RAM_start__     = __ICFEDIT_SB_HDP_Code_region_RAM_end__ + 1;
__ICFEDIT_SB_region_RAM_end__       = 0x2001FFFF;
 
SE_RAM_region_Length = __ICFEDIT_SE_region_RAM_end__ - __ICFEDIT_SE_region_RAM_stack_top__ + 1;
SB_HDP_CODE_RAM_region_Length = __ICFEDIT_SB_HDP_Code_region_RAM_end__ - __ICFEDIT_SB_HDP_Code_region_RAM_start__ + 1;
SB_RAM_region_Length = __ICFEDIT_SB_region_RAM_end__ - __ICFEDIT_SB_region_RAM_start__ + 1;
 
MEMORY
{
 SE_Entry_Secure_ROM_Region (rx)     : ORIGIN = __ICFEDIT_SE_CallGate_region_ROM_start__, LENGTH = SE_Entry_Secure_ROM_Region_Length
 SE_Key_region_ROM (rx)              : ORIGIN = __ICFEDIT_SE_Key_region_ROM_start__, LENGTH = SE_Key_region_ROM_Length
 SE_Startup_region_ROM (rx)          : ORIGIN = __ICFEDIT_SE_Startup_region_ROM_start__, LENGTH = SE_Startup_region_ROM_Length
 SE_ROM_region (rx)                  : ORIGIN = __ICFEDIT_SE_Code_nokey_region_ROM_start__, LENGTH = SE_ROM_region_Length
 SE_IF_region_ROM (rx)               : ORIGIN = __ICFEDIT_SE_IF_region_ROM_start__, LENGTH = SE_IF_region_ROM_Length
 SB_HDP_ROM_region (rx)              : ORIGIN = __ICFEDIT_SB_HDP_region_ROM_start__, LENGTH = SB_HDP_ROM_region_Length
 SB_ROM_region (rx)                  : ORIGIN = __ICFEDIT_SB_region_ROM_start__, LENGTH = SB_ROM_region_Length
 SE_RAM_region (xrw)               : ORIGIN = __ICFEDIT_SE_region_RAM_stack_top__, LENGTH = SE_RAM_region_Length
 SB_HDP_Code_RAM_region (xrw)      : ORIGIN = __ICFEDIT_SB_HDP_Code_region_RAM_start__, LENGTH = SB_HDP_CODE_RAM_region_Length
 SB_RAM_region (xrw)               : ORIGIN = __ICFEDIT_SB_region_RAM_start__, LENGTH = SB_RAM_region_Length
}

Your STM32CubeProgrammer screenshot shows PCROP enabled and starting at 0x8000100, and explains the reads from 0x8000100 being incorrect.

For recovery, perhaps try mode "Under Reset" and Reset mode "Hardware reset", connect and then "erase fill chip flash memory". If that doesn't work, you might try individually disabling whatever protections are set in the OBs.

Docs for the STM32CubeProgrammer are at https://www.st.com/content/st_com/en/products/development-tools/software-development-tools/stm32-software-development-tools/stm32-programmers/stm32cubeprog.html#documentation.

If none of the above works, you may find the earlier STM32 ST-LINK Utility tool at https://www.st.com/content/st_com/en/products/development-tools/software-development-tools/stm32-software-development-tools/stm32-programmers/stsw-link004.html.

EBonv
Associate III

The PCROP should have been disabled and I believe it is the reason behind my problem.

I had tried already to connect with the "Under Reset" mode as I saw in other threads that it could be a solution in some cases. I also retried now, but still with no success. I am also unable to modify any of the OBs when I am in hot plug mode (which is the only mode in which I can connect to the board at the moment).

I also switched back to a Windows distribution to download the earlier ST-LINK Utility tool you suggested. Unfortunately, I obtain the exact same outcomes than with STM32CubeProgrammer. That is (1) I am only able to connect to the board using the hot plug mode, trying to connect in other modes yield an error and (2) in hot plug mode I am unable to perform a full chip erase or to modify any of the OBs.

I ordered a new board as I am out of ideas on how to recover this one and I don't want to take more of your time. I will be more careful with the next board. Your advice in your first reply will definitely help me, I will select it as best.

Thank you a lot for your time and advice.

Not sure if you've a problem with SWD reset.

Not sure if STM32CubeProgrammer's mass erase does proper protection removal first.

If you can connect, you might try manually removing protections per RM044 section 4.3.10 FLASH erase operations and other places.

@Remi QUINTIN​, you've expertise with STM32CubeProgrammer and option bytes. Could you assist please?