cancel
Showing results for 
Search instead for 
Did you mean: 

Dual bootloader - how to?

tykhaytschaar
Associate

Hi everyone!

I have to implement a dual bootloader system on different stm32 microcontrollers in STM32cube ide, and I have some questions…

The idea is the following:

There is a “pre-bootloader�? at the beginning of the flash. When it starts, it gets some data from a specified memory (flash) area: the address, size and crc of the actual “real�? bootloader. (Let’s name this area BL_DATA). Calculates the crc of the bootloader, compares it to the stored value, and if it’s ok, jumps to that address.

The bootloader waits for messages over u(s)art. If the arrived message is a command to flash the user app, it gets the app binary in chunks, and after some validation it writes the new user app to the specified address.

The address, size and crc of the user app are stored in BL_DATA. After flashing the user app, the bootloader refreshes user app crc and size. The address of the user app is constant.

If the command is to flash the bootloader, it writes the arriving program to the proper address: there are 2 bootloader addresses stored in BL_DATA, the new bootloader address is which is not equal to the actual bootloader address. After writing to flash, the bootloader sets the actual bootloader address to the other’s (and also the size and a calculated crc).

If no message arrives in time, it simply jumps to the user application (after reading its address, crc and things like that from BL_DATA, just like the pre-bootloader).

I started with implementing the jumping feature. It works, but I needed some workarounds to make it work:

In the debug configurations of the pre-bootloader on the startup tab I added the bootloader too. In the pre-bootloader program I check what’s on the address in BL_DATA where the actual bootloader address needs to be, and if nothing is set there I write the actual bootloader address to there and then jump to it.

 - First question: is it possible to link a binary content (in the linker script?) to make it being stored at a specified memory area? (I guess it is, but I need some keywords to search with…) or it’s just simpler to commit this “initial write�??

 - It’s necessary to spearate BL_DATA from other areas in flash because when i want to flash a new bootloader or user app, i have to erase that area first. E.g. with stm32f767zi the smallest “section�? to erase is a 32K sector, so in this case I have to reserve a whole sector for BL_DATA. Am I right? (To store all the data I need only 64 bytes so it seems to be a bit wasteful - despite it’s 2M flash memory…)

 - The bootloader’s address in the memory depends on what’s the actual bootloader address stored in BL_DATA. How can I configure the bootloader project’s linker file to achieve this?

I’d be really glad if someone gave me some explanations and/or keywords in these topics…

1 ACCEPTED SOLUTION

Accepted Solutions
mattias norlander
ST Employee

How do you intend to develop and maintain your project structures?

To me it sounds like you may want to setup 3 different CubeIDE projects:

  • Pre-bootloader
  • Boot-loader
  • User app

Each would produce its own output.

When you debug the code you can load just one of the project elf-files to the target or all 3 elf-files to be able to debug different scenarios.

In such case, do you need to use linker magic to copy binary blobs from one image to the other?

Is this booloader system supposed to be STM32 agnostic? That is, should it be able to compile for let's say L4, G0 and H7? If so, you should opt for the CDT project type.

Have you by the way had a look at the ST provided SBSFU package?

It is not for you if you are looking for something simple. But if you end up needing a lot of security, you may find it useful!

I also link a youtube guide which gives some useful pointers on designing your own custom boot loader:

https://www.youtube.com/watch?v=OkUQ3iMmiYQ

View solution in original post

2 REPLIES 2
mattias norlander
ST Employee

How do you intend to develop and maintain your project structures?

To me it sounds like you may want to setup 3 different CubeIDE projects:

  • Pre-bootloader
  • Boot-loader
  • User app

Each would produce its own output.

When you debug the code you can load just one of the project elf-files to the target or all 3 elf-files to be able to debug different scenarios.

In such case, do you need to use linker magic to copy binary blobs from one image to the other?

Is this booloader system supposed to be STM32 agnostic? That is, should it be able to compile for let's say L4, G0 and H7? If so, you should opt for the CDT project type.

Have you by the way had a look at the ST provided SBSFU package?

It is not for you if you are looking for something simple. But if you end up needing a lot of security, you may find it useful!

I also link a youtube guide which gives some useful pointers on designing your own custom boot loader:

https://www.youtube.com/watch?v=OkUQ3iMmiYQ

Why wouldn't you just keep the size and crc/signing in the app​ image itself?

If you have an index or sequence number you can determine the newest valid image in a system.

The linker script or scatter file can define the base address for the image being built.​

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..