Secure DFU failure on large applications

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
BrBr_1320441
Level 3
Level 3
25 replies posted 10 replies posted 5 replies posted

Hi,

I have been trying to get secure DFU working with a UART transport layer and am having some issues. I believe I have a safe memory layout at this point, but it would appear I am trying to write to read only memory still.

I am basing my work on CE222802 on CYBLE-416045-2. I am using PDL 3.0.4 because the suggested version of 3.0.1 will not work with CYBLE-416045-2, and upgrading to 3.1+ causes lots of backwards compatibility issues.

Anyway, with the standard project and PDL 3.0.4 (and one header change needed for a difference between PDL 3.0.1 and 3.0.4), everything works.

However, my actual application needs much more memory (both flash and ram) than this example project allocates for App1.

So, I am starting with just the flash memory tables, and I modified it as such in both app0 and app1 in the common linker script.

    flash_app0_core0  (rx)  : ORIGIN = 0x10000000, LENGTH = 0x10000

    flash_app0_core1  (rx)  : ORIGIN = 0x10010000, LENGTH = 0x10000

    flash_app1_core0  (rx)  : ORIGIN = 0x10040000, LENGTH = 0x20000

    flash_app1_core1  (rx)  : ORIGIN = 0x10060000, LENGTH = 0x80000

    flash_storage     (rw)  : ORIGIN = 0x100E0000, LENGTH = 0x1000

    flash_boot_meta   (rw)  : ORIGIN = 0x100FFA00, LENGTH = 0x400

All other variables are exactly the same. Bolded values are the ones I actually changed from the default in CE222802.

When I do this, after around 350 seconds (towards the end of the process) I receive an error in the bootloader host tool: "The flash row is not valid for the selected array"

If I reduce LENGTH(flash_app1_core1) (I tested at 0x4000), then it works. It did not work with length of 0x6000 though.

I am not sure why this wouldn't be right. I cant see any obvious memory overlaps.

Thanks for any help

0 Likes
1 Solution

It looks there is no simple way to disable the temporary image placement in CE222802, unless to modify the specific project code.

Instead, CE213903 use a direct loading method to store image in a perpetual address. You can refer to this code to modify CE222802.

Just for remaind, one major differenrce between the two projects is the handling in bootload_user.c / dfu_user.c -> Cy_Bootload_WriteData() / Cy_Dfu_WriteData().

Another one is the appId marked in CE222802 app1 linker files is 2, to recognize the received image to store in a temporary place  -

/* Bootloader SDK specific: sets an app Id */

__cy_app_id = 2;

Hope this helps.

View solution in original post

0 Likes
6 Replies
BrBr_1320441
Level 3
Level 3
25 replies posted 10 replies posted 5 replies posted

As a follow up -- I believe I have at least identified the cause.

It would appear the secure dfu sample CE222802  (which I am using as a base), first uploads the image to a temporary location and then moves it after validation.

The temporary location chosen is 0x10080000. So it is writing the application and will reach the flash_storage region after 0x6000 bytes. This would make sense why it reached the very end but failed when I set it to 0x6000, but worked at 0x5000 length.

So, as a test I changed the temporary image location in bootload_user.c to &__cy_app1_verify_start.

And with that, the application completes bootloading successfully!

But Im still not done, because it appears that it isn't loading the bootloadable correctly at this point. I wonder if it is failing to validate for some reason?

Is there a better way to actually disable the temporary image placement? I am perfectly okay with the loader corrupting the application in this case, so long as the bootloader is still functional.

0 Likes

It looks there is no simple way to disable the temporary image placement in CE222802, unless to modify the specific project code.

Instead, CE213903 use a direct loading method to store image in a perpetual address. You can refer to this code to modify CE222802.

Just for remaind, one major differenrce between the two projects is the handling in bootload_user.c / dfu_user.c -> Cy_Bootload_WriteData() / Cy_Dfu_WriteData().

Another one is the appId marked in CE222802 app1 linker files is 2, to recognize the received image to store in a temporary place  -

/* Bootloader SDK specific: sets an app Id */

__cy_app_id = 2;

Hope this helps.

0 Likes

Great, thanks. I will follow up with that today and hopefully have something working soon.

Another question I have related to this:

When I build an application with Creator I of course get 4 total hex files for CM0+/CM4 core on App0/1. In a production environment, should I be using something like Cypress Programmer or OpenOCD to program all four of those seprately? And would that be equivalent to programming the bootloader and bootloading the bootloadable? Basically I am trying to avoid needing to bootload in a prod environment because it takes forever and is a separate test. I would rather flash both in the same step.

Brian

0 Likes

After refactoring based on CE213903  I am now correctly bootloading without temporary image placement.

I was also able to verify that flashing the four hex files was good enough to load both the bootloader and bootloadable application.

Should I be flashing the normal hex file or the signed one for the bootloader and/or application? It doesn't appear to work when flashing the signed hex files that are generated from the mcu elf tool.

0 Likes

You should flash the normal hex file.

In addition, it's feasible to generate a merged hex file of both app0 and app1 to simplify the flash process. Please refer to the steps described in the following KBA - Generate Combined Hex File for PSoC 6 MCU Basic Device Firmware Update - KBA227138

0 Likes

Great, thank you!

That led me to the documentation for cymcuelftool and I now am able to generate a single image for both cores and both apps.

I think I have this working now.

Thanks!

Brian

0 Likes