dwelch67
Posts: 1006
Joined: Sat May 26, 2012 5:32 pm

[SOLVED] pico rf2040 booting

Thu Jan 28, 2021 9:02 pm

I am trying to get my pico booted and have hit the next issue.

uf2 file format that is all fine and good.

the chip docs say the first 256 bytes on flash (address 0x10000000) have a crc32 with certain parameters. I can read and verify the blink example and check the crc32 code. my uf2 file matches the algorithm.

hexdump -C notmain.uf2
00000000 55 46 32 0a 57 51 5d 9e 00 20 00 00 00 10 04 20 |UF2.WQ].. ..... |
00000010 00 01 00 00 00 00 00 00 01 00 00 00 56 ff 8b e4 |............V...|
00000020 01 31 03 32 c0 46 c0 46 fa e7 00 00 00 00 00 00 |.1.2.F.F........|
00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000110 00 00 00 00 00 00 00 00 00 00 00 00 b8 8e 2e 36 |...............6|
00000120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
000001f0 00 00 00 00 00 00 00 00 00 00 00 00 30 6f b1 0a |............0o..|
00000200



Disassembly of section .text:

10000000 <loop>:
10000000: 3101 adds r1, #1
10000002: 3203 adds r2, #3
10000004: 46c0 nop ; (mov r8, r8)
10000006: 46c0 nop ; (mov r8, r8)
10000008: e7fa b.n 10000000 <loop>

was hoping to see this code running in the debugger (openocd).

The pico debugger thing works well, that was a very good idea, I just wish it worked on other cortex-m products (yep tried it).

They copy to sram5 so they say check the crc there then branch to it (in sram). I dont see the code there either. If I change the uf2 file to sram it does seem to at least write it to sram, but does not execute it. and if you reset it is gone, so ...

Perhaps I have not fully read or understood the datasheet for the part. The code is not the most friendly to read, nor the tools, I think i found a bug in the doc already as well as there are gaps of information. SIGNIFICANTLY better than prior information and experience to the full sized pi's I will grant them that. (the implication is the watchdog powers up disabled, for example but needs work)

I would be happy to blink an led from poking registers or downloading a program to ram at this point...

David (dwelch67)
Last edited by dwelch67 on Sat Jan 30, 2021 9:58 pm, edited 1 time in total.

dwelch67
Posts: 1006
Joined: Sat May 26, 2012 5:32 pm

Re: pico rf2040 booting

Thu Jan 28, 2021 9:05 pm

openocd seemed to support some flash sector erasing and writing too and that did not make a difference. Nor did picotool which claimed it did something too. so I suspect there are rules for that secondary bootloader, right now dont care about enabling access to the flash (can you believe it is off chip?) if they copy 256 bytes, that is a good enough start, or should be.

David

dwelch67
Posts: 1006
Joined: Sat May 26, 2012 5:32 pm

Re: pico rf2040 booting

Fri Jan 29, 2021 3:43 am

It copies the 256 bytes to 0x20041f00

dwelch67
Posts: 1006
Joined: Sat May 26, 2012 5:32 pm

Re: pico rf2040 booting

Fri Jan 29, 2021 4:20 am

Okay I see, cant get it working yet...

cleverca22
Posts: 3979
Joined: Sat Aug 18, 2012 2:33 pm

Re: pico rp2040 booting

Fri Jan 29, 2021 5:54 am

i had done some investigation of that low level in another thread:
cleverca22 wrote:
Sun Jan 24, 2021 3:57 am
i'm also interested in the low-level startup before the user-code comes into play

poking around in the .elf files that the examples produce, i can see:

Code: Select all

10000100 <__reset_start>:
10000100:       4827            ldr     r0, [pc, #156]  ; (100001a0 <__get_current_exception+0xa>)
10000102:       e000            b.n     10000106 <__vector_entry>
that the code begins 256 bytes into the flash space
the 2ndstage that deals with enabling XIP is missing, but thats somewhat good, the 2nd stage is specific to which SPI chip you have, not what you want to run

Code: Select all

Disassembly of section .data:

200000c0 <mutex_enter_blocking>:
200000c0:       b510            push    {r4, lr}
200000c2:       6802            ldr     r2, [r0, #0]
200000c4:       2400            movs    r4, #0
then i can see a chunk of .data sitting at the base of the raid0'd sram, but the question is, how did it wind up there...

Code: Select all

10000112 <_reset_handler>:
1000011a:       a412            add     r4, pc, #72     ; (adr r4, 10000164 <data_cpy_table>)
10000164 <data_cpy_table>:
10000164:       10002df8        .word   0x10002df8
10000168:       200000c0        .word   0x200000c0
1000016c:       20000a64        .word   0x20000a64

10000170:       1000379c        .word   0x1000379c
10000174:       20040000        .word   0x20040000
10000178:       20040000        .word   0x20040000

1000017c:       1000379c        .word   0x1000379c
10000180:       20041000        .word   0x20041000
10000184:       20041000        .word   0x20041000
10000188:       00000000        .word   0x00000000
aha, as i suspected, there is code that runs on startup, to copy data from flash->sram, ive seen the same thing in both AVR and bootrom's before

Code: Select all

[nix-shell:~/apps/rpi/pico/pico-examples/build]$ arm-none-eabi-objdump -p blink/blink.elf

blink/blink.elf:     file format elf32-littlearm

Program Header:
    LOAD off    0x00010000 vaddr 0x10000000 paddr 0x10000000 align 2**16
         filesz 0x00002df8 memsz 0x00002df8 flags rwx
    LOAD off    0x000200c0 vaddr 0x200000c0 paddr 0x10002df8 align 2**16
         filesz 0x000009a4 memsz 0x000009a4 flags rwx
    LOAD off    0x00020a64 vaddr 0x20000a64 paddr 0x20000a64 align 2**16
         filesz 0x00000000 memsz 0x000002ec flags rw-
private flags = 5000200: [Version5 EABI] [soft-float ABI]
aha, and that makes more sense
the virtual address in the LOAD commands (and what the linker uses everywhere), is the sram addr
but the physical address is over in the flash

so the linker script says to put .text in flash, both virtually and physically
but then put .data at the virt addr of ram, but append it to .text in flash, and record that as a physical addr
and .bss is all virtual, since its not stored

https://github.com/raspberrypi/pico-sdk ... #L255-L274

Code: Select all

data_cpy_table:
#if PICO_COPY_TO_RAM
.word __ram_text_source__
.word __ram_text_start__
.word __ram_text_end__
#endif
.word __etext
.word __data_start__
.word __data_end__
the assembly is just blindly inserting the address for various symbols into a table
https://github.com/raspberrypi/pico-sdk ... #L104-L126

Code: Select all

MEMORY
{
    FLASH(rx) : ORIGIN = 0x10000000, LENGTH = 2048k
    RAM(rwx) : ORIGIN =  0x20000000, LENGTH = 256k
    SCRATCH_X(rwx) : ORIGIN = 0x20040000, LENGTH = 4k
    SCRATCH_Y(rwx) : ORIGIN = 0x20041000, LENGTH = 4k
}

...
    .text : {
        __ram_text_start__ = .;
...
        __ram_text_end__ = .;
    } > RAM AT> FLASH
    __ram_text_source__ = LOADADDR(.text);
the start/end symbols are the virtual addresses the linked picked within the RAM section, and i'm guessing the "AT>FLASH" is a linker statement to say its actually stored in FLASH instead, then LOADADDR gets that flash addr, and assigns it to a src symbol

so in the end, there is a mix of sections
.flashtext is XIP from the flash
.rodata is just read directly from flash via the same route as XIP
.ram_vector_table goes into ram first, for alignment reasons
.text lives in both flash and ram, and gets copied on startup
.data then follows, copied from flash->ram
then .bss .heap and the stack fill the rest of ram

edit:
the 2ndstage that deals with enabling XIP is missing, but thats somewhat good, the 2nd stage is specific to which SPI chip you have, not what you want to run
after re-reading the source, i checked with objdump -D, and found that it is present in the elf, but the section had weird tags, so objdump wasnt decompiling it
objdump also defaults to trying to decompile it as arm32, but its thumb code, so everything is mis-aligned
-Mforce-thumb solves that though, i can see the code, but cant make much sense of it at a glance
but it does give enough context to find https://github.com/raspberrypi/pico-sdk ... oot_stage2 where i can see the expected code
since i also plan on doing similar low-level stuff to what your doing

dwelch67
Posts: 1006
Joined: Sat May 26, 2012 5:32 pm

Re: pico rf2040 booting

Fri Jan 29, 2021 2:20 pm

yes I saw those second stage bootloaders I tried the generic one, no joy.

int main() {
const uint LED_PIN = 25;
gpio_init(LED_PIN);
gpio_set_dir(LED_PIN, GPIO_OUT);
while (true) {
gpio_put(LED_PIN, 1);
sleep_ms(250);
gpio_put(LED_PIN, 0);
sleep_ms(250);
}
}

if I replace the sleep_ms functions with a simple delay, this results in about 100 bytes of code (including some startup and a count to N function)

yet the uf2 is 0x32 blocks of 256, 12800 bytes. what is all the other code.

I tried taking the first block from uf2 which if it is modelled after the boot2 sources it will start up the spi flash and then branch to 0x10000100.

Now how/why does the bootrom detect and accesses the flash, copies 256 bytes from it but then doesnt simply leave it open and visible at 0x10000000?

dwelch67
Posts: 1006
Joined: Sat May 26, 2012 5:32 pm

Re: pico rf2040 booting

Fri Jan 29, 2021 2:31 pm

independent of all that even if the second stage bootloader is not successful nor bothers trying to re-init the spi flash and open it up. that code should be visible.

There is also some other enable or magic with respect to the gpio. repeating what the blink program does to change the function to SIO and making it an output and all, that the function register didnt take a write. at least when run from ram or poked directly.

dwelch67
Posts: 1006
Joined: Sat May 26, 2012 5:32 pm

Re: pico rf2040 booting

Fri Jan 29, 2021 2:53 pm

should be visible and should run.

kilograham
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 752
Joined: Fri Apr 12, 2019 11:00 am
Location: austin tx

Re: pico rf2040 booting

Fri Jan 29, 2021 4:34 pm

you need to stuff from runtime_init() which un-resets various blocks and sets up clocks (although you could skip the clock for now)

also you can use busy_wait_us() if you don't want to pull in sleep/timer stuff

dwelch67
Posts: 1006
Joined: Sat May 26, 2012 5:32 pm

Re: pico rf2040 booting

Fri Jan 29, 2021 4:44 pm

Excellent, thanks!

dwelch67
Posts: 1006
Joined: Sat May 26, 2012 5:32 pm

Re: pico rf2040 booting

Fri Jan 29, 2021 6:21 pm

And the resets are documented, I had not circled back around to that I had spent a day on the uf2 stuff and then stage 2 bootloader then briefly leds and called it a night before looking for reset controls...I should have all the pieces now.

Thanks
David

dwelch67
Posts: 1006
Joined: Sat May 26, 2012 5:32 pm

Re: pico rf2040 booting

Sat Jan 30, 2021 3:42 am

https://github.com/dwelch67/raspberrypi-pico

Okay it blinks the led now...mostly tripped over my own feet, finally got around to all of the relevant topics.

Return to “SDK”