zephyrproject-rtos / zephyr

Primary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.
https://docs.zephyrproject.org
Apache License 2.0
10.67k stars 6.52k forks source link

MCUbootloader with b_u585i_iot02a (stm32u585) boot error #47781

Closed angeldelacalle closed 2 years ago

angeldelacalle commented 2 years ago

Describe the bug After running the mcuboot in a stm32u585 board with an image correctly signed and flashed in the image slot 0, the header address of the configuration do not match the real address where the msp and reset vectors are written from the hex file.

To Reproduce Steps to reproduce the behavior:

  1. Removing the "--erase" tag in the board.cmake (b_u585i_iot02a directory).

  2. Building mcuboot and saving the binaries in a clean directory: west build -p -b b_u585i_iot02a -s zephyr_base/bootloader/mcuboot/boot/zephyr -d build-mcuboot

  3. Flashing the mcuboot ("No bootable image found"): west flash -d build-mcuboot/

  4. Building and signing with the default key a sample application ("hello_world") for flashing it on the image 0 slot: west build -p -b b_u585i_iot02a -s zephyr_base/bootloader/mcuboot/samples/zephyr/hello-world/ -d build-hello-mcu-signed -- -DCONFIG_BOOTLOADER_MCUBOOT=y -DCONFIG_MCUBOOT_SIGNATURE_KEY_FILE=\"bootloader/mcuboot/root-rsa-2048.pem\"

  5. Flashing the app on the image: west flash -d build-hello-mcu-signed/

Expected behavior After a reset, mcuboot finds the signed binary in the image slot and jumps into it for running the application.

Experienced behavior The bootloader makes the checks of signed image in slot and goes to the funcion do_boot() under the defined macro CONFIG_ARM. It goes to flash_base_address(0x8000000)+image_offset(0x10000)+header_address(0x200) and jumps into a place of the image which is padded with zeros, provoking a hard fault. I've seen that if I double the header address, jumping then to flash_base_address(0x8000000)+image_offset(0x10000)+header_address(0x200+0x200), the boot jumps over that padded zone of zeros finding the addresses vt->msp and vt->reset and working correctly. After adding that offset of 0x200 bytes to the header, the boot goes to the application as expected and everything works fine.

Impact Not able to use the mcubootloader without manually patching it. I do not understand the reason of that padded zone with zeros at the beggining of the hex file when I enable CONFIG_BOOTLOADER_MCUBOOT in the compilation.

Environment

Additional context In kconfig.zephyr, I've been changing the values of ROM_START_OFFSET. I've seen that it changes the value of the header size in the built hex file but the padded zone keeps having the same size. So, the only combination that I've seen it was working fine was ROM_START_OFFSET=0x200 as default + 0x200 hardcoded in the do_boot application.

erwango commented 2 years ago

So actually, on U5/L5, table vector is expected to be aligned on 0x400 addresses, hence the additional 0x200 offset. Somehow, the image is correctly built regarding this constraint (I'm yet to understand if this is done for good reason), but unfortunately mcuboot is not informed (likely because the image header doesn't contain the right information). I'm digging a bit more

erwango commented 2 years ago

Configuring right header size using CONFIG_MCUBOOT_EXTRA_IMGTOOL_ARGS will fix this issue. Happen the following to your command:

-DCONFIG_MCUBOOT_EXTRA_IMGTOOL_ARGS="--header-size 1024"

Note that I personally need to escape literal strings : \"--header-size\ 1024\". Not sure why.

erwango commented 2 years ago

Addendum: Did you notice sysbuild ? Using sysbuild, you can do:

$ west build -p always -b b_u585i_iot02a --sysbuild samples/hello_world -- -DSB_CONFIG_BOOTLOADER_MCUBOOT=y -DCONFIG_MCUBOOT_SIGNATURE_KEY_FILE="bootloader/mcuboot/root-rsa-2048.pem" -DCONFIG_MCUBOOT_EXTRA_IMGTOOL_ARGS="--header-size 1024"
$ west flash