Oberon RTK

Build & Load: RP2350 (S/NS)

Build and load programs with S/NS segregation on RP2350 without debugging

Overview

This document describes how to build, load, and run RTK-based programs with S/NS segregation for the RP2350 without debugging.

  • S/NS programs comprise two ELF files, one for the Secure program and the NSC veneers, one for the Non-secure program.

  • Since two images must be loaded, the UF2 path is not available – ELF binaries via picotool are the load format.

  • make-elf creates the ELF files. The S image is the bootable image and includes the IMAGE_DEF metadata block; the NS image is loaded by the S image and does not need IMAGE_DEF. The framework default is Path A (see IMAGE_DEF).

  • Other guides:

See also Practical Notes.

Set-up

Prerequisites

The build configuration must be set up as explained in:

Flash Layout

RP2350 S/NS programs can be built for two flash layouts:

  • without flash partitions – single contiguous flash region; both images use absolute addresses.

  • with flash partitions – the S image and NS image live in separate partitions; the S image configures QMI address translation so the CPU fetches NS code from a translated virtual address.

Two reference example programs illustrate the difference:

  • <repo>/examples/v3.1/rpi/pico2/Secure – without flash partitions
  • <repo>/examples/v3.1/rpi/pico2/SecurePart – with flash partitions

See Compile and Link: RP2350 for the address-range tables.

Project

  • Directories:

    • S program in <project-dir>/sec
    • NS program in <project-dir>/nonsec
  • Commands as shown are run with cwd = <project-dir>.

  • Two Astrobe configuration files are required, one for the Secure and one for the Non-secure program. An easy way to provide the configuration files is to place them directly in the project directories sec and nonsec, where they can be picked up by the build scripts.

  • Refer to Compile and Link: RP2350 for the address ranges as used by the example programs.

Steps

1. Build the ELF Files

Building the two ELF files for the Secure and the Non-secure program is a multi-step process, which is best implemented and executed using a build script.

The S/NS example programs provide build-elf.cmd, which builds both the Secure and Non-secure ELF binaries, called S-program.elf and NS-program.elf below. This script can serve as basis for your own projects and programs.

2. Load the ELF Files

2a. Put the RP2350 in BOOTSEL mode, which mounts the virtual volume RP2350.

2b. Load the two ELF files using picotool.

  • Without partition table:
picotool load nonsec/<NS-program>.elf -v
picotool load sec/<S-program>.elf -v -x
  • With partition table (assuming partition 0 for S, partition 1 for NS):
picotool load -p 1 nonsec/<NS-program>.elf -v
picotool load -p 0 sec/<S-program>.elf -v -x

The -x option on the second command resets and starts the Secure program.

Inside the Build Script

The build script executes the following steps. Upon error, the script terminates.

  1. Compile the Secure program, running AstrobeBuild, which recursively compiles all modules as needed.

  2. Run sec-epilogue to add the Secure epilogues to all procedures that are exposed to the Non-secure world.

  3. Re-compile the Secure program to ensure that it contains the Secure epilogues.

  4. Link the Secure program, running AstrobeLink.

  5. Run gen-secure to create the Non-secure Callable (NSC) binary, containing one gateway veneer block per procedure exposed to the Non-secure world, plus the interface modules for the Non-secure code to call into the Secure world via the gateways.

  6. Run make-elf to create the Secure ELF binary in sec, with the NSC binary embedded and the IMAGE_DEF block prepended (--image-def).

  7. Compile the Non-secure program, running AstrobeBuild.

  8. Link the Non-secure program, running AstrobeLink.

  9. Run make-elf to create the Non-secure ELF binary in nonsec. No IMAGE_DEF is needed – the NS image is loaded by the S image rather than booted by the boot ROM.

Last updated: 16 May 2026