nihalpasham / rustBoot

rustBoot is a standalone bootloader written entirely in `Rust`, designed to run on anything from a microcontroller to a system on chip. It can be used to boot into bare-metal firmware or Linux.
MIT License
214 stars 21 forks source link

Add support for STM32F469 MCU in examples #64

Closed lionelains closed 2 years ago

lionelains commented 2 years ago

Hello, and first of all, thanks for this great work.

I have tried to add support for the STM32F469 MCU in the STM HAL. This chip is used on the STM32F469-IDISCO board and supporting should be very close to the existing code implemented for STM32F411 and STM32F446. However, I am wondering how to adjust the value for the constant FW_RESET_VTR, for which the definition is based on an offset... [This offset is 0xA9 in the current STM446 implementation] (https://github.com/nihalpasham/rustBoot/blob/5a3cc7aa392abeb0ac322aa4279bba5a8eba7c6e/boards/hal/src/stm/stm32f446.rs#L15) ...and 0x99 in the STM411 implementation.

What is the meaning of this offset? How can I adjust this for STM32F469? In the STM32 programming manual (PM201), the vector table is identical regardless of the chip STM32F411 or STM32F446...

lionelains commented 2 years ago

Digging around the binaries produced by the STM32F411 or STM32F446 counterparts, it looks like this offset can be guessed by grabbing the 32-bit reset vector located at offset 4 in the binary image. When I build for STM32F446, I indeed get a pointer to address 0x080202a9 (BASE_ADDR being 0x08020000), but RB_HDR_SIZE is not meaningful here because we haven't prepended the rustBoot header yet...

imrank03 commented 2 years ago

Hello, and first of all, thanks for this great work.

I have tried to add support for the STM32F469 MCU in the STM HAL. This chip is used on the STM32F469-IDISCO board and supporting should be very close to the existing code implemented for STM32F411 and STM32F446. However, I am wondering how to adjust the value for the constant FW_RESET_VTR, for which the definition is based on an offset... [This offset is 0xA9 in the current STM446 implementation] (

https://github.com/nihalpasham/rustBoot/blob/5a3cc7aa392abeb0ac322aa4279bba5a8eba7c6e/boards/hal/src/stm/stm32f446.rs#L15

) ...and 0x99 in the STM411 implementation. What is the meaning of this offset? How can I adjust this for STM32F469? In the STM32 programming manual (PM201), the vector table is identical regardless of the chip STM32F411 or STM32F446...

Hi @lionelains,

Thanks for reaching out, and glad to hear that you're interested in rustBoot!

imrank03 commented 2 years ago

Digging around the binaries produced by the STM32F411 or STM32F446 counterparts, it looks like this offset can be guessed by grabbing the 32-bit reset vector located at offset 4 in the binary image. When I build for STM32F446, I indeed get a pointer to address 0x080202a9 (BASE_ADDR being 0x08020000), but RB_HDR_SIZE is not meaningful here because we haven't prepended the rustBoot header yet...

Yes, we haven't prepended the rustBoot header yet, but we use RB_HDR_SIZE to create FW_RESET_VTR address used in boot_from function and this function called after image verification.

https://github.com/nihalpasham/rustBoot/blob/5a3cc7aa392abeb0ac322aa4279bba5a8eba7c6e/boards/hal/src/stm/stm32f446.rs#L229

lionelains commented 2 years ago

Hi @imrank03. Thanks for your reply. OK, if I understand correctly your point, when rustBoot is running from flash, the partition where it should load the application firmware has the header prepended, so we indeed need to skip the first RB_HDR_SIZE bytes.

But, in that case, based on the fact that the vector table is directly located at the very beginning inside the application's binary image we should find :

Thus, why don't we just have the following?

pub const FW_RESET_VTR    : u32 = BASE_ADDR + RB_HDR_SIZE + 4; 
imrank03 commented 2 years ago

We are checking the reset handler value at offset +4, FW_RESET_VTR must match the reset handler address, otherwise the boot_from function will panic. https://github.com/nihalpasham/rustBoot/blob/5a3cc7aa392abeb0ac322aa4279bba5a8eba7c6e/boards/hal/src/stm/stm32f446.rs#L229-L230

if we use this

pub const FW_RESET_VTR    : u32 = BASE_ADDR + RB_HDR_SIZE + 4; 

will get wrong 32 bit value and it will be different from +4 offset value.

Here's a tiny post on why we're doing this and what RefinedUsize is.

lionelains commented 2 years ago

Oh, I see, the FW_RESET_VTR is only a failsafe check of the entry point inside the application firmware, the real value to jump to is actually the 32-bit value provided to boot_from() inside its parameter fw_base_address.

lionelains commented 2 years ago

If you're interested, I think I have a port of the rustBoot demo (boot firmware->upgrade firmware with LED associated blinks) working on the STM32F469-IDISCO board... I can propose this as a PR.

Please note that I didn't however implement any support for the external QSPI flash that is also mounted on that board, so I'm only supporting the built-in flash

imrank03 commented 2 years ago

Hi @lionelains,

Thank you, we are completely open-source and as such, we welcome contributions from anyone! We will be happy if you propose this as a PR.

lionelains commented 2 years ago

Hi @imrank03, I have created PR https://github.com/nihalpasham/rustBoot/pull/65

imrank03 commented 2 years ago

Acknowledged