Note: I've just migrated to a different physical server to run Spivey's Corner,
with a new architecture, a new operating system, a new version of PHP, and an updated version of MediaWiki.
Please let me know if anything needs adjustment! – Mike

Pi Pico boot process

Copyright © 2024 J. M. Spivey
Jump to navigation Jump to search

Stage 1

The RP2040 has an inbuilt, immutable ROM that includes the initial startup code at address 0x0000 0000. This code copies the first 256 bytes of an external SPI Flash memory into RAM (at address 0x2000 0000), verifies a checksum, then executes it.

On coming out of reset, the system clock is taken from an internal ring oscillator that runs at about 3.5 MHz.

Stage 2

The second-stage boot code is specific to the kind of Flash chip on the board. It configures the execute-in-place (XIP) interface to run code from the Flash chip, with the chip contents appearing at address 0x1000 0000. Then, assuming that the Flash image has a vector table immediately following the stage 2 bootloader, it sets the vector table offset register (VTOR) to point to thjis table, loads the stack pointer from the first entry, and branches to the reset vector, which is configured to point into the Flash image.

Stage 3

The reset code runs from Flash, and initialises the hardware, including starting the crystal oscillator and PLLs that derive system clocks from it. Different configurations then behave in different ways; the usual default is to continue running code from the Flash memory using XIP, and benefitting from a read-only cache. For micro:bian, the routine __reset runs from Flash, and instead copies the text and data segments of the program from Flash into RAM. It also copies the vector table to an allocated place at the start of RAM, then sets the VTOR to point to this copy. It begins to execute the program at function __start in RAM. The function __start never returns, so the system makes no further use of Flash unless the program makes explicit access to it.