pico-sdk
pico-sdk copied to clipboard
Different behaviour of bin versus uf2 encrypted image
I am trying to load (using picotool) .bin encrypted image instead of .uf2 image in the enc_bootloader sample like scenario. In some cases it fails: rom_chain_image() call in the enc_bootloader returns -4.
If I use hello_serial_enc from pico-examples as is then it works.. However e.g. if I increase size of the image by adding some const data:
#include <stdio.h>
#include "pico/stdlib.h"
const char largedata[300 * 1024] = "ABCD";
const uint TFT_BL_PIN = 13;
int main() {
stdio_init_all();
gpio_init(TFT_BL_PIN);
gpio_set_dir(TFT_BL_PIN, GPIO_OUT);
gpio_put(TFT_BL_PIN, 0);
while (true) {
printf(largedata); //just to do not get largedata optimized out
printf("Hello, world!\n");
printf("I'm an encrypted binary\n");
sleep_ms(1000);
gpio_put(TFT_BL_PIN, 1);
sleep_ms(1000);
gpio_put(TFT_BL_PIN, 0);
}
}
The bootloader Is able to run this application when it is loaded using uf2 image but not when it is loaded using bin file. I tried to use various versions of picotool including last Windows x64 build from pico-sdk-tools. I am on Windows..
I also mentioned this problem in issue 558 of pico-examples
..I use bin images because I need to flash the device through serial line/bluetooth. I have the functionality implemented however I've found the transferred image doesn't work for some reason which after a lot of head-aching pointed me to this problem (so that the problem lies in the encrypted bin image itself)..
I was too in a hurry above: that code doesn't reproduce the problem reliably..
Above I've attached the bin images (unencrypted images) and map files of tho projects which do about the same: sends some 28 bytes through the serial interface and then inverses value of GPIO 13 each second in a loop. -"efis" is binary and map of my project minimalised to find minimal code to reproduce the problem -"hello_serial_enc" is binary and map of "hello_serial_enc" examples project modified to do about the same like upper "efis" image does
- If I load encrypted version of "efis", enc_bootloader returns with -4 on rom_chain_image() call
- If I load encrypted version of "hello_serial_enc", enc_bootloader runs it and it works Above two points are valid for bin encrypted images. If I use uf2 encrypted images, both are working OK.
If I compare map files of those two images I see they are pretty similar. 12 bytes shift between them starts on .rodata.str1.4 Where I believe project name constant string is placed, that sounds be OK.. I am running out of ideas..
I've got an idea to rename my version of "hello_serial_enc" project to the same length like my second project has and now I see the problem also with this test project:
ping @will-v-pi
This appears to be the same issue that was fixed in https://github.com/raspberrypi/picotool/pull/150 - I'm guessing that the gap between the .text and .rodata sections is causing this issue. Try my fix that worked there to remove that gap https://github.com/raspberrypi/pico-examples/issues/558#issuecomment-2388405026 - I've confirmed that fix works for me with your tst.zip
@kilograham I think this might require an SDK fix to prevent gaps between sections within segments in ELF files, such as my suggested linker script change
I've confirmed that fix works for me with your tst.zip
Mentioned patch of linker script doesn't work for me. Please could you try again with following test project? tst1.zip
I use
- GCC10.3.1, Release configuration
- Last MASTER SDK 2.1.1
- picotool v2.1.2-develop used for encryption (picotool built tautomatically into build/_deps)
- picotool 2.1.1 from pico-sdk-tools (full with USB) used to load ".bin" binary into partition
Mentioned patch of linker script doesn't work for me. Please could you try again with following test project? tst1.zip
This test project does not contain pico_sdk_init() in your CMakeLists.txt, so will not work with the pico-sdk - you need to add pico_sdk_init() after the project line.
I've confirmed and my patch does fix the issue on my system (using the same compiler/sdk/picotool) for that test project too, once I've added the pico_sdk_init() line to it. I'd suggest making sure that the ABCD.ld file generated in your build folder contains the patch, and if not then add the patch manually to that file and rebuild.
you need to add pico_sdk_init() after the project line.
Yes, I have it in my CMakelists.txt of course however since I have more executables (not related to this test) in the same file I deleted non needed stuff (and deleted too much)..
This is my generated ABCD.ld file:
(postfixed by .txt to be able to attach it here). I think it contains the patch but please, could you look?
Please, if you rollback that linker file patch (and use the ld file from MASTER SDK), do you see the problem? ( I mean just to confirm that your patch is related with my problem)..
I think it contains the patch but please, could you look?
Yes, that contains the patch, so I'm not sure what's going wrong on your system
Please, if you rollback that linker file patch (and use the ld file from MASTER SDK), do you see the problem? ( I mean just to confirm that your patch is related with my problem)..
Yes, I've confirmed I can reproduce your problem with tst1.zip, and it goes away for me after applying that patch to the SDK linker script, so I'm not sure why the patch is not fixing it for you.
Thank you. I am running out of ideas. Please, could you attach your map file (ABCD.elf.map) of the binary with patch included so I could try to compare and find the differences?
I made one more experiment: I've converted uf2 file of my project using uf2conv.py from here: https://github.com/microsoft/uf2/blob/master/utils/uf2conv.md
The command line was as follows:
python uf2conv.py efis.uf2 --family=0xe48bff59 --convert --output efis.bin
The bin file made this way works!
BTW: file generated by that python script is 32bytes bigger than one generated by the picotool. I've tried that with both versions of linker scripts, it works in both cases..
..not sure if this information could bring some light into the problem but in each case I have a workaround..
Just to add another example of gaps in ELF files causing issues
This is with OpenOCD loading the ELF, which suggests that OpenOCD loads in sections rather than segments, and therefore leaves ffs where there are gaps between sections, rather than the 00s that the hash expects.
gdb for JLink was leaving ffs too inbetween sections, so I had to clone .ld script and manually align(16) at the end of .text (i.e. before .rodata). Strangely enough, disassembler I tried (IDA) was showing those ff-s belong to some section named LOAD although there was no such section in my .elf
Merged into develop