Most do follow that de facto standard, Stage 2 in the first 256 bytes, user code immediately following.Most of the examples I've found for bare metal seem to be confined to the initial 252 bytes of bootloader2 SRAM, which isn't going to cut it for the project I'm hoping to work towards
The Boot ROM code checksums that first 256 bytes and will only proceed if there's a match -
Code:
.----------------------. .----. | | | | | \|/ | \|/ .---^-.-----. .---------.-------^-.--------------------------. | BS2 : CRC | | Vectors | Prelude | User Code | `-----^-----' `---------^---------^--------------------------'
Code:
.----------------------. .----. .----. | | | | | | | \|/ | \|/ | \|/ .---^-.-----. .---------.------------^-.-------^-.-----------. | BS2 : CRC | | Vectors | Extended BS2 | Prelude | User Code | `-----^-----' `---------^--------------^---------^-----------' .-------------------------------------. .----. .-|---------------------. | | | | | | \|/ | \|/ .-^-^-.-----. .---------.-^------------.-------^-.-----------. | BS2 : CRC | | Vectors | Extended BS2 | Prelude | User Code | `-----^-----' `---------^--------------^---------^-----------'
It has been a while since I did any bare metal but I recall, because it's so simple, only creates the above infrastructure, I used shell scripts to do the build, calling the RP2040 ARM Assemblers, Compilers and Linkers as required, only used SDK provided tools rather than 'cmake' and the Pico SDK.
So it's basically figuring out what the steps are, E&OE -
Boot ROM - Checksums the first 256 bytes of Flash, copies to RAM, jumps to it.
Boot Stage 2 - Configures Flash, loads the Vectors, jumps to the Prelude to User Code.
Prelude - Initialises stack, clears and initialises RAM variables, calls 'main'.
User Code - The 'main' and usually a 'while true' loop.
The User Code is self contained so entirely separate to the rest which gets it there. Though it may be convenient to put some 'BIOS' functionality that can call in the Extended BS2 to save duplication.
I can't remember exactly where clocks and peripherals are initialised, think it may be spread about. but can be anywhere so long as they are initialised before being used.
Once you understand the basic steps and sequence you will see it's all quite elegant and simple, even if those steps can be a little involved in setting up what is needed to make things work. Finding where those parts are within a Pico SDK 'cmake' build will identify what needs to be done and shows how they do it.
Rather than hacking at the bare metal level it might be worth considering hacking at the start of 'main', using a pure Pico SDK build. But it will depend on what you are wanting to do.
Statistics: Posted by hippy — Fri May 03, 2024 2:57 pm