Skip to content

Add note about pico-sdk-tools to README.md #146

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

Merged
merged 6 commits into from
Apr 22, 2025
Merged
Show file tree
Hide file tree
Changes from 5 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
99 changes: 99 additions & 0 deletions BUILDING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
## Building

You need to set PICO_SDK_PATH in the environment, or pass it to cmake with `-DPICO_SDK_PATH=/path/to/pico-sdk`. To use features such as signing or hashing, you will need to make sure the mbedtls submodule in the SDK is checked out - this can be done by running this from your SDK directory.

```console
git submodule update --init lib/mbedtls
```

You also need to install `libusb-1.0` if you want to use the USB functionality.

> If libusb-1.0 is not installed, picotool still builds, but it omits all options that deal with managing a pico via USB (load, save, erase, verify, reboot). Builds that do not include USB support can be recognized because these commands won't appear in the output of the help command. The build output message 'libUSB is not found - no USB support will be built' also appears in the build logs.

### Linux / macOS

Use your favorite package tool to install dependencies. For example, on Ubuntu:

```console
sudo apt install build-essential pkg-config libusb-1.0-0-dev cmake
```

Then simply build like a normal CMake project:

```console
mkdir build
cd build
cmake ..
make
```

On Linux you can add udev rules in order to run picotool without sudo:

```console
sudo cp udev/99-picotool.rules /etc/udev/rules.d/
```

### Windows

##### For Windows without MinGW

Download libUSB from here https://libusb.info/

Set LIBUSB_ROOT environment variable to the install directory.
```console
mkdir build
cd build
cmake -G "NMake Makefiles" ..
nmake
```

##### For Windows with MinGW in WSL

Download libUSB from here https://libusb.info/

Set LIBUSB_ROOT environment variable to the install directory.

```console
mkdir build
cd build
cmake ..
make
```

##### For Windows with MinGW in MSYS2:

No need to download libusb separately or set `LIBUSB_ROOT`.

```console
pacman -S $MINGW_PACKAGE_PREFIX-{toolchain,cmake,libusb}
mkdir build
cd build
cmake .. -DCMAKE_INSTALL_PREFIX=$MINGW_PREFIX
cmake --build .
```

## Installing (so the Pico SDK can find it)

The Raspberry Pi Pico SDK ([pico-sdk](https://github.com/raspberrypi/pico-sdk)) version 2.0.0 and above uses `picotool` to do the ELF-to-UF2 conversion previously handled by the `elf2uf2` tool in the SDK. The SDK also uses `picotool` to hash and sign binaries.

Whilst the SDK can download picotool on its own per project, if you have multiple projects or build configurations, it is preferable to install a single copy of `picotool` locally. This can be done most simply with `make install` or `cmake --install .`, using `sudo` if required; the SDK will use this installed version by default.

> On some Linux systems, the `~/.local` prefix may be used for an install without `sudo`; from your build directory simply run
> ```console
> cmake -DCMAKE_INSTALL_PREFIX=~/.local ..
> make install
> ```
> This will only work if `~/.local/bin` is included in your `PATH`

### Custom Path Installation (eg if you can't use `sudo`)

Alternatively, you can install to a custom path via:

```console
cmake -DCMAKE_INSTALL_PREFIX=$MY_INSTALL_DIR -DPICOTOOL_FLAT_INSTALL=1 ..
make install
```

In order for the SDK to find `picotool` in this custom folder, you will usually need to set the `picotool_DIR` variable in your project. This can be achieved either by setting the `picotool_DIR` environment variable to `$MY_INSTALL_DIR/picotool`, by passing `-Dpicotool_DIR=$MY_INSTALL_DIR/picotool` to your `cmake` command, or by adding `set(picotool_DIR $MY_INSTALL_DIR/picotool)` to your CMakeLists.txt file.

> See the [find_package documentation](https://cmake.org/cmake/help/latest/command/find_package.html#config-mode-search-procedure) for more details
110 changes: 9 additions & 101 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,101 +1,3 @@
## Building

You need to set PICO_SDK_PATH in the environment, or pass it to cmake with `-DPICO_SDK_PATH=/path/to/pico-sdk`. To use features such as signing or hashing, you will need to make sure the mbedtls submodule in the SDK is checked out - this can be done by running this from your SDK directory.

```console
git submodule update --init lib/mbedtls
```

You also need to install `libusb-1.0`.

### Linux / macOS

Use your favorite package tool to install dependencies. For example, on Ubuntu:

```console
sudo apt install build-essential pkg-config libusb-1.0-0-dev cmake
```

> If libusb-1.0-0-dev is not installed, picotool still builds, but it omits all options that deal with managing a pico via USB (load, save, erase, verify, reboot). Builds that do not include USB support can be recognized because these commands also do not appear in the help command. The build output message 'libUSB is not found - no USB support will be built' also appears in the build logs.

Then simply build like a normal CMake project:

```console
mkdir build
cd build
cmake ..
make
```

On Linux you can add udev rules in order to run picotool without sudo:

```console
sudo cp udev/99-picotool.rules /etc/udev/rules.d/
```

### Windows

##### For Windows without MinGW

Download libUSB from here https://libusb.info/

set LIBUSB_ROOT environment variable to the install directory.
```console
mkdir build
cd build
cmake -G "NMake Makefiles" ..
nmake
```

##### For Windows with MinGW in WSL

Download libUSB from here https://libusb.info/

set LIBUSB_ROOT environment variable to the install directory.

```console
mkdir build
cd build
cmake ..
make
```

##### For Windows with MinGW in MSYS2:

No need to download libusb separately or set `LIBUSB_ROOT`.

```console
pacman -S $MINGW_PACKAGE_PREFIX-{toolchain,cmake,libusb}
mkdir build
cd build
cmake .. -DCMAKE_INSTALL_PREFIX=$MINGW_PREFIX
cmake --build .
```

## Usage by the Raspberry Pi Pico SDK

The Raspberry Pi Pico SDK ([pico-sdk](https://github.com/raspberrypi/pico-sdk)) version 2.0.0 and above uses `picotool` to do the ELF-to-UF2 conversion previously handled by the `elf2uf2` tool in the SDK. The SDK also uses `picotool` to hash and sign binaries.

Whilst the SDK can download picotool on its own per project, if you have multiple projects or build configurations, it is preferable to install a single copy of `picotool` locally. This can be done most simply with `make install` or `cmake --install .`, using `sudo` if required; the SDK will use this installed version by default.

> On some Linux systems, the `~/.local` prefix may be used for an install without `sudo`; from your build directory simply run
> ```console
> cmake -DCMAKE_INSTALL_PREFIX=~/.local ..
> make install
> ```
> This will only work if `~/.local/bin` is included in your `PATH`

Alternatively, you can install to a custom path via:

```console
cmake -DCMAKE_INSTALL_PREFIX=$MY_INSTALL_DIR -DPICOTOOL_FLAT_INSTALL=1 ..
make install
```

In order for the SDK to find `picotool` in this custom folder, you will usually need to set the `picotool_DIR` variable in your project. This can be achieved either by setting the `picotool_DIR` environment variable to `$MY_INSTALL_DIR/picotool`, by passing `-Dpicotool_DIR=$MY_INSTALL_DIR/picotool` to your `cmake` command, or by adding `set(picotool_DIR $MY_INSTALL_DIR/picotool)` to your CMakeLists.txt file.

> See the [find_package documentation](https://cmake.org/cmake/help/latest/command/find_package.html#config-mode-search-procedure) for more details

## Overview

`picotool` is a tool for working with RP2040/RP2350 binaries, and interacting with RP2040/RP2350 devices when they are in BOOTSEL mode. (As of version 1.1 of `picotool` it is also possible to interact with devices that are not in BOOTSEL mode, but are using USB stdio support from the Raspberry Pi Pico SDK by using the `-f` argument of `picotool`).
Expand Down Expand Up @@ -155,6 +57,12 @@ Use "picotool help <cmd>" for more info

Note commands that aren't acting on files require a device in BOOTSEL mode to be connected.

## Building & Installing

If you don't want to build picotool yourself, you can find pre-built executables for Windows, macOS, and Linux in the [pico-sdk-tools](https://github.com/raspberrypi/pico-sdk-tools/releases) repository. Assuming you've extracted that archive to `$EXTRACT_LOCATION` (with the actual picotool executable at `$EXTRACT_LOCATION/picotool/picotool`), you can point the Pico SDK at this binary by setting the `picotool_DIR` environment variable to `$EXTRACT_LOCATION/picotool`, or by passing `-Dpicotool_DIR=$EXTRACT_LOCATION/picotool` to your `cmake` command or setting it in your `CMakeLists.txt` file.

If you do wish to build picotool yourself, then see [Building](BUILDING.md#building) for build instructions. For the Pico SDK to find your picotool you will need to install it, the simplest way being to run `cmake --install .` - see [Installing](BUILDING.md#installing-so-the-pico-sdk-can-find-it) for more details and alternatives. **You cannot just copy the binary into your `PATH`, else the Pico SDK will not be able to locate it.**

## info

There is _Binary Information_ support in the SDK which allows for easily storing compact information that `picotool`
Expand Down Expand Up @@ -668,7 +576,7 @@ OPTIONS:

## encrypt

`encrypt` allows you to encrypt and sign a binary for use on the RP2350. By default, it will sign the encrypted binary, but that can be configured similarly to `picotool sign`.
`encrypt` allows you to encrypt and sign a binary for use on the RP2350. By default, it will sign the encrypted binary, but that can be configured similarly to `picotool seal`.

The encrypted binary will have the following structure:

Expand Down Expand Up @@ -942,10 +850,10 @@ These commands will set/get specific rows of OTP. By default, they will write/re

### load

This command allows loading of a range of OTP rows onto the device. The source can be a binary file, or a JSON file such as the one output by `picotool sign`. The schema for this JSON file is [here](json/schemas/otp-schema.json)
This command allows loading of a range of OTP rows onto the device. The source can be a binary file, or a JSON file such as the one output by `picotool seal`. The schema for this JSON file is [here](json/schemas/otp-schema.json)
For example, if you wish to sign a binary and then test secure boot with it, you can run the following set of commands:
```text
$ picotool sign hello_world.elf hello_world.signed.elf private.pem otp.json
$ picotool seal --sign hello_world.elf hello_world.signed.elf private.pem otp.json
$ picotool load hello_world.signed.elf
$ picotool otp load otp.json
$ picotool reboot
Expand Down
Loading