Build padded image for bootloader

I’m trying to build “Hello, world” application based on zephyr with mcuboot bootloader. Board is stm32f4 disco, i use stlink debug tool.

MCUBoot flashes successful, it starts, detects and validates primary image but system halted with instruction access violation.

I found, that image builds w/o offset 0x080000000, but needs 0x08020000:

> LANG=C readelf -S firmware.elf
There are 28 section headers, starting at offset 0xb57c0:

Section Headers:
[Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
[ 0]                   NULL            00000000 000000 000000 00      0   0  0
[ 1] rom_start         PROGBITS        08000000 0000b4 000388 00 WAX  0   0  4
...

My stm32f4_disco.overlay:

&flash0 {
        partitions {
                compatible = "fixed-partitions";
                #address-cells = <1>;
                #size-cells = <1>;
                boot_partition: partition@0 {
                        label = "mcuboot";
                        reg = <0x00000000 0x00010000>;
                        read-only;
                };
                slot0_partition: partition@20000 {
                        label = "image-0";
                        reg = <0x00020000 0x00040000>;
                };
                slot1_partition: partition@60000 {
                        label = "image-1";
                        reg = <0x00060000 0x00040000>;
                };
                scratch_partition: partition@A0000 {
                        label = "image-scratch";
                        reg = <0x000A0000 0x000020000>;
                };
                data_prtition: partition@b0000 {
                        label = "data";
                        reg = <0x000b0000 0x00050000>;
                };
        };
};

prj.conf:

CONFIG_BOOTLOADER_MCUBOOT=y
CONFIG_LOG=y
CONFIG_LOG_BUFFER_SIZE=16384

platformio.ini:

[env:disco_f407vg]
platform = ststm32
board = disco_f407vg
framework = zephyr
debug_tool = stlink
monitor_port = /dev/ttyUSB0
monitor_speed = 115200
monitor_flags = --raw
board_upload.offset_address = 0x08020000

MCUBoot logs (do_boot() lines logs by my patch, to check address for next chain call):

*** Booting Zephyr OS version 2.5.0  ***
[00:00:00.003,000] <inf> mcuboot: Starting bootloader
[00:00:00.003,000] <inf> mcuboot: (s) Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
[00:00:00.003,000] <inf> mcuboot: (s) Scratch: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
[00:00:00.003,000] <inf> mcuboot: Boot source (s): primary slot
[00:00:00.011,000] <inf> mcuboot: Swap type: none
[00:00:00.103,000] <inf> mcuboot: Bootloader chainload address offset: 0x20000
[00:00:00.103,000] <inf> mcuboot: Jumping to the first image slot
[00:00:00.103,000] <inf> mcuboot: do_boot() vt=0x8020200
[00:00:00.103,000] <inf> mcuboot: do_boot() vt->reset()
[00:00:00.103,000] <err> os: ***** MPU FAULT *****
[00:00:00.103,000] <err> os:   Instruction Access Violation
[00:00:00.103,000] <err> os: r0/a1:  0xffffffff  r1/a2:  0x20006782  r2/a3:  0x00000004
[00:00:00.103,000] <err> os: r3/a4:  0x080008b1 r12/ip:  0xa0000000 r14/lr:  0x0800053b
[00:00:00.103,000] <err> os:  xpsr:  0x20000000
[00:00:00.103,000] <err> os: Faulting instruction address (r15/pc): 0x20002ea8
[00:00:00.103,000] <err> os: >>> ZEPHYR FATAL ERROR 0: CPU exception on CPU 0
[00:00:00.103,000] <err> os: Current thread: 0x200002c8 (unknown)
[00:00:00.103,000] <err> os: Halting system

How to build image with offset? Need I create custom ld script or may be simple way exists?

1 Like

When I read docs like here and here and this blog post saying

The command line is almost identical to the previous one, except for the additional -DCONFIG_BOOTLOADER_MCUBOOT=y option. This tells the build system to compile for usage with MCUboot and sets the start of the code fragment on the start address of slot0 instead of 0 (where MCUboot currently is placed!).

I don’t see a problem with your configuration that might cause the wrong address – maybe PlatformIO has a problem there.

But, the above article also talks about signing the image. I also don’t know if that’s a step done by PlatformIO or if that’s to be done manually.

In any case, I hope @valeros can help here.

I found settings, this do that I want:

/ {
	chosen {
		zephyr,code-partition = &slot0_partition;
	};
};