cancel
Showing results for 
Search instead for 
Did you mean: 

Custom "thick" bootloader to boot identical application binary from either address A or B?

Code257
Associate III

Hello. I have run into a problem in a MCU project I have. I'll explain the situation.

We have a STM32F072RB -based product where we are implementing firmware update functionality. There would be 3 binaries in the MCU:

  1. Custom "thick" bootloader selecting application binary 1 or application binary 2 and jumping to run it
  2. Application binary 1 beginning at address A
  3. Application binary 2 beginning at address B

Our initial plan was to build different application binaries with explicitly different locations, but my customer is kind of wishing to use only one application binary. Therefore binary 1 would have exactly the same contents as binary 2.

Some experts say the way my customer wants the functionality is almost impossible to make. What do you say?

If anyone has any pointers what to google, what documents to read, etc, I'm all ears.

(My current, possibly stupid, idea is to make the single application binary to contain some kind of functionality to determine where it is run from and if it is run from binary 2 beginning from address B, then maybe perform some kind of elegant function/resource remapping so that when the image 2 runs, it does not use image 1 addresses for stuff, but locations in image 2 address space. Is this totally dumb?)

23 REPLIES 23

So if I just jump from Bootloader to arbitrarily-positioned Application, GOT is not needed? Just PIC/pic is needed? And just for Application? And I just keep the Bootloader notified of the Application location?

I will test this. I was experimenting with all of these options:

# Generate position independent code.

-fPIC

# Access bss via the GOT.

-mno-pic-data-is-text-relative

# GOT is not PC-relative; store GOT location in a register.

-msingle-pic-base

# Store GOT location in r9.

-mpic-register=r9

But maybe I just use -fpic / -fPIC and see how what happens.

Ok, got finally the idea. The external system hosting the application binary (and doing the firmware upload to the product module) is also some kind of embedded system with limited memory. They want therefore to limit the storage footprint and one thing to practically halve it is the PIC .

Or follow the last paragraph of my previous post. Just make a bootloader that is capable of updating/recovering the device under any circumstances and you don't have to waste storage space on both (host and client) devices, and you don't have to mess with a PIC either.

Customer has another valid point. The HW module is a critical component of a bigger system and does not tolerate more downtime than maybe just a few seconds. Firmware upgrade is prepared "on the side" when the main functionality is running. That's why they need 2 applications.

> Customer has another valid point. The HW module is a critical component of a bigger system and does not tolerate more downtime than maybe just a few seconds.

> Firmware upgrade is prepared "on the side" when the main functionality is running. That's why they need 2 applications.

Fair enough, but that still does not validate the extra hassle with a single position-independent binary, as opposed to two binaries plus whatever mechanism needed to choose between them.

JW

Javier1
Principal

what does "thick" stand for?

we dont need to firmware by ourselves, lets talk

In this case it would include functionality to access Application binary locations to do crc verification. It would also include Eeprom capabilities for upgrade control.

Code257
Associate III

Hello again,

I started to use M4 (Nucleo-L432KC) because it is a bit easier in some aspects. I made bootloader which blinks led in a fast speed and tries to load firmware. Made firmware which blinks led in a slow speed.

In general it seems nobody ever shares full code about this, so here is my try:

https://github.com/usvi/L432KC-BL-FW/

What I currently have:

L432KC_Bootloader, it works fine and jumps away just fine. In linker script start address is 0x8000000. The bootloader can even jump to itself (0x8000000).

L432KC_Firmware_0x8005000, which has in linker script defined that flash begins from 0x8005000, also I have SCB->VTOR = 0x8005000; -fPIC is enabled in IDE. Made L432KC_Firmware_0x8005000 for reference to verify bootloader can jump to firmware. I flash the .bin file manually to 0x8005000 and it works.

L432KC_Firmware_anywhere, which has in linker script start address 0x8000000. SCB->VTOR is not altered, so it is zero. -fPIC is enabled in IDE. I flash the .bin file manually to 0x8005000 and it does not work, bootloader tries to jump there but it crashes.

Can anyone spot what I'm doing obviously wrong?

Code257
Associate III

I fixed it. I will write an article about it "soon".

Code257
Associate III

I have now fully working, dynamic, clean, interrupts-driven, self-verifying, multi-mode solutions for both F070RB and L432KC. I need still to find time to write that article. It seems that about 99% of the information of this on various forums and other places is inaccurate, misleading, lacking or wrong.