Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for Raspberry-pi pico2 (rp2350) #524

Merged
merged 18 commits into from
Jan 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions .github/workflows/test-build-pico-sdk.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
name: Wolfboot Reusable Build Workflow for Raspberry Pi Pico2 (rp2350)

on:

workflow_call:
inputs:
arch:
required: true
type: string
config-file:
required: true
type: string
make-args:
required: false
type: string
target:
required: true
type: string

jobs:

build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
with:
submodules: true

- uses: actions/checkout@main
with:
repository: raspberrypi/pico-sdk
path: pico-sdk

- name: Workaround for sources.list
run: sudo sed -i 's|http://azure.archive.ubuntu.com/ubuntu/|http://mirror.arizona.edu/ubuntu/|g' /etc/apt/sources.list

- name: Update repository
run: sudo apt-get update

- name: Install cross compilers
run: |
sudo apt-get install -y gcc-arm-none-eabi

- name: make distclean
run: |
make distclean

- name: Select config
run: |
cp ${{inputs.config-file}} .config && make include/target.h

- name: Build tools
run: |
make -C tools/keytools && make -C tools/bin-assemble

- name: pre-build wolfboot
run: |
make
- name: build wolfboot with pico-sdk
run: |
cd IDE/pico-sdk/${{inputs.target}}/wolfboot
mkdir build
cd build
cmake ../ -DPICO_SDK_PATH="$GITHUB_WORKSPACE/pico-sdk" -DPICO_PLATFORM=${{inputs.target}}
make
7 changes: 7 additions & 0 deletions .github/workflows/test-configs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -439,3 +439,10 @@ jobs:
with:
arch: host
config-file: ./config/examples/sim-wolfHSM.config

rp2350_test:
uses: ./.github/workflows/test-build-pico-sdk.yml
with:
arch: arm
config-file: ./config/examples/rp2350.config
target: rp2350
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,13 @@ IDE/Renesas/e2studio/RX72N/app_RenesasRX01/src/smc_gen
IDE/Renesas/e2studio/RX72N/wolfBoot/HardwareDebug
IDE/Renesas/e2studio/RX72N/wolfBoot/src/smc_gen

# IDE pico-sdk build directories
IDE/pico-sdk/rp2350/wolfboot/build
IDE/pico-sdk/rp2350/test-app/build

# Third party test application distributed off-tree
IDE/pico-sdk/rp2350/test-app/blink.c

# Renesas Libraries
lib/r_bsp
lib/r_config
Expand Down
143 changes: 143 additions & 0 deletions IDE/pico-sdk/rp2350/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
## wolfBoot port for rp2350 (Raspberry pi pico 2)

### Support for TrustZone

By default, TZEN=1 is enabled in the provided configuration. wolfBoot will run
from the Secure domain, and will stage the application in the Non-Secure domain.

The flash memory is divided as follows:

- wolfBoot partition (0x10000000 - 0x1003FFFF), 224 KB
- Non-secure callable partition (for secure gateway) (0x10038000 - 0x1003FFFF), 32 KB
- Boot partition (0x10040000 - 0x1007FFFF), 768 KB
- Update partition (0x10100000 - 0x1013FFFF), 768 KB
- Unused flash space (0x101C1000 - 0x101FFFFF), 252 KB
- Swap space (0x101C0000 - 0x101C0FFF), 4 KB

The SRAM bank0 is assigned to the Secure domain, and enforced using both SAU and `ACCESS_CONTROL` registers.

- Secure SRAM0-3: 0x20000000 - 0x2003FFFF, 256 KB
- Non-secure SRAM4-7: 0x20040000 - 0x2007FFFF, 256 KB
- Non-secure stack for application SRAM8-9: 0x20080000 - 0x20081FFF, 8 KB


### Requirements

#### External debugger

As the two images (bootloader + application) are stored in different areas in
the flash memory, a SWD connector is recommended to upload the binary images
into the flash, as opposed to the default bootloader, allowing to upload
non-signed applications into a storage device.

The scripts used in this example expect a JLink to be connected to the SWD port
as documented [here](https://kb.segger.com/Raspberry_Pi_Pico).

There is documentation below on how to do this with `picotool` instead, the
scripts to error that it cannot file the JLink if you wish to use `picotool`
instead, but this can be ignored.

#### PicoSDK

Clone the repository from raspberrypi's github:

```
git clone https://github.com/raspberrypi/pico-sdk.git
```

Export the `PICO_SDK_PATH` environment variable to point to the pico-sdk directory:

```
export PICO_SDK_PATH=/path/to/pico-sdk
```

### Configuring wolfBoot to build with pico-sdk

From wolfBoot root directory, copy the example configuration:

```
cp config/examples/rp2350.config .config
```

You can now edit the .config file to change partition sizes/offsets, algorithms,
disable trustzone, add/remove features, etc.

When TZEN=0, the application will run in the Secure domain.

When the configuration is complete, run `make`. This will:

- Build the key tools (keygen & sign):
- Generate the configuration header `target.h`
- Generate a new keypair (only once), and place the public key in the
keystore

The environment has now been prepared to build and flash the two images
(wolfBoot + test application).

### Building and uploading wolfBoot.bin

After preparing the configuration and creating the keypair,
return to the `IDE/pico-sdk/rp2350/` directory and run:

```
cd wolfboot
export PICO_SDK_PATH=...
./build-wolfboot.sh
```

The script above will compile wolfboot as rp2350 second-stage bootloader.
This version of wolfboot incorporates the `.boot2` sequence needed to enable
the QSPI device, provided by the pico-sdk and always embedded in all
applications.

wolfboot.bin contains the bootloader, and can be loaded into the RP2350,
starting at address 0x10000000. The script will automatically upload the binary
if a JLink debugger is connected.

If you do not have a JLink you can install the binary using:

```
picotool load build/wolfboot.uf2
```

### Building and uploading the application

```
cd ../test-app
./build-signed-app.sh
```
The script above will compile the test application and sign it with the
wolfBoot private key. The signed application is then uploaded to the boot
partition of the flash memory, at address 0x10040000.

The linker script included is modified to change the application entry point
from 0x10000000 to 0x10040400, which is the start of the application code,
taking into account the wolfBoot header size.

The application is signed with the wolfBoot private key, and the signature is
stored in the manifest header of the application binary.

The output file `build/blink_v1_signed.bin` is automatically uploaded to the
RP2350 if a JLink debugger is connected.
The application image is stored in the boot partition, starting at address
0x10040000.
The entry point of the application (0x10040400), set in the linker script
`hal/rp2350-app.ld`, is the start of the application code, taking into account
the wolfBoot header size.

To use `picotool` instead run:

```
picotool load build/blink_v1_signed.bin -o 0x10040000
```

### Testing the application

The application is a simple blinky example, which toggles the LED on the board
every 500ms.

If the above steps are successful, the LED on the board should start blinking.

The code has been tested on a Seeed studio XIAO RP2350 board and a Raspberry Pi
Pico 2 (non-WiFi version).

35 changes: 35 additions & 0 deletions IDE/pico-sdk/rp2350/test-app/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
cmake_minimum_required(VERSION 3.13)
set(WOLFBOOT_PATH ../../../../)
set(CMAKE_CXX_COMPILER arm-none-eabi-gcc)
set(LIB_PICO_RUNTIME_INIT=0)

include(${PICO_SDK_PATH}/pico_sdk_init.cmake)

set(PICOTOOL_FETCH_FROM_GIT_PATH ../wolfboot/build/picotool)
set(BOOT_STAGE2_FILE ${CMAKE_CURRENT_LIST_DIR}/boot2_empty.S)
set(PICO_NO_RUNTIME 1)

project(blink)

# initialize the Raspberry Pi Pico SDK
pico_sdk_init()


add_executable(blink
blink.c
runtime.c
)

target_compile_options(blink PRIVATE
-DPICO_RUNTIME_NO_INIT_BOOTROM_RESET=1
-DPICO_RUNTIME_NO_INIT_CLOCKS=1
-DPICO_TIME_DEFAULT_ALARM_POOL_DISABLED=1
)
target_compile_definitions(blink PRIVATE PICO_NO_RUNTIME=1)

pico_set_linker_script(blink ../../../../../hal/rp2350-app.ld)
target_link_libraries(blink pico_stdlib)

# create map/bin/hex/uf2 file etc.
pico_add_extra_outputs(blink)

17 changes: 17 additions & 0 deletions IDE/pico-sdk/rp2350/test-app/build-signed-app.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash

mkdir -p build
cd build
cmake .. -DPICO_SDK_PATH=$PICO_SDK_PATH -DPICO_PLATFORM=rp2350

# Get off-tree source file from raspberry pico-examples
curl -o blink.c https://raw.githubusercontent.com/raspberrypi/pico-examples/refs/tags/sdk-2.1.0/blink/blink.c

make clean && make

IMAGE_HEADER_SIZE=1024 ../../../../../tools/keytools/sign --sha256 --ecc256 blink.bin \
../../../../../wolfboot_signing_private_key.der 1

cd ..

JLinkExe -Device RP2350_M33_0 -If swd -Speed 4000 -CommanderScript flash_app.jlink
6 changes: 6 additions & 0 deletions IDE/pico-sdk/rp2350/test-app/flash_app.jlink
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
connect
r
loadfile build/blink_v1_signed.bin 0x10040000
r
g
exit
34 changes: 34 additions & 0 deletions IDE/pico-sdk/rp2350/test-app/runtime.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/* runtime.c
*
* Custom pre-init for non-secure application, staged by wolfBoot.
* Wolfboot test application for raspberry-pi pico2 (rp2350)
*
* Copyright (C) 2025 wolfSSL Inc.
*
* This file is part of wolfBoot.
*
* wolfBoot is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfBoot is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#include <stdint.h>
typedef void (*preinit_fn_t)(void);

void runtime_init_cpasr(void)
{
volatile uint32_t *cpasr_ns = (volatile uint32_t*) 0xE000ED88;
*cpasr_ns |= 0xFF;
}

preinit_fn_t __attribute__((section(".nonsecure_preinit_array"))) nonsecure_preinit[] =
{ &runtime_init_cpasr };
5 changes: 5 additions & 0 deletions IDE/pico-sdk/rp2350/wolfboot/.gdbinit
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
tar rem:3333
file build/wolfboot.elf
add-symbol-file ../test-app/build/blink.elf
foc c

Loading
Loading