mirror of
https://codeberg.org/libreboot/picotool.git
synced 2025-07-04 16:27:03 +00:00
Compare commits
No commits in common. "master" and "2.0.0" have entirely different histories.
41 changed files with 709 additions and 2411 deletions
|
@ -1 +0,0 @@
|
||||||
lib/pico-sdk
|
|
36
.github/workflows/bazel_build.yml
vendored
36
.github/workflows/bazel_build.yml
vendored
|
@ -1,36 +0,0 @@
|
||||||
name: Bazel presubmit checks
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
pull_request:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
bazel-build-check:
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
os: [ubuntu-latest, macos-latest]
|
|
||||||
fail-fast: false
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
- name: Get Bazel
|
|
||||||
uses: bazel-contrib/setup-bazel@0.9.0
|
|
||||||
with:
|
|
||||||
# Avoid downloading Bazel every time.
|
|
||||||
bazelisk-cache: true
|
|
||||||
# Store build cache per workflow.
|
|
||||||
disk-cache: ${{ github.workflow }}
|
|
||||||
# Share repository cache between workflows.
|
|
||||||
repository-cache: true
|
|
||||||
- name: Fetch latest Pico SDK
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
repository: raspberrypi/pico-sdk
|
|
||||||
ref: develop
|
|
||||||
fetch-depth: 0
|
|
||||||
path: lib/pico-sdk
|
|
||||||
- name: Bazel Picotool with develop pico-sdk
|
|
||||||
run: bazel build @picotool//:picotool --override_module=pico-sdk=lib/pico-sdk
|
|
7
.github/workflows/choco_packages.config
vendored
7
.github/workflows/choco_packages.config
vendored
|
@ -1,7 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<packages>
|
|
||||||
<package id="gcc-arm-embedded" version="10.2.1" />
|
|
||||||
<package id="cmake" version="3.25.2" installArguments="ADD_CMAKE_TO_PATH=System" />
|
|
||||||
<package id="mingw" version="12.2.0" />
|
|
||||||
<package id="ninja" version="1.11.1" />
|
|
||||||
</packages>
|
|
73
.github/workflows/test.yml
vendored
73
.github/workflows/test.yml
vendored
|
@ -1,73 +0,0 @@
|
||||||
on:
|
|
||||||
push:
|
|
||||||
pull_request:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
# Prevent running twice for PRs from same repo
|
|
||||||
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
|
|
||||||
name: Build & Test
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
|
||||||
generator: ["Ninja", "Unix Makefiles"]
|
|
||||||
mbedtls: ["mbedtls", ""]
|
|
||||||
libusb: ["libusb", ""]
|
|
||||||
compile: ["compile", ""]
|
|
||||||
exclude:
|
|
||||||
- os: 'windows-latest'
|
|
||||||
generator: "Unix Makefiles"
|
|
||||||
- libusb: ""
|
|
||||||
compile: "compile"
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Install dependencies (Windows)
|
|
||||||
if: runner.os == 'Windows'
|
|
||||||
run: |
|
|
||||||
choco install -y .github/workflows/choco_packages.config
|
|
||||||
curl -L https://github.com/libusb/libusb/releases/download/v1.0.27/libusb-1.0.27.7z -o libusb.7z
|
|
||||||
7z x libusb.7z -olibusb
|
|
||||||
- name: Set LIBUSB_ROOT (Windows)
|
|
||||||
if: runner.os == 'Windows'
|
|
||||||
shell: bash
|
|
||||||
run: echo "LIBUSB_ROOT=$(pwd)/libusb" >> "$GITHUB_ENV"
|
|
||||||
|
|
||||||
- name: Install dependencies (macOS)
|
|
||||||
if: runner.os == 'macOS'
|
|
||||||
run: |
|
|
||||||
brew install libusb ninja
|
|
||||||
brew install --cask gcc-arm-embedded
|
|
||||||
|
|
||||||
- name: Install dependencies (Linux)
|
|
||||||
if: runner.os == 'Linux'
|
|
||||||
run: sudo apt install cmake ninja-build python3 build-essential gcc-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib libusb-1.0-0-dev
|
|
||||||
- name: Checkout Pico SDK
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
repository: raspberrypi/pico-sdk
|
|
||||||
ref: develop
|
|
||||||
path: pico-sdk
|
|
||||||
submodules: ${{ !(!matrix.mbedtls) }}
|
|
||||||
|
|
||||||
- name: Build and Install
|
|
||||||
run: |
|
|
||||||
cmake -S . -B build -G "${{ matrix.generator }}" -D PICO_SDK_PATH="${{ github.workspace }}/pico-sdk" ${{ !matrix.libusb && '-D PICOTOOL_NO_LIBUSB=1' || '' }} ${{ matrix.compile && '-D USE_PRECOMPILED=false' || '' }}
|
|
||||||
cmake --build build
|
|
||||||
${{ runner.os != 'Windows' && 'sudo' || '' }} cmake --install build
|
|
||||||
- name: Add to path (Windows)
|
|
||||||
if: runner.os == 'Windows'
|
|
||||||
run: echo "C:\Program Files (x86)\picotool\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
|
||||||
|
|
||||||
- name: Test
|
|
||||||
run: |
|
|
||||||
picotool help
|
|
||||||
curl -L https://datasheets.raspberrypi.com/soft/blink.uf2 -o blink.uf2
|
|
||||||
curl -L https://datasheets.raspberrypi.com/soft/hello_world.uf2 -o hello_world.uf2
|
|
||||||
curl -L https://datasheets.raspberrypi.com/soft/flash_nuke.uf2 -o flash_nuke.uf2
|
|
||||||
picotool info -a blink.uf2
|
|
||||||
picotool info -a hello_world.uf2
|
|
||||||
picotool info -a flash_nuke.uf2
|
|
31
BUILD.bazel
31
BUILD.bazel
|
@ -2,8 +2,6 @@ load("//bazel:defs.bzl", "otp_header_parse", "picotool_binary_data_header")
|
||||||
|
|
||||||
package(default_visibility = ["//visibility:public"])
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
PICOTOOL_SDK_VERSION_STRING = module_version() if module_version() != None else "0.0.1-WORKSPACE"
|
|
||||||
|
|
||||||
picotool_binary_data_header(
|
picotool_binary_data_header(
|
||||||
name = "rp2350_rom",
|
name = "rp2350_rom",
|
||||||
src = "bootrom.end.bin",
|
src = "bootrom.end.bin",
|
||||||
|
@ -17,13 +15,6 @@ picotool_binary_data_header(
|
||||||
out = "xip_ram_perms_elf.h",
|
out = "xip_ram_perms_elf.h",
|
||||||
)
|
)
|
||||||
|
|
||||||
# TODO: Make it possible to build the prebuilt from source.
|
|
||||||
picotool_binary_data_header(
|
|
||||||
name = "flash_id_bin",
|
|
||||||
src = "//picoboot_flash_id:picoboot_flash_id_prebuilt",
|
|
||||||
out = "flash_id_bin.h",
|
|
||||||
)
|
|
||||||
|
|
||||||
cc_library(
|
cc_library(
|
||||||
name = "xip_ram_perms",
|
name = "xip_ram_perms",
|
||||||
srcs = ["xip_ram_perms.cpp"],
|
srcs = ["xip_ram_perms.cpp"],
|
||||||
|
@ -46,10 +37,6 @@ otp_header_parse(
|
||||||
name = "otp_header",
|
name = "otp_header",
|
||||||
src = "@pico-sdk//src/rp2350/hardware_regs:otp_data_header",
|
src = "@pico-sdk//src/rp2350/hardware_regs:otp_data_header",
|
||||||
out = "rp2350.json.h",
|
out = "rp2350.json.h",
|
||||||
target_compatible_with = select({
|
|
||||||
"@rules_cc//cc/compiler:msvc-cl": ["@platforms//:incompatible"],
|
|
||||||
"//conditions:default": [],
|
|
||||||
}),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
cc_binary(
|
cc_binary(
|
||||||
|
@ -60,14 +47,10 @@ cc_binary(
|
||||||
"main.cpp",
|
"main.cpp",
|
||||||
"otp.cpp",
|
"otp.cpp",
|
||||||
"otp.h",
|
"otp.h",
|
||||||
|
"rp2350.json.h",
|
||||||
"rp2350.rom.h",
|
"rp2350.rom.h",
|
||||||
"xip_ram_perms.cpp",
|
"xip_ram_perms.cpp",
|
||||||
] + select({
|
],
|
||||||
# MSVC can't handle long strings, so use this manually generated
|
|
||||||
# header instead.
|
|
||||||
"@rules_cc//cc/compiler:msvc-cl": [],
|
|
||||||
"//conditions:default": ["rp2350.json.h"],
|
|
||||||
}),
|
|
||||||
copts = select({
|
copts = select({
|
||||||
"@rules_cc//cc/compiler:msvc-cl": [
|
"@rules_cc//cc/compiler:msvc-cl": [
|
||||||
"/std:c++20",
|
"/std:c++20",
|
||||||
|
@ -81,7 +64,8 @@ cc_binary(
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
defines = [
|
defines = [
|
||||||
'PICOTOOL_VERSION=\\"{}\\"'.format(PICOTOOL_SDK_VERSION_STRING),
|
# TODO: There's probably a nicer way to share the version with CMake.
|
||||||
|
'PICOTOOL_VERSION=\\"2.0.0\\"',
|
||||||
'SYSTEM_VERSION=\\"host\\"',
|
'SYSTEM_VERSION=\\"host\\"',
|
||||||
'COMPILER_INFO=\\"local\\"',
|
'COMPILER_INFO=\\"local\\"',
|
||||||
"SUPPORT_A0=0",
|
"SUPPORT_A0=0",
|
||||||
|
@ -114,10 +98,5 @@ cc_binary(
|
||||||
"@pico-sdk//src/rp2350/hardware_regs:otp_data",
|
"@pico-sdk//src/rp2350/hardware_regs:otp_data",
|
||||||
"@pico-sdk//src/rp2_common/pico_bootrom:pico_bootrom_headers",
|
"@pico-sdk//src/rp2_common/pico_bootrom:pico_bootrom_headers",
|
||||||
"@pico-sdk//src/rp2_common/pico_stdio_usb:reset_interface_headers",
|
"@pico-sdk//src/rp2_common/pico_stdio_usb:reset_interface_headers",
|
||||||
] + select({
|
],
|
||||||
# MSVC can't handle long strings, so use this manually generated
|
|
||||||
# header instead.
|
|
||||||
"@rules_cc//cc/compiler:msvc-cl": ["//otp_header_parser:pre_generated_otp_header"],
|
|
||||||
"//conditions:default": [],
|
|
||||||
}),
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -35,7 +35,7 @@ if (PICOTOOL_FLAT_INSTALL)
|
||||||
set(INSTALL_DATADIR picotool)
|
set(INSTALL_DATADIR picotool)
|
||||||
set(INSTALL_BINDIR picotool)
|
set(INSTALL_BINDIR picotool)
|
||||||
else()
|
else()
|
||||||
set(INSTALL_CONFIGDIR lib/cmake/picotool)
|
set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/picotool)
|
||||||
set(INSTALL_DATADIR ${CMAKE_INSTALL_DATADIR}/picotool)
|
set(INSTALL_DATADIR ${CMAKE_INSTALL_DATADIR}/picotool)
|
||||||
set(INSTALL_BINDIR ${CMAKE_INSTALL_BINDIR})
|
set(INSTALL_BINDIR ${CMAKE_INSTALL_BINDIR})
|
||||||
endif()
|
endif()
|
||||||
|
@ -70,7 +70,6 @@ if (NOT PICOTOOL_NO_LIBUSB)
|
||||||
"-DCMAKE_MAKE_PROGRAM:FILEPATH=${CMAKE_MAKE_PROGRAM}"
|
"-DCMAKE_MAKE_PROGRAM:FILEPATH=${CMAKE_MAKE_PROGRAM}"
|
||||||
"-DPICO_SDK_PATH:FILEPATH=${PICO_SDK_PATH}"
|
"-DPICO_SDK_PATH:FILEPATH=${PICO_SDK_PATH}"
|
||||||
"-DUSE_PRECOMPILED:BOOL=${USE_PRECOMPILED}"
|
"-DUSE_PRECOMPILED:BOOL=${USE_PRECOMPILED}"
|
||||||
"-DPICO_DEBUG_INFO_IN_RELEASE=OFF"
|
|
||||||
BUILD_ALWAYS 1 # todo remove this
|
BUILD_ALWAYS 1 # todo remove this
|
||||||
INSTALL_COMMAND ""
|
INSTALL_COMMAND ""
|
||||||
)
|
)
|
||||||
|
@ -85,30 +84,6 @@ if (NOT PICOTOOL_NO_LIBUSB)
|
||||||
DEPENDS xip_ram_perms
|
DEPENDS xip_ram_perms
|
||||||
)
|
)
|
||||||
|
|
||||||
# compile flash_id
|
|
||||||
ExternalProject_Add(flash_id
|
|
||||||
PREFIX picoboot_flash_id
|
|
||||||
SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/picoboot_flash_id
|
|
||||||
BINARY_DIR ${CMAKE_BINARY_DIR}/picoboot_flash_id
|
|
||||||
CMAKE_ARGS
|
|
||||||
"-DCMAKE_MAKE_PROGRAM:FILEPATH=${CMAKE_MAKE_PROGRAM}"
|
|
||||||
"-DPICO_SDK_PATH:FILEPATH=${PICO_SDK_PATH}"
|
|
||||||
"-DUSE_PRECOMPILED:BOOL=${USE_PRECOMPILED}"
|
|
||||||
"-DPICO_DEBUG_INFO_IN_RELEASE=OFF"
|
|
||||||
BUILD_ALWAYS 1 # todo remove this
|
|
||||||
INSTALL_COMMAND ""
|
|
||||||
)
|
|
||||||
|
|
||||||
set(FLASH_ID_BIN ${CMAKE_BINARY_DIR}/picoboot_flash_id/flash_id.bin)
|
|
||||||
add_executable(flash_id_bin IMPORTED)
|
|
||||||
add_dependencies(flash_id_bin flash_id)
|
|
||||||
set_property(TARGET flash_id_bin PROPERTY IMPORTED_LOCATION ${FLASH_ID_BIN})
|
|
||||||
# copy flash_id.bin into build directory
|
|
||||||
add_custom_command(TARGET flash_id
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy ${FLASH_ID_BIN} ${CMAKE_BINARY_DIR}/flash_id.bin
|
|
||||||
DEPENDS flash_id
|
|
||||||
)
|
|
||||||
|
|
||||||
# We want to generate headers from WELCOME.HTM etc.
|
# We want to generate headers from WELCOME.HTM etc.
|
||||||
ExternalProject_Add(otp_header_parser
|
ExternalProject_Add(otp_header_parser
|
||||||
PREFIX otp_header_parser
|
PREFIX otp_header_parser
|
||||||
|
@ -169,10 +144,7 @@ if (NOT PICOTOOL_NO_LIBUSB)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_custom_target(binary_data DEPENDS
|
add_custom_target(binary_data DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/rp2350.rom.h ${CMAKE_CURRENT_BINARY_DIR}/xip_ram_perms_elf.h)
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/rp2350.rom.h
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/xip_ram_perms_elf.h
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/flash_id_bin.h)
|
|
||||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/rp2350.rom.h
|
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/rp2350.rom.h
|
||||||
COMMAND ${CMAKE_COMMAND}
|
COMMAND ${CMAKE_COMMAND}
|
||||||
-D BINARY_FILE=${CMAKE_CURRENT_LIST_DIR}/bootrom.end.bin
|
-D BINARY_FILE=${CMAKE_CURRENT_LIST_DIR}/bootrom.end.bin
|
||||||
|
@ -188,14 +160,6 @@ add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/xip_ram_perms_elf.h
|
||||||
DEPENDS xip_ram_perms
|
DEPENDS xip_ram_perms
|
||||||
COMMENT "Configuring xip_ram_perms_elf.h"
|
COMMENT "Configuring xip_ram_perms_elf.h"
|
||||||
VERBATIM)
|
VERBATIM)
|
||||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/flash_id_bin.h
|
|
||||||
COMMAND ${CMAKE_COMMAND}
|
|
||||||
-D BINARY_FILE=${FLASH_ID_BIN}
|
|
||||||
-D OUTPUT_NAME=flash_id_bin
|
|
||||||
-P ${CMAKE_CURRENT_LIST_DIR}/cmake/binh.cmake
|
|
||||||
DEPENDS flash_id
|
|
||||||
COMMENT "Configuring flash_id_bin.h"
|
|
||||||
VERBATIM)
|
|
||||||
|
|
||||||
add_subdirectory(errors)
|
add_subdirectory(errors)
|
||||||
|
|
||||||
|
@ -224,9 +188,10 @@ add_subdirectory(${PICO_SDK_PATH}/src/common/boot_uf2_headers boot_uf2_headers)
|
||||||
add_subdirectory(${PICO_SDK_PATH}/src/common/boot_picoboot_headers boot_picoboot_headers)
|
add_subdirectory(${PICO_SDK_PATH}/src/common/boot_picoboot_headers boot_picoboot_headers)
|
||||||
add_subdirectory(${PICO_SDK_PATH}/src/common/boot_picobin_headers boot_picobin_headers)
|
add_subdirectory(${PICO_SDK_PATH}/src/common/boot_picobin_headers boot_picobin_headers)
|
||||||
add_subdirectory(${PICO_SDK_PATH}/src/common/pico_usb_reset_interface_headers pico_usb_reset_interface_headers)
|
add_subdirectory(${PICO_SDK_PATH}/src/common/pico_usb_reset_interface_headers pico_usb_reset_interface_headers)
|
||||||
add_subdirectory(${PICO_SDK_PATH}/src/rp2_common/boot_bootrom_headers boot_bootrom_headers)
|
|
||||||
add_subdirectory(${PICO_SDK_PATH}/src/host/pico_platform pico_platform)
|
add_subdirectory(${PICO_SDK_PATH}/src/host/pico_platform pico_platform)
|
||||||
|
|
||||||
|
add_library(pico_bootrom_headers INTERFACE)
|
||||||
|
target_include_directories(pico_bootrom_headers INTERFACE ${PICO_SDK_PATH}/src/rp2_common/pico_bootrom/include)
|
||||||
add_library(regs_headers INTERFACE)
|
add_library(regs_headers INTERFACE)
|
||||||
target_include_directories(regs_headers INTERFACE ${PICO_SDK_PATH}/src/rp2350/hardware_regs/include)
|
target_include_directories(regs_headers INTERFACE ${PICO_SDK_PATH}/src/rp2350/hardware_regs/include)
|
||||||
|
|
||||||
|
@ -239,8 +204,8 @@ if (NOT PICOTOOL_NO_LIBUSB)
|
||||||
target_sources(picotool PRIVATE xip_ram_perms.cpp)
|
target_sources(picotool PRIVATE xip_ram_perms.cpp)
|
||||||
add_dependencies(picotool generate_otp_header xip_ram_perms_elf binary_data)
|
add_dependencies(picotool generate_otp_header xip_ram_perms_elf binary_data)
|
||||||
endif()
|
endif()
|
||||||
set(PROJECT_VERSION 2.1.0)
|
set(PROJECT_VERSION 2.0.0)
|
||||||
set(PICOTOOL_VERSION 2.1.0)
|
set(PICOTOOL_VERSION 2.0.0)
|
||||||
set(SYSTEM_VERSION "${CMAKE_SYSTEM_NAME}")
|
set(SYSTEM_VERSION "${CMAKE_SYSTEM_NAME}")
|
||||||
set(COMPILER_INFO "${CMAKE_C_COMPILER_ID}-${CMAKE_C_COMPILER_VERSION}, ${CMAKE_BUILD_TYPE}")
|
set(COMPILER_INFO "${CMAKE_C_COMPILER_ID}-${CMAKE_C_COMPILER_VERSION}, ${CMAKE_BUILD_TYPE}")
|
||||||
target_compile_definitions(picotool PRIVATE
|
target_compile_definitions(picotool PRIVATE
|
||||||
|
@ -259,7 +224,7 @@ target_link_libraries(picotool
|
||||||
boot_uf2_headers
|
boot_uf2_headers
|
||||||
boot_picoboot_headers
|
boot_picoboot_headers
|
||||||
boot_picobin_headers
|
boot_picobin_headers
|
||||||
boot_bootrom_headers
|
pico_bootrom_headers
|
||||||
pico_platform_headers
|
pico_platform_headers
|
||||||
pico_usb_reset_interface_headers
|
pico_usb_reset_interface_headers
|
||||||
regs_headers
|
regs_headers
|
||||||
|
@ -277,11 +242,7 @@ else()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (NOT LIBUSB_FOUND)
|
if (NOT LIBUSB_FOUND)
|
||||||
if (PICOTOOL_NO_LIBUSB)
|
message("libUSB is not found - no USB support will be built")
|
||||||
message("PICOTOOL_NO_LIBUSB is set - no USB support will be built")
|
|
||||||
else()
|
|
||||||
message("libUSB is not found - no USB support will be built")
|
|
||||||
endif()
|
|
||||||
target_compile_definitions(picotool PRIVATE HAS_LIBUSB=0)
|
target_compile_definitions(picotool PRIVATE HAS_LIBUSB=0)
|
||||||
target_link_libraries(picotool
|
target_link_libraries(picotool
|
||||||
picoboot_connection_header)
|
picoboot_connection_header)
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
module(
|
module(
|
||||||
name = "picotool",
|
name = "picotool",
|
||||||
version = "2.1.0",
|
version = "2.0.0",
|
||||||
)
|
)
|
||||||
|
|
||||||
bazel_dep(name = "rules_libusb", version = "0.1.0-rc1")
|
bazel_dep(name = "rules_libusb", version = "0.1.0-rc1")
|
||||||
bazel_dep(name = "pico-sdk", version = "2.1.0")
|
bazel_dep(name = "pico-sdk", version = "2.0.0")
|
||||||
bazel_dep(name = "rules_cc", version = "0.0.9")
|
bazel_dep(name = "rules_cc", version = "0.0.9")
|
||||||
bazel_dep(name = "bazel_skylib", version = "1.6.1")
|
bazel_dep(name = "bazel_skylib", version = "1.6.1")
|
||||||
bazel_dep(name = "rules_python", version = "0.22.1")
|
bazel_dep(name = "rules_python", version = "0.22.1")
|
||||||
|
|
199
README.md
199
README.md
|
@ -16,8 +16,6 @@ Use your favorite package tool to install dependencies. For example, on Ubuntu:
|
||||||
sudo apt install build-essential pkg-config libusb-1.0-0-dev cmake
|
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:
|
Then simply build like a normal CMake project:
|
||||||
|
|
||||||
```console
|
```console
|
||||||
|
@ -68,33 +66,32 @@ No need to download libusb separately or set `LIBUSB_ROOT`.
|
||||||
pacman -S $MINGW_PACKAGE_PREFIX-{toolchain,cmake,libusb}
|
pacman -S $MINGW_PACKAGE_PREFIX-{toolchain,cmake,libusb}
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake .. -DCMAKE_INSTALL_PREFIX=$MINGW_PREFIX
|
MSYS2_ARG_CONV_EXCL=- cmake .. -G"MSYS Makefiles" -DCMAKE_INSTALL_PREFIX=$MINGW_PREFIX
|
||||||
cmake --build .
|
make
|
||||||
|
make install DESTDIR=/ # optional
|
||||||
```
|
```
|
||||||
|
|
||||||
## Usage by the Raspberry Pi Pico SDK
|
## 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.
|
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->UF2 conversion previously handled by the `elf2uf2` tool in the SDK. `picootol` is also used by the SDK for hashing and/or signing 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.
|
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.
|
||||||
|
|
||||||
> On some Linux systems, the `~/.local` prefix may be used for an install without `sudo`; from your build directory simply run
|
This can be done most simply with `make install`; the SDK will use this installed version by default.
|
||||||
> ```console
|
|
||||||
> cmake -DCMAKE_INSTALL_PREFIX=~/.local ..
|
|
||||||
> make install
|
|
||||||
> ```
|
|
||||||
> This will only work if `~/.local` is included in your `PATH`
|
|
||||||
|
|
||||||
Alternatively, you can install to a custom path via:
|
Alternatively you can install in a custom path via:
|
||||||
|
|
||||||
```console
|
```
|
||||||
cmake -DCMAKE_INSTALL_PREFIX=$MY_INSTALL_DIR -DPICOTOOL_FLAT_INSTALL=1 ..
|
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.
|
In order for the SDK to find `picotool` in this custom path, you will need to set the `picotool_DIR` variable in your project, either by passing to `-Dpicotool_DIR=$MY_INSTALL_DIR/picotool` to your SDK `cmake` command, or by adding
|
||||||
|
|
||||||
> See the [find_package documentation](https://cmake.org/cmake/help/latest/command/find_package.html#config-mode-search-procedure) for more details
|
```CMake
|
||||||
|
set(picotool_DIR $MY_INSTALL_DIR/picotool)
|
||||||
|
```
|
||||||
|
|
||||||
|
to your CMakeLists.txt file.
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
|
@ -105,23 +102,20 @@ Note for additional documentation see https://rptl.io/pico-get-started
|
||||||
```
|
```
|
||||||
$ picotool help
|
$ picotool help
|
||||||
PICOTOOL:
|
PICOTOOL:
|
||||||
Tool for interacting with RP-series device(s) in BOOTSEL mode, or with an RP-series binary
|
Tool for interacting with RP2040/RP2350 device(s) in BOOTSEL mode, or with an RP2040/RP2350 binary
|
||||||
|
|
||||||
SYNOPSIS:
|
SYNOPSIS:
|
||||||
picotool info [-b] [-m] [-p] [-d] [--debug] [-l] [-a] [device-selection]
|
picotool info [-b] [-p] [-d] [--debug] [-l] [-a] [device-selection]
|
||||||
picotool info [-b] [-m] [-p] [-d] [--debug] [-l] [-a] <filename> [-t <type>]
|
picotool info [-b] [-p] [-d] [--debug] [-l] [-a] <filename> [-t <type>]
|
||||||
picotool config [-s <key> <value>] [-g <group>] [device-selection]
|
picotool config [-s <key> <value>] [-g <group>] [device-selection]
|
||||||
picotool config [-s <key> <value>] [-g <group>] <filename> [-t <type>]
|
picotool config [-s <key> <value>] [-g <group>] <filename> [-t <type>]
|
||||||
picotool load [--ignore-partitions] [--family <family_id>] [-p <partition>] [-n] [-N] [-u] [-v] [-x] <filename> [-t <type>] [-o <offset>] [device-selection]
|
picotool load [-p] [-n] [-N] [-u] [-v] [-x] <filename> [-t <type>] [-o <offset>] [device-selection]
|
||||||
picotool encrypt [--quiet] [--verbose] [--hash] [--sign] <infile> [-t <type>] [-o <offset>] <outfile> [-t <type>] <aes_key> [-t <type>] [<signing_key>] [-t <type>]
|
picotool encrypt [--quiet] [--verbose] [--hash] [--sign] <infile> [-t <type>] [-o <offset>] <outfile> [-t <type>] <aes_key> [-t <type>] [<signing_key>] [-t <type>]
|
||||||
picotool seal [--quiet] [--verbose] [--hash] [--sign] [--clear] <infile> [-t <type>] [-o <offset>] <outfile> [-t <type>] [<key>] [-t <type>] [<otp>] [-t <type>] [--major <major>] [--minor <minor>] [--rollback <rollback> [<rows>..]]
|
picotool seal [--quiet] [--verbose] [--hash] [--sign] [--clear] <infile> [-t <type>] [-o <offset>] <outfile> [-t <type>] [<key>] [-t <type>] [<otp>] [-t <type>] [--major <major>] [--minor <minor>] [--rollback <rollback> [<rows>..]]
|
||||||
picotool link [--quiet] [--verbose] <outfile> [-t <type>] <infile1> [-t <type>] <infile2> [-t <type>] [<infile3>] [-t <type>] [-p] <pad>
|
picotool link [--quiet] [--verbose] <outfile> [-t <type>] <infile1> [-t <type>] <infile2> [-t <type>] [<infile3>] [-t <type>] [-p] <pad>
|
||||||
picotool save [-p] [-v] [--family <family_id>] [device-selection]
|
picotool save [-p] [device-selection]
|
||||||
picotool save -a [-v] [--family <family_id>] [device-selection]
|
picotool save -a [device-selection]
|
||||||
picotool save -r <from> <to> [-v] [--family <family_id>] [device-selection]
|
picotool save -r <from> <to> [device-selection]
|
||||||
picotool erase [-a] [device-selection]
|
|
||||||
picotool erase -p <partition> [device-selection]
|
|
||||||
picotool erase -r <from> <to> [device-selection]
|
|
||||||
picotool verify [device-selection]
|
picotool verify [device-selection]
|
||||||
picotool reboot [-a] [-u] [-g <partition>] [-c <cpu>] [device-selection]
|
picotool reboot [-a] [-u] [-g <partition>] [-c <cpu>] [device-selection]
|
||||||
picotool otp list|get|set|load|dump|permissions|white-label
|
picotool otp list|get|set|load|dump|permissions|white-label
|
||||||
|
@ -133,21 +127,20 @@ SYNOPSIS:
|
||||||
|
|
||||||
COMMANDS:
|
COMMANDS:
|
||||||
info Display information from the target device(s) or file.
|
info Display information from the target device(s) or file.
|
||||||
Without any arguments, this will display basic information for all connected RP-series devices in BOOTSEL mode
|
Without any arguments, this will display basic information for all connected RP2040 devices in BOOTSEL mode
|
||||||
config Display or change program configuration settings from the target device(s) or file.
|
config Display or change program configuration settings from the target device(s) or file.
|
||||||
load Load the program / memory range stored in a file onto the device.
|
load Load the program / memory range stored in a file onto the device.
|
||||||
encrypt Encrypt the program.
|
encrypt Encrypt the program.
|
||||||
seal Add final metadata to a binary, optionally including a hash and/or signature.
|
seal Add final metadata to a binary, optionally including a hash and/or signature.
|
||||||
link Link multiple binaries into one block loop.
|
link Link multiple binaries into one block loop.
|
||||||
save Save the program / memory stored in flash on the device to a file.
|
save Save the program / memory stored in flash on the device to a file.
|
||||||
erase Erase the program / memory stored in flash on the device.
|
|
||||||
verify Check that the device contents match those in the file.
|
verify Check that the device contents match those in the file.
|
||||||
reboot Reboot the device
|
reboot Reboot the device
|
||||||
otp Commands related to the RP2350 OTP (One-Time-Programmable) Memory
|
otp Commands related to the RP2350 OTP (One-Time-Programmable) Memory
|
||||||
partition Commands related to RP2350 Partition Tables
|
partition Commands related to RP2350 Partition Tables
|
||||||
uf2 Commands related to UF2 creation and status
|
uf2 Commands related to UF2 creation and status
|
||||||
version Display picotool version
|
version Display picotool version
|
||||||
coprodis Post-process coprocessor instructions in disassembly files.
|
coprodis Post-process coprocessor instructions in dissassembly files.
|
||||||
help Show general help or help for a specific command
|
help Show general help or help for a specific command
|
||||||
|
|
||||||
Use "picotool help <cmd>" for more info
|
Use "picotool help <cmd>" for more info
|
||||||
|
@ -167,18 +160,16 @@ a file. This file can be an ELF, a UF2 or a BIN file.
|
||||||
$ picotool help info
|
$ picotool help info
|
||||||
INFO:
|
INFO:
|
||||||
Display information from the target device(s) or file.
|
Display information from the target device(s) or file.
|
||||||
Without any arguments, this will display basic information for all connected RP-series devices in BOOTSEL mode
|
Without any arguments, this will display basic information for all connected RP2040 devices in BOOTSEL mode
|
||||||
|
|
||||||
SYNOPSIS:
|
SYNOPSIS:
|
||||||
picotool info [-b] [-m] [-p] [-d] [--debug] [-l] [-a] [device-selection]
|
picotool info [-b] [-p] [-d] [--debug] [-l] [-a] [device-selection]
|
||||||
picotool info [-b] [-m] [-p] [-d] [--debug] [-l] [-a] <filename> [-t <type>]
|
picotool info [-b] [-p] [-d] [--debug] [-l] [-a] <filename> [-t <type>]
|
||||||
|
|
||||||
OPTIONS:
|
OPTIONS:
|
||||||
Information to display
|
Information to display
|
||||||
-b, --basic
|
-b, --basic
|
||||||
Include basic information. This is the default
|
Include basic information. This is the default
|
||||||
-m, --metadata
|
|
||||||
Include all metadata blocks
|
|
||||||
-p, --pins
|
-p, --pins
|
||||||
Include pin information
|
Include pin information
|
||||||
-d, --device
|
-d, --device
|
||||||
|
@ -191,7 +182,7 @@ OPTIONS:
|
||||||
Include all information
|
Include all information
|
||||||
|
|
||||||
TARGET SELECTION:
|
TARGET SELECTION:
|
||||||
To target one or more connected RP-series device(s) in BOOTSEL mode (the default)
|
To target one or more connected RP2040 device(s) in BOOTSEL mode (the default)
|
||||||
--bus <bus>
|
--bus <bus>
|
||||||
Filter devices by USB bus number
|
Filter devices by USB bus number
|
||||||
--address <addr>
|
--address <addr>
|
||||||
|
@ -299,7 +290,7 @@ OPTIONS:
|
||||||
Filter by feature group
|
Filter by feature group
|
||||||
|
|
||||||
TARGET SELECTION:
|
TARGET SELECTION:
|
||||||
To target one or more connected RP-series device(s) in BOOTSEL mode (the default)
|
To target one or more connected RP2040 device(s) in BOOTSEL mode (the default)
|
||||||
--bus <bus>
|
--bus <bus>
|
||||||
Filter devices by USB bus number
|
Filter devices by USB bus number
|
||||||
--address <addr>
|
--address <addr>
|
||||||
|
@ -373,7 +364,7 @@ OPTIONS:
|
||||||
--family
|
--family
|
||||||
Specify the family ID of the file to load
|
Specify the family ID of the file to load
|
||||||
<family_id>
|
<family_id>
|
||||||
family ID to use for load
|
family id to use for load
|
||||||
-p, --partition
|
-p, --partition
|
||||||
Specify the partition to load into
|
Specify the partition to load into
|
||||||
<partition>
|
<partition>
|
||||||
|
@ -437,9 +428,9 @@ SAVE:
|
||||||
Save the program / memory stored in flash on the device to a file.
|
Save the program / memory stored in flash on the device to a file.
|
||||||
|
|
||||||
SYNOPSIS:
|
SYNOPSIS:
|
||||||
picotool save [-p] [-v] [--family <family_id>] [device-selection]
|
picotool save [-p] [device-selection]
|
||||||
picotool save -a [-v] [--family <family_id>] [device-selection]
|
picotool save -a [device-selection]
|
||||||
picotool save -r <from> <to> [-v] [--family <family_id>] [device-selection]
|
picotool save -r <from> <to> [device-selection]
|
||||||
|
|
||||||
OPTIONS:
|
OPTIONS:
|
||||||
Selection of data to save
|
Selection of data to save
|
||||||
|
@ -454,13 +445,6 @@ OPTIONS:
|
||||||
The lower address bound in hex
|
The lower address bound in hex
|
||||||
<to>
|
<to>
|
||||||
The upper address bound in hex
|
The upper address bound in hex
|
||||||
Other
|
|
||||||
-v, --verify
|
|
||||||
Verify the data was saved correctly
|
|
||||||
--family
|
|
||||||
Specify the family ID to save the file as
|
|
||||||
<family_id>
|
|
||||||
family id to save file as
|
|
||||||
Source device selection
|
Source device selection
|
||||||
--bus <bus>
|
--bus <bus>
|
||||||
Filter devices by USB bus number
|
Filter devices by USB bus number
|
||||||
|
@ -511,95 +495,6 @@ name: lcd_1602_i2c
|
||||||
web site: https://github.com/raspberrypi/pico-examples/tree/HEAD/i2c/lcd_1602_i2c
|
web site: https://github.com/raspberrypi/pico-examples/tree/HEAD/i2c/lcd_1602_i2c
|
||||||
```
|
```
|
||||||
|
|
||||||
## erase
|
|
||||||
|
|
||||||
`erase` allows you to erase all of flash, a partition of flash, or an explicit range of flash on the device.
|
|
||||||
It defaults to erasing all of flash.
|
|
||||||
|
|
||||||
```text
|
|
||||||
$ picotool help erase
|
|
||||||
ERASE:
|
|
||||||
Erase the program / memory stored in flash on the device.
|
|
||||||
|
|
||||||
SYNOPSIS:
|
|
||||||
picotool erase [-a] [device-selection]
|
|
||||||
picotool erase [-p <partition>] [device-selection]
|
|
||||||
picotool erase -r <from> <to> [device-selection]
|
|
||||||
|
|
||||||
OPTIONS:
|
|
||||||
Selection of data to erase
|
|
||||||
-a, --all
|
|
||||||
Erase all of flash memory. This is the default
|
|
||||||
-p, --partition
|
|
||||||
Erase a partition
|
|
||||||
<partition>
|
|
||||||
Partition number to erase
|
|
||||||
-r, --range
|
|
||||||
Erase a range of memory. Note that erases must be 4096 byte-aligned, so the range is expanded accordingly
|
|
||||||
<from>
|
|
||||||
The lower address bound in hex
|
|
||||||
<to>
|
|
||||||
The upper address bound in hex
|
|
||||||
Source device selection
|
|
||||||
--bus <bus>
|
|
||||||
Filter devices by USB bus number
|
|
||||||
--address <addr>
|
|
||||||
Filter devices by USB device address
|
|
||||||
--vid <vid>
|
|
||||||
Filter by vendor id
|
|
||||||
--pid <pid>
|
|
||||||
Filter by product id
|
|
||||||
--ser <ser>
|
|
||||||
Filter by serial number
|
|
||||||
-f, --force
|
|
||||||
Force a device not in BOOTSEL mode but running compatible code to reset so the command can be executed. After executing the
|
|
||||||
command (unless the command itself is a 'reboot') the device will be rebooted back to application mode
|
|
||||||
-F, --force-no-reboot
|
|
||||||
Force a device not in BOOTSEL mode but running compatible code to reset so the command can be executed. After executing the
|
|
||||||
command (unless the command itself is a 'reboot') the device will be left connected and accessible to picotool, but without the
|
|
||||||
RPI-RP2 drive mounted
|
|
||||||
```
|
|
||||||
|
|
||||||
e.g. first looking at what is on the device...
|
|
||||||
|
|
||||||
```text
|
|
||||||
$ picotool info
|
|
||||||
Partition 0
|
|
||||||
Program Information
|
|
||||||
none
|
|
||||||
|
|
||||||
Partition 1
|
|
||||||
Program Information
|
|
||||||
name: blink
|
|
||||||
web site: https://github.com/raspberrypi/pico-examples/tree/HEAD/blink
|
|
||||||
features: UART stdin / stdout
|
|
||||||
binary start: 0x10000000
|
|
||||||
binary end: 0x1000a934
|
|
||||||
target chip: RP2350
|
|
||||||
image type: ARM Secure
|
|
||||||
```
|
|
||||||
|
|
||||||
... then erase partition 1 ...
|
|
||||||
```text
|
|
||||||
$ picotool erase -p 1
|
|
||||||
Erasing partition 1:
|
|
||||||
0007f000->000fc000
|
|
||||||
Erasing: [==============================] 100%
|
|
||||||
Erased 512000 bytes
|
|
||||||
```
|
|
||||||
|
|
||||||
... and looking at the device again:
|
|
||||||
```text
|
|
||||||
$ picotool info
|
|
||||||
Partition 0
|
|
||||||
Program Information
|
|
||||||
none
|
|
||||||
|
|
||||||
Partition 1
|
|
||||||
Program Information
|
|
||||||
none
|
|
||||||
```
|
|
||||||
|
|
||||||
## seal
|
## seal
|
||||||
|
|
||||||
`seal` allows you to sign and/or hash a binary to run on RP2350.
|
`seal` allows you to sign and/or hash a binary to run on RP2350.
|
||||||
|
@ -758,14 +653,14 @@ un-partitioned_space : S(rw) NSBOOT(rw) NS(rw), uf2 { absolute }
|
||||||
partitions:
|
partitions:
|
||||||
0(A) 00002000->00201000 S(rw) NSBOOT(rw) NS(rw), id=0000000000000000, "A", uf2 { rp2350-arm-s, rp2350-riscv }, arm_boot 1, riscv_boot 1
|
0(A) 00002000->00201000 S(rw) NSBOOT(rw) NS(rw), id=0000000000000000, "A", uf2 { rp2350-arm-s, rp2350-riscv }, arm_boot 1, riscv_boot 1
|
||||||
1(B w/ 0) 00201000->00400000 S(rw) NSBOOT(rw) NS(rw), id=0000000000000001, "B", uf2 { rp2350-arm-s, rp2350-riscv }, arm_boot 1, riscv_boot 1
|
1(B w/ 0) 00201000->00400000 S(rw) NSBOOT(rw) NS(rw), id=0000000000000001, "B", uf2 { rp2350-arm-s, rp2350-riscv }, arm_boot 1, riscv_boot 1
|
||||||
Family ID 'rp2350-arm-s' can be downloaded in partition 0:
|
Family id 'rp2350-arm-s' can be downloaded in partition 0:
|
||||||
00002000->00201000
|
00002000->00201000
|
||||||
```
|
```
|
||||||
|
|
||||||
### create
|
### create
|
||||||
|
|
||||||
This command allows you to create partition tables, and additionally embed them into the block loop if ELF files (for example, for bootloaders).
|
This command allows you to create partition tables, and additionally embed them into the block loop if ELF files (for example, for bootloaders).
|
||||||
By default, all partition tables are hashed, and you can also sign them. The schema for this JSON file is [here](json/schemas/partition-table-schema.json).
|
By default, all partition tables are hashed, and you can also sign them.
|
||||||
|
|
||||||
```text
|
```text
|
||||||
$ picotool help partition create
|
$ picotool help partition create
|
||||||
|
@ -799,7 +694,7 @@ OPTIONS:
|
||||||
--family
|
--family
|
||||||
Specify the family if for UF2 file output
|
Specify the family if for UF2 file output
|
||||||
<family_id>
|
<family_id>
|
||||||
family ID for UF2 (default absolute)
|
family id for UF2 (default absolute)
|
||||||
embed partition table into bootloader ELF
|
embed partition table into bootloader ELF
|
||||||
<bootloader>
|
<bootloader>
|
||||||
The file name
|
The file name
|
||||||
|
@ -814,7 +709,7 @@ OPTIONS:
|
||||||
Don't hash the partition table
|
Don't hash the partition table
|
||||||
--singleton
|
--singleton
|
||||||
Singleton partition table
|
Singleton partition table
|
||||||
Errata RP2350-E10 Fix
|
Errata RP2350-E9 Fix
|
||||||
--abs-block
|
--abs-block
|
||||||
Enforce support for an absolute block
|
Enforce support for an absolute block
|
||||||
<abs_block_loc>
|
<abs_block_loc>
|
||||||
|
@ -823,7 +718,7 @@ OPTIONS:
|
||||||
|
|
||||||
## uf2
|
## uf2
|
||||||
|
|
||||||
The `uf2` commands allow for creation of UF2s, and can provide information if a UF2 download has failed.
|
The `uf2` commands allow for creation of UF2s, and cam provide information when if a UF2 download has failed.
|
||||||
|
|
||||||
### convert
|
### convert
|
||||||
|
|
||||||
|
@ -860,8 +755,8 @@ OPTIONS:
|
||||||
Load offset (memory address; default 0x10000000 for BIN file)
|
Load offset (memory address; default 0x10000000 for BIN file)
|
||||||
UF2 Family options
|
UF2 Family options
|
||||||
<family_id>
|
<family_id>
|
||||||
family ID for UF2
|
family id for UF2
|
||||||
Errata RP2350-E10 Fix
|
Errata RP2350-E9 Fix
|
||||||
--abs-block
|
--abs-block
|
||||||
Add an absolute block
|
Add an absolute block
|
||||||
<abs_block_loc>
|
<abs_block_loc>
|
||||||
|
@ -909,7 +804,7 @@ The `otp` commands are for interacting with the RP2350 OTP Memory. They are not
|
||||||
Note that the OTP Memory is One-Time-Programmable, which means that once a bit has been changed from 0 to 1, it cannot be changed back.
|
Note that the OTP Memory is One-Time-Programmable, which means that once a bit has been changed from 0 to 1, it cannot be changed back.
|
||||||
Therefore, caution should be used when using these commands, as they risk bricking your RP2350 device. For example, if you set SECURE_BOOT_ENABLE but don't set a boot key, and disable the PICOBOOT interface, then your device will be unusable.
|
Therefore, caution should be used when using these commands, as they risk bricking your RP2350 device. For example, if you set SECURE_BOOT_ENABLE but don't set a boot key, and disable the PICOBOOT interface, then your device will be unusable.
|
||||||
|
|
||||||
For the `list`, `set`, `get` and `load` commands, you can define your own OTP layout in a JSON file and pass that in with the `-i` argument. These rows will be added to the default rows when parsing. The schema for this JSON file is [here](json/schemas/otp-contents-schema.json)
|
For the `list`, `set`, `get` and `load` commands, you can define your own OTP layout in a JSON file and pass that in with the `-i` argument. These rows will be added to the default rows when parsing.
|
||||||
|
|
||||||
```text
|
```text
|
||||||
$ picotool help otp
|
$ picotool help otp
|
||||||
|
@ -917,9 +812,9 @@ OTP:
|
||||||
Commands related to the RP2350 OTP (One-Time-Programmable) Memory
|
Commands related to the RP2350 OTP (One-Time-Programmable) Memory
|
||||||
|
|
||||||
SYNOPSIS:
|
SYNOPSIS:
|
||||||
picotool otp list [-p] [-n] [-f] [-i <filename>] [<selector>..]
|
picotool otp list [-p] [-n] [-i <filename>] [<selector>..]
|
||||||
picotool otp get [-c <copies>] [-r] [-e] [-n] [-i <filename>] [device-selection] [-z] [<selector>..]
|
picotool otp get [-c <copies>] [-r] [-e] [-n] [-i <filename>] [device-selection] [-z] [<selector>..]
|
||||||
picotool otp set [-c <copies>] [-r] [-e] [-s] [-i <filename>] [-z] <selector> <value> [device-selection]
|
picotool otp set [-c <copies>] [-r] [-e] [-i <filename>] [-z] <selector> <value> [device-selection]
|
||||||
picotool otp load [-r] [-e] [-s <row>] [-i <filename>] <filename> [-t <type>] [device-selection]
|
picotool otp load [-r] [-e] [-s <row>] [-i <filename>] <filename> [-t <type>] [device-selection]
|
||||||
picotool otp dump [-r] [-e] [device-selection]
|
picotool otp dump [-r] [-e] [device-selection]
|
||||||
picotool otp permissions <filename> [-t <type>] [--led <pin>] [--hash] [--sign] [<key>] [-t <type>] [device-selection]
|
picotool otp permissions <filename> [-t <type>] [--led <pin>] [--hash] [--sign] [<key>] [-t <type>] [device-selection]
|
||||||
|
@ -942,7 +837,7 @@ These commands will set/get specific rows of OTP. By default, they will write/re
|
||||||
|
|
||||||
### load
|
### 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 sign`.
|
||||||
For example, if you wish to sign a binary and then test secure boot with it, you can run the following set of commands:
|
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
|
```text
|
||||||
$ picotool sign hello_world.elf hello_world.signed.elf private.pem otp.json
|
$ picotool sign hello_world.elf hello_world.signed.elf private.pem otp.json
|
||||||
|
@ -954,7 +849,7 @@ $ picotool reboot
|
||||||
### white-label
|
### white-label
|
||||||
|
|
||||||
This command allows for OTP white-labelling, which sets the USB configuration used by the device in BOOTSEL mode.
|
This command allows for OTP white-labelling, which sets the USB configuration used by the device in BOOTSEL mode.
|
||||||
This can be configured from a JSON file, an example of which is in [sample-wl.json](json/sample-wl.json). The schema for this JSON file is [here](json/schemas/whitelabel-schema.json)
|
This can be configured from a JSON file, an example of which is in [sample-wl.json](sample-wl.json).
|
||||||
|
|
||||||
```text
|
```text
|
||||||
$ picotool help otp white-label
|
$ picotool help otp white-label
|
||||||
|
@ -992,7 +887,7 @@ OPTIONS:
|
||||||
```
|
```
|
||||||
|
|
||||||
```text
|
```text
|
||||||
$ picotool otp white-label -s 0x100 sample-wl.json
|
$ picotool otp white-label -s 0x100 ../sample-wl.json
|
||||||
Setting attributes 20e0
|
Setting attributes 20e0
|
||||||
0x2e8b, 0x000e, 0x0215, 0x0c09, 0x1090, 0x200c, 0x2615, 0x20e0, 0x310b, 0x3706, 0x3a04, 0x3c04, 0x3e21, 0x4f15, 0x5a0a, 0x5f0a, 0x007a, 0x00df, 0x6c34, 0xd83c, 0xdf4c, 0x0020, 0x0054, 0x0065, 0x0073, 0x0074, 0x0027, 0x0073,
|
0x2e8b, 0x000e, 0x0215, 0x0c09, 0x1090, 0x200c, 0x2615, 0x20e0, 0x310b, 0x3706, 0x3a04, 0x3c04, 0x3e21, 0x4f15, 0x5a0a, 0x5f0a, 0x007a, 0x00df, 0x6c34, 0xd83c, 0xdf4c, 0x0020, 0x0054, 0x0065, 0x0073, 0x0074, 0x0027, 0x0073,
|
||||||
0x0020, 0x0050, 0x0069, 0x0073, 0x6554, 0x7473, 0x5220, 0x3250, 0x3533, 0x3f30, 0x6f6e, 0x6e74, 0x6365, 0x7365, 0x6173, 0x6972, 0x796c, 0x6e61, 0x6d75, 0x6562, 0x0072, 0x6554, 0x7473, 0x6950, 0x4220, 0x6f6f, 0x0074, 0x6554,
|
0x0020, 0x0050, 0x0069, 0x0073, 0x6554, 0x7473, 0x5220, 0x3250, 0x3533, 0x3f30, 0x6f6e, 0x6e74, 0x6365, 0x7365, 0x6173, 0x6972, 0x796c, 0x6e61, 0x6d75, 0x6562, 0x0072, 0x6554, 0x7473, 0x6950, 0x4220, 0x6f6f, 0x0074, 0x6554,
|
||||||
|
@ -1034,7 +929,7 @@ Device Descriptor:
|
||||||
This command will run a binary on your device in order to set the OTP permissions, as these are not directly accessible from `picotool` on due to the default permissions settings required to fix errata XXX on RP2350.
|
This command will run a binary on your device in order to set the OTP permissions, as these are not directly accessible from `picotool` on due to the default permissions settings required to fix errata XXX on RP2350.
|
||||||
Because it runs a binary, the binary needs to be sign it if secure boot is enabled. The binary will print what it is doing over uart, which
|
Because it runs a binary, the binary needs to be sign it if secure boot is enabled. The binary will print what it is doing over uart, which
|
||||||
can be configured using the UART Configuration arguments. You can define your OTP permissions in a json file, an example of which
|
can be configured using the UART Configuration arguments. You can define your OTP permissions in a json file, an example of which
|
||||||
is in [sample-permissions.json](json/sample-permissions.json). The schema for this JSON file is [here](json/schemas/permissions-schema.json)
|
is in [sample-permissions.json](sample-permissions.json).
|
||||||
|
|
||||||
```text
|
```text
|
||||||
$ picotool help otp permissions
|
$ picotool help otp permissions
|
||||||
|
@ -1083,7 +978,7 @@ OPTIONS:
|
||||||
```
|
```
|
||||||
|
|
||||||
```text
|
```text
|
||||||
$ picotool otp permissions --sign private.pem --tx 46 sample-permissions.json
|
$ picotool otp permissions --sign private.pem --tx 46 ../sample-permissions.json
|
||||||
Picking file ./xip_ram_perms.elf
|
Picking file ./xip_ram_perms.elf
|
||||||
page10
|
page10
|
||||||
page10 = 0
|
page10 = 0
|
||||||
|
|
|
@ -9,10 +9,10 @@ cc_library(
|
||||||
"library/*.h",
|
"library/*.h",
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
includes = ["include"],
|
|
||||||
linkopts = select({
|
linkopts = select({
|
||||||
"@rules_cc//cc/compiler:msvc-cl": ["-DEFAULTLIB:AdvAPI32.Lib"],
|
"@rules_cc//cc/compiler:msvc-cl": ["-DEFAULTLIB:AdvAPI32.Lib"],
|
||||||
"//conditions:default": [],
|
"//conditions:default": [],
|
||||||
}),
|
}),
|
||||||
|
includes = ["include"],
|
||||||
deps = ["@picotool//lib:mbedtls_config"],
|
deps = ["@picotool//lib:mbedtls_config"],
|
||||||
)
|
)
|
||||||
|
|
|
@ -12,7 +12,6 @@ cc_library(
|
||||||
"metadata.h",
|
"metadata.h",
|
||||||
],
|
],
|
||||||
copts = select({
|
copts = select({
|
||||||
"@rules_cc//cc/compiler:msvc-cl": ["/std:c++20"],
|
|
||||||
"@platforms//os:windows": [],
|
"@platforms//os:windows": [],
|
||||||
"//conditions:default": [
|
"//conditions:default": [
|
||||||
"-Wno-unused-variable",
|
"-Wno-unused-variable",
|
||||||
|
|
|
@ -453,120 +453,6 @@ block place_new_block(std::vector<uint8_t> &bin, uint32_t storage_addr, std::uni
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Checksum stuff
|
|
||||||
uint32_t poly8_lookup[256] =
|
|
||||||
{
|
|
||||||
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
|
|
||||||
0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
|
|
||||||
0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
|
|
||||||
0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
|
|
||||||
0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
|
|
||||||
0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
|
|
||||||
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
|
|
||||||
0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
|
|
||||||
0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
|
|
||||||
0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
|
|
||||||
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
|
|
||||||
0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
|
|
||||||
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
|
|
||||||
0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
|
|
||||||
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
|
|
||||||
0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
|
|
||||||
0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
|
|
||||||
0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
|
|
||||||
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
|
|
||||||
0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
|
|
||||||
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
|
|
||||||
0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
|
|
||||||
0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
|
|
||||||
0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
|
|
||||||
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
|
|
||||||
0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
|
|
||||||
0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
|
|
||||||
0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
|
|
||||||
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
|
|
||||||
0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
|
|
||||||
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
|
|
||||||
0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
|
|
||||||
0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
|
|
||||||
0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
|
|
||||||
0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
|
|
||||||
0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
|
|
||||||
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
|
|
||||||
0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
|
|
||||||
0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
|
|
||||||
0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
|
|
||||||
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
|
|
||||||
0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
|
|
||||||
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
|
|
||||||
0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
|
|
||||||
0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
|
|
||||||
0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
|
|
||||||
0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
|
|
||||||
0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
|
|
||||||
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
|
|
||||||
0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
|
|
||||||
0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
|
|
||||||
0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
|
|
||||||
0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
|
|
||||||
0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
|
|
||||||
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
|
|
||||||
0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
|
|
||||||
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
|
|
||||||
0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
|
|
||||||
0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
|
|
||||||
0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
|
|
||||||
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
|
|
||||||
0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
|
|
||||||
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
|
|
||||||
0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
|
|
||||||
};
|
|
||||||
|
|
||||||
uint32_t crc32_byte(const uint8_t *p, uint32_t bytelength)
|
|
||||||
{
|
|
||||||
uint32_t crc = 0xffffffff;
|
|
||||||
while (bytelength-- !=0) crc = poly8_lookup[((uint8_t) crc ^ *(p++))] ^ (crc >> 8);
|
|
||||||
return crc;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t rev_8(uint8_t b) {
|
|
||||||
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
|
|
||||||
b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
|
|
||||||
b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t rev_32(uint32_t b) {
|
|
||||||
uint8_t b0 = rev_8(b >> 24);
|
|
||||||
uint8_t b1 = rev_8(b >> 16);
|
|
||||||
uint8_t b2 = rev_8(b >> 8);
|
|
||||||
uint8_t b3 = rev_8(b);
|
|
||||||
return (b3 << 24) | (b2 << 16) | (b1 << 8) | b0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void crc32(const uint8_t *data, size_t len, uint32_t* cs_out) {
|
|
||||||
uint8_t rev_data[252] = {};
|
|
||||||
for (size_t i=0; i < sizeof(rev_data); i++) {
|
|
||||||
rev_data[i] = rev_8(data[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t crc = crc32_byte(rev_data, sizeof(rev_data));
|
|
||||||
|
|
||||||
crc = rev_32(crc);
|
|
||||||
|
|
||||||
*cs_out = crc;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t calc_checksum(std::vector<uint8_t> bin) {
|
|
||||||
assert(bin.size() == 252);
|
|
||||||
|
|
||||||
uint32_t checksum = 0;
|
|
||||||
crc32(bin.data(), bin.size(), &checksum);
|
|
||||||
|
|
||||||
return checksum;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if HAS_MBEDTLS
|
#if HAS_MBEDTLS
|
||||||
void hash_andor_sign_block(block *new_block, const public_t public_key, const private_t private_key, bool hash_value, bool sign, std::vector<uint8_t> to_hash) {
|
void hash_andor_sign_block(block *new_block, const public_t public_key, const private_t private_key, bool hash_value, bool sign, std::vector<uint8_t> to_hash) {
|
||||||
std::shared_ptr<hash_def_item> hash_def = std::make_shared<hash_def_item>(PICOBIN_HASH_SHA256);
|
std::shared_ptr<hash_def_item> hash_def = std::make_shared<hash_def_item>(PICOBIN_HASH_SHA256);
|
||||||
|
@ -668,29 +554,21 @@ std::vector<uint8_t> get_lm_hash_data(elf_file *elf, block *new_block, bool clea
|
||||||
for(const auto &entry : load_map->entries) {
|
for(const auto &entry : load_map->entries) {
|
||||||
std::vector<uint8_t> data;
|
std::vector<uint8_t> data;
|
||||||
uint32_t current_storage_address = entry.storage_address;
|
uint32_t current_storage_address = entry.storage_address;
|
||||||
if (current_storage_address == 0) {
|
while (data.size() < entry.size) {
|
||||||
std::copy(
|
auto seg = elf->segment_from_physical_address(current_storage_address);
|
||||||
(uint8_t*)&entry.size,
|
if (seg == nullptr) {
|
||||||
(uint8_t*)&entry.size + sizeof(entry.size),
|
fail(ERROR_NOT_POSSIBLE, "The ELF file does not contain the storage address %x", current_storage_address);
|
||||||
std::back_inserter(to_hash));
|
|
||||||
DEBUG_LOG("CLEAR %08x + %08x\n", (int)entry.runtime_address, (int)entry.size);
|
|
||||||
} else {
|
|
||||||
while (data.size() < entry.size) {
|
|
||||||
auto seg = elf->segment_from_physical_address(current_storage_address);
|
|
||||||
if (seg == nullptr) {
|
|
||||||
fail(ERROR_NOT_POSSIBLE, "The ELF file does not contain the storage address %x", current_storage_address);
|
|
||||||
}
|
|
||||||
const auto new_data = elf->content(*seg);
|
|
||||||
|
|
||||||
uint32_t offset = current_storage_address - seg->physical_address();
|
|
||||||
|
|
||||||
std::copy(new_data.begin()+offset, new_data.end(), std::back_inserter(data));
|
|
||||||
current_storage_address += new_data.size();
|
|
||||||
}
|
}
|
||||||
data.resize(entry.size);
|
const auto new_data = elf->content(*seg);
|
||||||
std::copy(data.begin(), data.end(), std::back_inserter(to_hash));
|
|
||||||
DEBUG_LOG("HASH %08x + %08x\n", (int)entry.storage_address, (int)data.size());
|
uint32_t offset = current_storage_address - seg->physical_address();
|
||||||
|
|
||||||
|
std::copy(new_data.begin()+offset, new_data.end(), std::back_inserter(data));
|
||||||
|
current_storage_address += new_data.size();
|
||||||
}
|
}
|
||||||
|
data.resize(entry.size);
|
||||||
|
std::copy(data.begin(), data.end(), std::back_inserter(to_hash));
|
||||||
|
DEBUG_LOG("HASH %08x + %08x\n", (int)entry.storage_address, (int)data.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -735,7 +613,7 @@ std::vector<uint8_t> get_lm_hash_data(std::vector<uint8_t> bin, uint32_t storage
|
||||||
(uint8_t*)&entry.size,
|
(uint8_t*)&entry.size,
|
||||||
(uint8_t*)&entry.size + sizeof(entry.size),
|
(uint8_t*)&entry.size + sizeof(entry.size),
|
||||||
std::back_inserter(to_hash));
|
std::back_inserter(to_hash));
|
||||||
DEBUG_LOG("CLEAR %08x + %08x\n", (int)entry.runtime_address, (int)entry.size);
|
DEBUG_LOG("HASH CLEAR %08x + %08x\n", (int)entry.storage_address, (int)entry.size);
|
||||||
} else {
|
} else {
|
||||||
uint32_t rel_addr = entry.storage_address - storage_addr;
|
uint32_t rel_addr = entry.storage_address - storage_addr;
|
||||||
std::copy(
|
std::copy(
|
||||||
|
|
|
@ -34,7 +34,6 @@ std::unique_ptr<block> find_first_block(std::vector<uint8_t> bin, uint32_t stora
|
||||||
std::unique_ptr<block> get_last_block(std::vector<uint8_t> &bin, uint32_t storage_addr, std::unique_ptr<block> &first_block, get_more_bin_cb more_cb = nullptr);
|
std::unique_ptr<block> get_last_block(std::vector<uint8_t> &bin, uint32_t storage_addr, std::unique_ptr<block> &first_block, get_more_bin_cb more_cb = nullptr);
|
||||||
std::vector<std::unique_ptr<block>> get_all_blocks(std::vector<uint8_t> &bin, uint32_t storage_addr, std::unique_ptr<block> &first_block, get_more_bin_cb more_cb = nullptr);
|
std::vector<std::unique_ptr<block>> get_all_blocks(std::vector<uint8_t> &bin, uint32_t storage_addr, std::unique_ptr<block> &first_block, get_more_bin_cb more_cb = nullptr);
|
||||||
block place_new_block(std::vector<uint8_t> &bin, uint32_t storage_addr, std::unique_ptr<block> &first_block);
|
block place_new_block(std::vector<uint8_t> &bin, uint32_t storage_addr, std::unique_ptr<block> &first_block);
|
||||||
uint32_t calc_checksum(std::vector<uint8_t> bin);
|
|
||||||
#if HAS_MBEDTLS
|
#if HAS_MBEDTLS
|
||||||
std::vector<uint8_t> hash_andor_sign(std::vector<uint8_t> bin, uint32_t storage_addr, uint32_t runtime_addr, block *new_block, const public_t public_key, const private_t private_key, bool hash_value, bool sign, bool clear_sram = false);
|
std::vector<uint8_t> hash_andor_sign(std::vector<uint8_t> bin, uint32_t storage_addr, uint32_t runtime_addr, block *new_block, const public_t public_key, const private_t private_key, bool hash_value, bool sign, bool clear_sram = false);
|
||||||
std::vector<uint8_t> encrypt(std::vector<uint8_t> bin, uint32_t storage_addr, uint32_t runtime_addr, block *new_block, const private_t aes_key, const public_t public_key, const private_t private_key, bool hash_value, bool sign);
|
std::vector<uint8_t> encrypt(std::vector<uint8_t> bin, uint32_t storage_addr, uint32_t runtime_addr, block *new_block, const private_t aes_key, const public_t public_key, const private_t private_key, bool hash_value, bool sign);
|
||||||
|
|
|
@ -225,55 +225,8 @@ struct partition_table_item : public single_byte_size_item {
|
||||||
partition_table_item() = default;
|
partition_table_item() = default;
|
||||||
|
|
||||||
explicit partition_table_item(uint32_t unpartitioned_flags, bool singleton) : unpartitioned_flags(unpartitioned_flags), singleton(singleton) {}
|
explicit partition_table_item(uint32_t unpartitioned_flags, bool singleton) : unpartitioned_flags(unpartitioned_flags), singleton(singleton) {}
|
||||||
template <typename I> static std::shared_ptr<item> parse(I& it, I end, uint32_t header) {
|
template <typename I> static std::shared_ptr<item> parse(I it, I end, uint32_t header) {
|
||||||
uint32_t size = decode_size(header);
|
return nullptr;
|
||||||
uint8_t singleton_count = header >> 24;
|
|
||||||
bool singleton = singleton_count & 0x80;
|
|
||||||
uint8_t partition_count = singleton_count & 0x0f;
|
|
||||||
uint32_t unpartitioned_flags = *it++;
|
|
||||||
|
|
||||||
auto pt = std::make_shared<partition_table_item>(unpartitioned_flags, singleton);
|
|
||||||
|
|
||||||
std::vector<uint32_t> data;
|
|
||||||
for (unsigned int i=2; i < size; i++) {
|
|
||||||
data.push_back(*it++);
|
|
||||||
}
|
|
||||||
int i=0;
|
|
||||||
while (i < data.size()) {
|
|
||||||
partition new_p;
|
|
||||||
uint32_t permissions_locations = data[i++];
|
|
||||||
new_p.permissions = (permissions_locations & PICOBIN_PARTITION_PERMISSIONS_BITS) >> PICOBIN_PARTITION_PERMISSIONS_LSB;
|
|
||||||
new_p.first_sector = (permissions_locations & PICOBIN_PARTITION_LOCATION_FIRST_SECTOR_BITS) >> PICOBIN_PARTITION_LOCATION_FIRST_SECTOR_LSB;
|
|
||||||
new_p.last_sector = (permissions_locations & PICOBIN_PARTITION_LOCATION_LAST_SECTOR_BITS) >> PICOBIN_PARTITION_LOCATION_LAST_SECTOR_LSB;
|
|
||||||
|
|
||||||
uint32_t permissions_flags = data[i++];
|
|
||||||
uint8_t permissions2 = (permissions_flags & PICOBIN_PARTITION_PERMISSIONS_BITS) >> PICOBIN_PARTITION_PERMISSIONS_LSB;
|
|
||||||
if (new_p.permissions != permissions2) {
|
|
||||||
printf("Permissions mismatch %02x %02x\n", new_p.permissions, permissions2);
|
|
||||||
assert(false);
|
|
||||||
}
|
|
||||||
new_p.flags = permissions_flags & (~PICOBIN_PARTITION_PERMISSIONS_BITS);
|
|
||||||
|
|
||||||
if (new_p.flags & PICOBIN_PARTITION_FLAGS_HAS_ID_BITS) {
|
|
||||||
new_p.id = (uint64_t)data[i++] | ((uint64_t)data[i++] << 32);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t num_extra_families = (new_p.flags & PICOBIN_PARTITION_FLAGS_ACCEPTS_NUM_EXTRA_FAMILIES_BITS) >> PICOBIN_PARTITION_FLAGS_ACCEPTS_NUM_EXTRA_FAMILIES_LSB;
|
|
||||||
for (int fam=0; fam < num_extra_families; fam++) {
|
|
||||||
new_p.extra_families.push_back(data[i++]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (new_p.flags & PICOBIN_PARTITION_FLAGS_HAS_NAME_BITS) {
|
|
||||||
auto bytes = words_to_lsb_bytes(data.begin() + i++, data.end());
|
|
||||||
int name_size = bytes[0];
|
|
||||||
// This works neatly - accounts for the size byte at the start
|
|
||||||
i += name_size / 4;
|
|
||||||
new_p.name = std::string((char*)(bytes.data() + 1), name_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
pt->partitions.push_back(new_p);
|
|
||||||
}
|
|
||||||
return pt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint32_t> to_words(item_writer_context& ctx) const override {
|
std::vector<uint32_t> to_words(item_writer_context& ctx) const override {
|
||||||
|
@ -414,11 +367,7 @@ struct load_map_item : public item {
|
||||||
if (absolute) {
|
if (absolute) {
|
||||||
rc.push_back(entry.storage_address);
|
rc.push_back(entry.storage_address);
|
||||||
rc.push_back(entry.runtime_address);
|
rc.push_back(entry.runtime_address);
|
||||||
if (entry.storage_address != 0) {
|
rc.push_back(entry.runtime_address + entry.size);
|
||||||
rc.push_back(entry.runtime_address + entry.size);
|
|
||||||
} else {
|
|
||||||
rc.push_back(entry.size);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (entry.storage_address != 0) {
|
if (entry.storage_address != 0) {
|
||||||
rc.push_back(entry.storage_address - ctx.base_addr - ctx.word_offset * 4);
|
rc.push_back(entry.storage_address - ctx.base_addr - ctx.word_offset * 4);
|
||||||
|
@ -621,7 +570,7 @@ struct block {
|
||||||
i = image_type_item::parse(it, end, header);
|
i = image_type_item::parse(it, end, header);
|
||||||
break;
|
break;
|
||||||
case PICOBIN_BLOCK_ITEM_PARTITION_TABLE:
|
case PICOBIN_BLOCK_ITEM_PARTITION_TABLE:
|
||||||
i = partition_table_item::parse(it, end, header);
|
i = ignored_item::parse(it, end, header);
|
||||||
break;
|
break;
|
||||||
case PICOBIN_BLOCK_ITEM_1BS_VECTOR_TABLE:
|
case PICOBIN_BLOCK_ITEM_1BS_VECTOR_TABLE:
|
||||||
i = vector_table_item::parse(it, end, header);
|
i = vector_table_item::parse(it, end, header);
|
||||||
|
|
7
cli.h
7
cli.h
|
@ -432,18 +432,13 @@ namespace cli {
|
||||||
base = 2;
|
base = 2;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
if (std::is_signed<T>()) {
|
lvalue = std::stoll(value, &pos, base);
|
||||||
lvalue = std::stoll(value, &pos, base);
|
|
||||||
} else {
|
|
||||||
lvalue = std::stoull(value, &pos, base);
|
|
||||||
}
|
|
||||||
if (pos != value.length()) {
|
if (pos != value.length()) {
|
||||||
return "Garbage after integer value: " + value.substr(pos);
|
return "Garbage after integer value: " + value.substr(pos);
|
||||||
}
|
}
|
||||||
} catch (std::invalid_argument&) {
|
} catch (std::invalid_argument&) {
|
||||||
return value + " is not a valid integer";
|
return value + " is not a valid integer";
|
||||||
} catch (std::out_of_range&) {
|
} catch (std::out_of_range&) {
|
||||||
return value + " is out of range";
|
|
||||||
}
|
}
|
||||||
if (lvalue != (int64_t)lvalue) {
|
if (lvalue != (int64_t)lvalue) {
|
||||||
return value + " is too big";
|
return value + " is too big";
|
||||||
|
|
|
@ -25,9 +25,7 @@ else (LIBUSB_INCLUDE_DIR AND LIBUSB_LIBRARIES)
|
||||||
|
|
||||||
if (PKG_CONFIG_FOUND)
|
if (PKG_CONFIG_FOUND)
|
||||||
pkg_check_modules(PC_LIBUSB libusb-1.0)
|
pkg_check_modules(PC_LIBUSB libusb-1.0)
|
||||||
endif()
|
else ()
|
||||||
|
|
||||||
if (NOT PC_LIBUSB_FOUND)
|
|
||||||
# As the pkg-config was not found we are probably building under windows.
|
# As the pkg-config was not found we are probably building under windows.
|
||||||
# Determine the architecture of the host, to choose right library
|
# Determine the architecture of the host, to choose right library
|
||||||
if (NOT DEFINED ARCHITECTURE)
|
if (NOT DEFINED ARCHITECTURE)
|
||||||
|
@ -58,10 +56,5 @@ else (LIBUSB_INCLUDE_DIR AND LIBUSB_LIBRARIES)
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
include(FindPackageHandleStandardArgs)
|
||||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBUSB DEFAULT_MSG LIBUSB_LIBRARIES LIBUSB_INCLUDE_DIR)
|
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBUSB DEFAULT_MSG LIBUSB_LIBRARIES LIBUSB_INCLUDE_DIR)
|
||||||
|
|
||||||
# Don't use .dll.a libraries, as they require the .dll file to be in the correct location
|
|
||||||
# Replace with .a for static linking instead
|
|
||||||
string(REPLACE ".dll.a" ".a" LIBUSB_LIBRARIES ${LIBUSB_LIBRARIES})
|
|
||||||
|
|
||||||
MARK_AS_ADVANCED(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARIES)
|
MARK_AS_ADVANCED(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARIES)
|
||||||
endif (LIBUSB_INCLUDE_DIR AND LIBUSB_LIBRARIES)
|
endif (LIBUSB_INCLUDE_DIR AND LIBUSB_LIBRARIES)
|
||||||
|
|
36
default-pt.json
Normal file
36
default-pt.json
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
{
|
||||||
|
"version": [1, 0],
|
||||||
|
"unpartitioned": {
|
||||||
|
"families": ["absolute"],
|
||||||
|
"permissions": {
|
||||||
|
"secure": "rw",
|
||||||
|
"nonsecure": "rw",
|
||||||
|
"bootloader": "rw"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"partitions": [
|
||||||
|
{
|
||||||
|
"name": "A",
|
||||||
|
"id": 0,
|
||||||
|
"size": "2044K",
|
||||||
|
"families": ["rp2350-arm-s", "rp2350-riscv"],
|
||||||
|
"permissions": {
|
||||||
|
"secure": "rw",
|
||||||
|
"nonsecure": "rw",
|
||||||
|
"bootloader": "rw"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "B",
|
||||||
|
"id": 1,
|
||||||
|
"size": "2044K",
|
||||||
|
"families": ["rp2350-arm-s", "rp2350-riscv"],
|
||||||
|
"permissions": {
|
||||||
|
"secure": "rw",
|
||||||
|
"nonsecure": "rw",
|
||||||
|
"bootloader": "rw"
|
||||||
|
},
|
||||||
|
"link": ["a", 0]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -150,10 +150,7 @@ int rp_check_elf_header(const elf32_header &eh) {
|
||||||
if (eh.common.machine != EM_ARM && eh.common.machine != EM_RISCV) {
|
if (eh.common.machine != EM_ARM && eh.common.machine != EM_RISCV) {
|
||||||
fail(ERROR_FORMAT, "Not an Arm or RISC-V executable");
|
fail(ERROR_FORMAT, "Not an Arm or RISC-V executable");
|
||||||
}
|
}
|
||||||
// Accept either ELFOSABI_NONE or ELFOSABI_GNU for EI_OSABI. Compilers may
|
if (eh.common.abi != 0) {
|
||||||
// set the OS/ABI field to ELFOSABI_GNU when they use GNU features, such as
|
|
||||||
// the SHF_GNU_RETAIN section flag, but the binary is still compatible.
|
|
||||||
if (eh.common.abi != 0 /* NONE */ && eh.common.abi != 3 /* GNU */) {
|
|
||||||
fail(ERROR_INCOMPATIBLE, "Unrecognized ABI");
|
fail(ERROR_INCOMPATIBLE, "Unrecognized ABI");
|
||||||
}
|
}
|
||||||
// todo amy not sure if this should be expected or not - we have HARD float in clang only for now
|
// todo amy not sure if this should be expected or not - we have HARD float in clang only for now
|
||||||
|
@ -230,15 +227,6 @@ void elf_file::flatten(void) {
|
||||||
}
|
}
|
||||||
idx++;
|
idx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
idx = 0;
|
|
||||||
for (const auto &ph : ph_entries) {
|
|
||||||
if (ph.filez) {
|
|
||||||
elf_bytes.resize(std::max(ph.offset + ph.filez, (uint32_t)elf_bytes.size()));
|
|
||||||
memcpy(&elf_bytes[ph.offset], &ph_data[idx][0], ph.filez);
|
|
||||||
}
|
|
||||||
idx++;
|
|
||||||
}
|
|
||||||
if (verbose) printf("Elf file size %zu\n", elf_bytes.size());
|
if (verbose) printf("Elf file size %zu\n", elf_bytes.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,18 +262,6 @@ void elf_file::read_sh_data(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void elf_file::read_ph_data(void) {
|
|
||||||
int ph_idx = 0;
|
|
||||||
ph_data.resize(eh.ph_num);
|
|
||||||
for (const auto &ph: ph_entries) {
|
|
||||||
if (ph.filez) {
|
|
||||||
ph_data[ph_idx].resize(ph.filez);
|
|
||||||
read_bytes(ph.offset, ph.filez, &ph_data[ph_idx][0]);
|
|
||||||
}
|
|
||||||
ph_idx++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string elf_file::section_name(uint32_t sh_name) const {
|
const std::string elf_file::section_name(uint32_t sh_name) const {
|
||||||
if (!eh.sh_str_index || eh.sh_str_index > eh.sh_num)
|
if (!eh.sh_str_index || eh.sh_str_index > eh.sh_num)
|
||||||
return "";
|
return "";
|
||||||
|
@ -393,7 +369,6 @@ int elf_file::read_file(std::shared_ptr<std::iostream> file) {
|
||||||
read_sh();
|
read_sh();
|
||||||
}
|
}
|
||||||
read_sh_data();
|
read_sh_data();
|
||||||
read_ph_data();
|
|
||||||
}
|
}
|
||||||
catch (const std::ios_base::failure &e) {
|
catch (const std::ios_base::failure &e) {
|
||||||
std::cerr << "Failed to read elf file" << std::endl;
|
std::cerr << "Failed to read elf file" << std::endl;
|
||||||
|
@ -440,7 +415,6 @@ void elf_file::content(const elf32_ph_entry &ph, const std::vector<uint8_t> &con
|
||||||
if (verbose) printf("Update segment content offset %x content size %zx physical size %x\n", ph.offset, content.size(), ph.filez);
|
if (verbose) printf("Update segment content offset %x content size %zx physical size %x\n", ph.offset, content.size(), ph.filez);
|
||||||
memcpy(&elf_bytes[ph.offset], &content[0], std::min(content.size(), (size_t) ph.filez));
|
memcpy(&elf_bytes[ph.offset], &content[0], std::min(content.size(), (size_t) ph.filez));
|
||||||
read_sh_data(); // Extract the sections after modifying the content
|
read_sh_data(); // Extract the sections after modifying the content
|
||||||
read_ph_data();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void elf_file::content(const elf32_sh_entry &sh, const std::vector<uint8_t> &content) {
|
void elf_file::content(const elf32_sh_entry &sh, const std::vector<uint8_t> &content) {
|
||||||
|
@ -449,7 +423,6 @@ void elf_file::content(const elf32_sh_entry &sh, const std::vector<uint8_t> &con
|
||||||
if (verbose) printf("Update section content offset %x content size %zx section size %x\n", sh.offset, content.size(), sh.size);
|
if (verbose) printf("Update section content offset %x content size %zx section size %x\n", sh.offset, content.size(), sh.size);
|
||||||
memcpy(&elf_bytes[sh.offset], &content[0], std::min(content.size(), (size_t) sh.size));
|
memcpy(&elf_bytes[sh.offset], &content[0], std::min(content.size(), (size_t) sh.size));
|
||||||
read_sh_data(); // Extract the sections after modifying the content
|
read_sh_data(); // Extract the sections after modifying the content
|
||||||
read_ph_data();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const elf32_ph_entry* elf_file::segment_from_physical_address(uint32_t paddr) {
|
const elf32_ph_entry* elf_file::segment_from_physical_address(uint32_t paddr) {
|
||||||
|
@ -527,7 +500,6 @@ const elf32_ph_entry& elf_file::append_segment(uint32_t vaddr, uint32_t paddr, u
|
||||||
sh_entries.push_back(sh);
|
sh_entries.push_back(sh);
|
||||||
sh_data.push_back(std::vector<uint8_t>(size));
|
sh_data.push_back(std::vector<uint8_t>(size));
|
||||||
ph_entries.back().offset = sh.offset;
|
ph_entries.back().offset = sh.offset;
|
||||||
ph_data.push_back(std::vector<uint8_t>(size));
|
|
||||||
|
|
||||||
eh.sh_offset = sh.offset + sh.size;
|
eh.sh_offset = sh.offset + sh.size;
|
||||||
eh.sh_num++;
|
eh.sh_num++;
|
||||||
|
|
|
@ -55,7 +55,6 @@ private:
|
||||||
void read_ph(void);
|
void read_ph(void);
|
||||||
void read_sh(void);
|
void read_sh(void);
|
||||||
void read_sh_data(void);
|
void read_sh_data(void);
|
||||||
void read_ph_data(void);
|
|
||||||
void read_bytes(unsigned offset, unsigned length, void *dest);
|
void read_bytes(unsigned offset, unsigned length, void *dest);
|
||||||
uint32_t append_section_name(const std::string &sh_name_str);
|
uint32_t append_section_name(const std::string &sh_name_str);
|
||||||
void flatten(void);
|
void flatten(void);
|
||||||
|
@ -66,7 +65,6 @@ private:
|
||||||
std::vector<elf32_ph_entry> ph_entries;
|
std::vector<elf32_ph_entry> ph_entries;
|
||||||
std::vector<elf32_sh_entry> sh_entries;
|
std::vector<elf32_sh_entry> sh_entries;
|
||||||
std::vector<std::vector<uint8_t>> sh_data;
|
std::vector<std::vector<uint8_t>> sh_data;
|
||||||
std::vector<std::vector<uint8_t>> ph_data;
|
|
||||||
bool verbose;
|
bool verbose;
|
||||||
};
|
};
|
||||||
int rp_check_elf_header(const elf32_header &eh);
|
int rp_check_elf_header(const elf32_header &eh);
|
||||||
|
|
|
@ -43,22 +43,27 @@
|
||||||
# define __LITTLE_ENDIAN LITTLE_ENDIAN
|
# define __LITTLE_ENDIAN LITTLE_ENDIAN
|
||||||
# define __PDP_ENDIAN PDP_ENDIAN
|
# define __PDP_ENDIAN PDP_ENDIAN
|
||||||
|
|
||||||
#elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
|
#elif defined(__OpenBSD__)
|
||||||
|
|
||||||
|
# include <endian.h>
|
||||||
|
|
||||||
|
# define __BYTE_ORDER BYTE_ORDER
|
||||||
|
# define __BIG_ENDIAN BIG_ENDIAN
|
||||||
|
# define __LITTLE_ENDIAN LITTLE_ENDIAN
|
||||||
|
# define __PDP_ENDIAN PDP_ENDIAN
|
||||||
|
|
||||||
|
#elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
|
||||||
|
|
||||||
# include <sys/endian.h>
|
# include <sys/endian.h>
|
||||||
|
|
||||||
#ifndef be16toh
|
|
||||||
# define be16toh(x) betoh16(x)
|
# define be16toh(x) betoh16(x)
|
||||||
#endif
|
|
||||||
#ifndef le16toh
|
|
||||||
# define le16toh(x) letoh16(x)
|
# define le16toh(x) letoh16(x)
|
||||||
#endif
|
|
||||||
#ifndef be32toh
|
|
||||||
# define be32toh(x) betoh32(x)
|
# define be32toh(x) betoh32(x)
|
||||||
#endif
|
|
||||||
#ifndef le32toh
|
|
||||||
# define le32toh(x) letoh32(x)
|
# define le32toh(x) letoh32(x)
|
||||||
#endif
|
|
||||||
|
# define be64toh(x) betoh64(x)
|
||||||
|
# define le64toh(x) letoh64(x)
|
||||||
|
|
||||||
#elif defined(__WINDOWS__)
|
#elif defined(__WINDOWS__)
|
||||||
|
|
||||||
|
|
|
@ -129,7 +129,7 @@ uf2_block gen_abs_block(uint32_t abs_block_loc) {
|
||||||
uf2_block block;
|
uf2_block block;
|
||||||
block.magic_start0 = UF2_MAGIC_START0;
|
block.magic_start0 = UF2_MAGIC_START0;
|
||||||
block.magic_start1 = UF2_MAGIC_START1;
|
block.magic_start1 = UF2_MAGIC_START1;
|
||||||
block.flags = UF2_FLAG_FAMILY_ID_PRESENT | UF2_FLAG_EXTENSION_FLAGS_PRESENT;
|
block.flags = UF2_FLAG_FAMILY_ID_PRESENT;
|
||||||
block.payload_size = UF2_PAGE_SIZE;
|
block.payload_size = UF2_PAGE_SIZE;
|
||||||
block.num_blocks = 2;
|
block.num_blocks = 2;
|
||||||
block.file_size = ABSOLUTE_FAMILY_ID;
|
block.file_size = ABSOLUTE_FAMILY_ID;
|
||||||
|
@ -138,7 +138,6 @@ uf2_block gen_abs_block(uint32_t abs_block_loc) {
|
||||||
block.block_no = 0;
|
block.block_no = 0;
|
||||||
memset(block.data, 0, sizeof(block.data));
|
memset(block.data, 0, sizeof(block.data));
|
||||||
memset(block.data, 0xef, UF2_PAGE_SIZE);
|
memset(block.data, 0xef, UF2_PAGE_SIZE);
|
||||||
*(uint32_t*)&(block.data[UF2_PAGE_SIZE]) = UF2_EXTENSION_RP2_IGNORE_BLOCK;
|
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,26 +145,21 @@ bool check_abs_block(uf2_block block) {
|
||||||
return std::all_of(block.data, block.data + UF2_PAGE_SIZE, [](uint8_t i) { return i == 0xef; }) &&
|
return std::all_of(block.data, block.data + UF2_PAGE_SIZE, [](uint8_t i) { return i == 0xef; }) &&
|
||||||
block.magic_start0 == UF2_MAGIC_START0 &&
|
block.magic_start0 == UF2_MAGIC_START0 &&
|
||||||
block.magic_start1 == UF2_MAGIC_START1 &&
|
block.magic_start1 == UF2_MAGIC_START1 &&
|
||||||
(block.flags & ~UF2_FLAG_EXTENSION_FLAGS_PRESENT) == UF2_FLAG_FAMILY_ID_PRESENT &&
|
block.flags == UF2_FLAG_FAMILY_ID_PRESENT &&
|
||||||
block.payload_size == UF2_PAGE_SIZE &&
|
block.payload_size == UF2_PAGE_SIZE &&
|
||||||
block.num_blocks == 2 &&
|
block.num_blocks == 2 &&
|
||||||
block.file_size == ABSOLUTE_FAMILY_ID &&
|
block.file_size == ABSOLUTE_FAMILY_ID &&
|
||||||
block.magic_end == UF2_MAGIC_END &&
|
block.magic_end == UF2_MAGIC_END &&
|
||||||
block.block_no == 0 &&
|
block.block_no == 0;
|
||||||
!(block.flags & UF2_FLAG_EXTENSION_FLAGS_PRESENT && *(uint32_t*)&(block.data[UF2_PAGE_SIZE]) != UF2_EXTENSION_RP2_IGNORE_BLOCK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int pages2uf2(std::map<uint32_t, std::vector<page_fragment>>& pages, std::shared_ptr<std::iostream> in, std::shared_ptr<std::iostream> out, uint32_t family_id, uint32_t abs_block_loc=0) {
|
int pages2uf2(std::map<uint32_t, std::vector<page_fragment>>& pages, std::shared_ptr<std::iostream> in, std::shared_ptr<std::iostream> out, uint32_t family_id, uint32_t abs_block_loc=0) {
|
||||||
// RP2350-E10: add absolute block to start of flash UF2s, targeting end of flash by default
|
// RP2350-E9: add absolute block to start, targeting end of flash by default
|
||||||
if (family_id != ABSOLUTE_FAMILY_ID && family_id != RP2040_FAMILY_ID && abs_block_loc) {
|
if (family_id != ABSOLUTE_FAMILY_ID && family_id != RP2040_FAMILY_ID && abs_block_loc) {
|
||||||
uint32_t base_addr = pages.begin()->first;
|
uf2_block block = gen_abs_block(abs_block_loc);
|
||||||
address_ranges flash_range = rp2350_address_ranges_flash;
|
out->write((char*)&block, sizeof(uf2_block));
|
||||||
if (is_address_initialized(flash_range, base_addr)) {
|
if (out->fail()) {
|
||||||
uf2_block block = gen_abs_block(abs_block_loc);
|
fail_write_error();
|
||||||
out->write((char*)&block, sizeof(uf2_block));
|
|
||||||
if (out->fail()) {
|
|
||||||
fail_write_error();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uf2_block block;
|
uf2_block block;
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
{
|
|
||||||
"$schema": "https://raw.githubusercontent.com/raspberrypi/picotool/develop/json/schemas/partition-table-schema.json",
|
|
||||||
"version": [1, 0],
|
|
||||||
"unpartitioned": {
|
|
||||||
"families": ["absolute"],
|
|
||||||
"permissions": {
|
|
||||||
"secure": "rw",
|
|
||||||
"nonsecure": "rw",
|
|
||||||
"bootloader": "rw"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"partitions": [
|
|
||||||
{
|
|
||||||
"name": "A",
|
|
||||||
"id": 0,
|
|
||||||
"size": "2044K",
|
|
||||||
"families": ["rp2350-arm-s", "rp2350-riscv"],
|
|
||||||
"permissions": {
|
|
||||||
"secure": "rw",
|
|
||||||
"nonsecure": "rw",
|
|
||||||
"bootloader": "rw"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "B",
|
|
||||||
"id": 1,
|
|
||||||
"size": "2044K",
|
|
||||||
"families": ["rp2350-arm-s", "rp2350-riscv"],
|
|
||||||
"permissions": {
|
|
||||||
"secure": "rw",
|
|
||||||
"nonsecure": "rw",
|
|
||||||
"bootloader": "rw"
|
|
||||||
},
|
|
||||||
"link": ["a", 0]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,77 +0,0 @@
|
||||||
{
|
|
||||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
||||||
"title": "OTP Contents",
|
|
||||||
"description": "Defined contents of the RP-series device OTP",
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"description": "OTP Row",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"crit": {
|
|
||||||
"description": "Critical Row (use three-of-eight vote encoding)",
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
|
||||||
"description": {
|
|
||||||
"description": "Row Description",
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"ecc": {
|
|
||||||
"description": "ECC Row",
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
|
||||||
"fields": {
|
|
||||||
"description": "Fields within row",
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"description": {
|
|
||||||
"description": "Field Description",
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"mask": {
|
|
||||||
"description": "Field Bit Mask",
|
|
||||||
"type": "integer"
|
|
||||||
},
|
|
||||||
"name": {
|
|
||||||
"description": "Field Name",
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": ["description", "mask", "name"],
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"mask": {
|
|
||||||
"description": "Row Bit Mask",
|
|
||||||
"type": "integer"
|
|
||||||
},
|
|
||||||
"name": {
|
|
||||||
"description": "Row Name",
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"redundancy": {
|
|
||||||
"description": "Number of redundant rows",
|
|
||||||
"type": "integer"
|
|
||||||
},
|
|
||||||
"row": {
|
|
||||||
"description": "OTP Row",
|
|
||||||
"type": "integer"
|
|
||||||
},
|
|
||||||
"seq_index": {
|
|
||||||
"description": "Sequence Index",
|
|
||||||
"type": "integer"
|
|
||||||
},
|
|
||||||
"seq_length": {
|
|
||||||
"description": "Sequence Length",
|
|
||||||
"type": "integer"
|
|
||||||
},
|
|
||||||
"seq_prefix": {
|
|
||||||
"description": "Sequence Prefix",
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": ["crit", "description"],
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,50 +0,0 @@
|
||||||
{
|
|
||||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
||||||
"title": "OTP Settings",
|
|
||||||
"description": "OTP Settings",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {"$schema": {}},
|
|
||||||
"patternProperties": {
|
|
||||||
"^\\d{1,2}:\\d{1,2}$": {
|
|
||||||
"description": "Generic OTP Row",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"ecc": {
|
|
||||||
"description": "Protect with ECC",
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
|
||||||
"value": {
|
|
||||||
"description": "Value to write",
|
|
||||||
"type": ["array", "string", "integer"],
|
|
||||||
"pattern": "^0x[0-9a-fA-F]{1,6}$",
|
|
||||||
"items": {
|
|
||||||
"description": "Data Byte",
|
|
||||||
"type": ["string", "integer"],
|
|
||||||
"pattern": "^0x[0-9a-fA-F]{1,2}$"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false,
|
|
||||||
"required": ["ecc", "value"]
|
|
||||||
},
|
|
||||||
"^[\\d\\w_]+$": {
|
|
||||||
"description": "Defined OTP Row",
|
|
||||||
"type": ["object", "array", "string", "integer"],
|
|
||||||
"pattern": "^0x[0-9a-fA-F]{1,6}$",
|
|
||||||
"items": {
|
|
||||||
"description": "Data Byte",
|
|
||||||
"type": ["string", "integer"],
|
|
||||||
"pattern": "^0x[0-9a-fA-F]{1,2}$"
|
|
||||||
},
|
|
||||||
"patternProperties": {
|
|
||||||
"^[\\d\\w_]+$": {
|
|
||||||
"description": "OTP Field",
|
|
||||||
"type": ["string", "integer"],
|
|
||||||
"pattern": "^0x[0-9a-fA-F]{1,6}$"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
|
@ -1,158 +0,0 @@
|
||||||
{
|
|
||||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
||||||
"title": "Partition Table",
|
|
||||||
"description": "Layout of the partition table",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"$schema": {},
|
|
||||||
"version": {
|
|
||||||
"description": "Partition Table Version",
|
|
||||||
"type": "array",
|
|
||||||
"prefixItems": [
|
|
||||||
{
|
|
||||||
"description": "Major Version",
|
|
||||||
"type": "integer",
|
|
||||||
"minimum": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Minor Version",
|
|
||||||
"type": "integer",
|
|
||||||
"minimum": 0
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"unpartitioned": {
|
|
||||||
"description": "Unpartitioned space UF2 families and permissions",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"families": {
|
|
||||||
"description": "UF2 families accepted",
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"enum": [
|
|
||||||
"data",
|
|
||||||
"absolute",
|
|
||||||
"rp2040",
|
|
||||||
"rp2350-arm-s",
|
|
||||||
"rp2350-arm-ns",
|
|
||||||
"rp2350-riscv"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"permissions": {"$ref": "#/$defs/permissions"}
|
|
||||||
},
|
|
||||||
"required": ["permissions", "families"],
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
"partitions": {
|
|
||||||
"description": "Partitions",
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"name": {
|
|
||||||
"description": "Partition Name",
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"id": {
|
|
||||||
"description": "Partition ID",
|
|
||||||
"type": ["integer", "string"],
|
|
||||||
"minimum": 0,
|
|
||||||
"exclusiveMaximum": 18446744073709551616,
|
|
||||||
"pattern": "^0x[0-9a-fA-F]{1,16}$",
|
|
||||||
"examples": [
|
|
||||||
"0xDED3FFFF01234567",
|
|
||||||
29,
|
|
||||||
"0xdeadbeef"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"start": {
|
|
||||||
"description": "Partition Start",
|
|
||||||
"type": ["integer", "string"],
|
|
||||||
"minimum": 0,
|
|
||||||
"pattern": "^\\d+(k|K)$"
|
|
||||||
},
|
|
||||||
"size": {
|
|
||||||
"description": "Partition Size",
|
|
||||||
"type": ["integer", "string"],
|
|
||||||
"minimum": 0,
|
|
||||||
"pattern": "^\\d+(k|K)$"
|
|
||||||
},
|
|
||||||
"families": {
|
|
||||||
"description": "UF2 families accepted",
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "string",
|
|
||||||
"pattern": "^data|absolute|rp2040|rp2350-arm-s|rp2350-arm-ns|rp2350-riscv|0x[0-9a-fA-F]{1,8}$",
|
|
||||||
"examples": [
|
|
||||||
"data",
|
|
||||||
"absolute",
|
|
||||||
"rp2040",
|
|
||||||
"rp2350-arm-s",
|
|
||||||
"rp2350-arm-ns",
|
|
||||||
"rp2350-riscv"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"permissions": {"$ref": "#/$defs/permissions"},
|
|
||||||
"link": {
|
|
||||||
"type": "array",
|
|
||||||
"prefixItems": [
|
|
||||||
{
|
|
||||||
"description": "Link Type",
|
|
||||||
"enum": ["a", "owner" , "none"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Link Value",
|
|
||||||
"type": "integer"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"no_reboot_on_uf2_download": {
|
|
||||||
"description": "Don't reboot after UF2 is downloaded",
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
|
||||||
"ab_non_bootable_owner_affinity": {
|
|
||||||
"description": "Pick the non-bootable owner instead",
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
|
||||||
"ignored_during_riscv_boot": {
|
|
||||||
"description": "Ignore this partition during Risc-V boot",
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
|
||||||
"ignored_during_arm_boot": {
|
|
||||||
"description": "Ignore this partition during Arm boot",
|
|
||||||
"type": "boolean"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": ["size", "permissions", "families"],
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": ["unpartitioned", "partitions"],
|
|
||||||
"additionalProperties": false,
|
|
||||||
"$defs": {
|
|
||||||
"permissions": {
|
|
||||||
"description": "Permissions",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"secure": {
|
|
||||||
"description": "Secure Permissions",
|
|
||||||
"type": "string",
|
|
||||||
"pattern": "^(r|w){0,2}$"
|
|
||||||
},
|
|
||||||
"nonsecure": {
|
|
||||||
"description": "Non-Secure Permissions",
|
|
||||||
"type": "string",
|
|
||||||
"pattern": "^(r|w){0,2}$"
|
|
||||||
},
|
|
||||||
"bootloader": {
|
|
||||||
"description": "Bootloader Permissions",
|
|
||||||
"type": "string",
|
|
||||||
"pattern": "^(r|w){0,2}$"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,52 +0,0 @@
|
||||||
{
|
|
||||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
||||||
"title": "OTP Permissions",
|
|
||||||
"description": "Setup of OTP page permissions",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {"$schema": {}},
|
|
||||||
"patternProperties": {
|
|
||||||
"^[0-6][0-9]$": {
|
|
||||||
"description": "OTP Page Permissions",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"no_key_state": {
|
|
||||||
"description": "State when at least one key is registered for this page and no matching key has been entered: 0 -> read_only, 1 -> inaccessible",
|
|
||||||
"type": "integer",
|
|
||||||
"minimum": 0,
|
|
||||||
"maximum": 1
|
|
||||||
},
|
|
||||||
"key_r": {
|
|
||||||
"description": "Index 1-6 of a hardware key which must be entered to grant read access, or 0 if no such key is required",
|
|
||||||
"type": "integer",
|
|
||||||
"minimum": 0,
|
|
||||||
"maximum": 6
|
|
||||||
},
|
|
||||||
"key_w": {
|
|
||||||
"description": "Index 1-6 of a hardware key which must be entered to grant write access, or 0 if no such key is required",
|
|
||||||
"type": "integer",
|
|
||||||
"minimum": 0,
|
|
||||||
"maximum": 6
|
|
||||||
},
|
|
||||||
"lock_bl": {
|
|
||||||
"description": "Dummy lock bits reserved for bootloaders (including the RP2350 USB bootloader) to store their own OTP access permissions: 0 -> read_write, 1 -> read_only, 2 -> Do not use (behaves the same as incaccessible), 3 -> inaccessible",
|
|
||||||
"type": "integer",
|
|
||||||
"minimum": 0,
|
|
||||||
"maximum": 3
|
|
||||||
},
|
|
||||||
"lock_ns": {
|
|
||||||
"description": "Lock state for Non-secure accesses to this page: 0 -> read_write, 1 -> read_only, 2 -> Do not use (behaves the same as incaccessible), 3 -> inaccessible",
|
|
||||||
"type": "integer",
|
|
||||||
"minimum": 0,
|
|
||||||
"maximum": 3
|
|
||||||
},
|
|
||||||
"lock_s": {
|
|
||||||
"description": "Lock state for Secure accesses to this page: 0 -> read_write, 1 -> read_only, 2 -> Do not use (behaves the same as incaccessible), 3 -> inaccessible",
|
|
||||||
"type": "integer",
|
|
||||||
"minimum": 0,
|
|
||||||
"maximum": 3
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
|
@ -1,124 +0,0 @@
|
||||||
{
|
|
||||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
||||||
"title": "White Labelling",
|
|
||||||
"description": "White Labelling Configuration, see section 5.7 in the RP2350 datasheet for more details",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"$schema": {},
|
|
||||||
"device": {
|
|
||||||
"description": "Device Properties",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"vid": {
|
|
||||||
"description": "Vendor ID",
|
|
||||||
"type": "string",
|
|
||||||
"pattern": "^0x[0-9a-fA-F]{4}$"
|
|
||||||
},
|
|
||||||
"pid": {
|
|
||||||
"description": "Product ID",
|
|
||||||
"type": "string",
|
|
||||||
"pattern": "^0x[0-9a-fA-F]{4}$"
|
|
||||||
},
|
|
||||||
"bcd": {
|
|
||||||
"description": "Device Revision",
|
|
||||||
"type": "number",
|
|
||||||
"minimum": 0,
|
|
||||||
"maximum": 99
|
|
||||||
},
|
|
||||||
"lang_id": {
|
|
||||||
"description": "Language ID",
|
|
||||||
"type": "string",
|
|
||||||
"pattern": "^0x[0-9a-fA-F]{4}$"
|
|
||||||
},
|
|
||||||
"manufacturer": {
|
|
||||||
"description": "Manufacturer Name (can contain unicode)",
|
|
||||||
"type": "string",
|
|
||||||
"maxLength": 30
|
|
||||||
},
|
|
||||||
"product": {
|
|
||||||
"description": "Product Name (can contain unicode)",
|
|
||||||
"type": "string",
|
|
||||||
"maxLength": 30
|
|
||||||
},
|
|
||||||
"serial_number": {
|
|
||||||
"description": "Serial Number (can contain unicode)",
|
|
||||||
"type": "string",
|
|
||||||
"maxLength": 30
|
|
||||||
},
|
|
||||||
"max_power": {
|
|
||||||
"description": "Max power consumption, in 2mA units",
|
|
||||||
"type": ["integer", "string"],
|
|
||||||
"maximum": 255,
|
|
||||||
"pattern": "^0x[0-9a-fA-F]{1,2}$"
|
|
||||||
},
|
|
||||||
"attributes": {
|
|
||||||
"description": "Device attributes: bit 7 must be 1, bit 6 is self-powered, bit 5 is remote wakeup, bits 0-4 must be 0",
|
|
||||||
"type": ["integer", "string"],
|
|
||||||
"minimum": 128,
|
|
||||||
"maximum": 224,
|
|
||||||
"pattern": "^0x[8aceACE]{1}0$"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"dependentRequired": {
|
|
||||||
"max_power": ["attributes"],
|
|
||||||
"attributes": ["max_power"]
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
"scsi": {
|
|
||||||
"description": "SCSI Inquiry Values",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"vendor": {
|
|
||||||
"description": "SCSI Vendor",
|
|
||||||
"type": "string",
|
|
||||||
"maxLength": 8
|
|
||||||
},
|
|
||||||
"product": {
|
|
||||||
"description": "SCSI Product",
|
|
||||||
"type": "string",
|
|
||||||
"maxLength": 16
|
|
||||||
},
|
|
||||||
"version": {
|
|
||||||
"description": "SCSI Version",
|
|
||||||
"type": "string",
|
|
||||||
"maxLength": 4
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
"volume": {
|
|
||||||
"description": "MSD Volume Configuration",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"label": {
|
|
||||||
"description": "Volume Label",
|
|
||||||
"type": "string",
|
|
||||||
"maxLength": 11
|
|
||||||
},
|
|
||||||
"redirect_url": {
|
|
||||||
"description": "INDEX.HTM Redirect URL",
|
|
||||||
"type": "string",
|
|
||||||
"maxLength": 127
|
|
||||||
},
|
|
||||||
"redirect_name": {
|
|
||||||
"description": "INDEX.HTM Redirect Name",
|
|
||||||
"type": "string",
|
|
||||||
"maxLength": 127
|
|
||||||
},
|
|
||||||
"model": {
|
|
||||||
"description": "INFO_UF2.TXT Model Name",
|
|
||||||
"type": "string",
|
|
||||||
"maxLength": 127
|
|
||||||
},
|
|
||||||
"board_id": {
|
|
||||||
"description": "INFO_UF2.TXT Board ID",
|
|
||||||
"type": "string",
|
|
||||||
"maxLength": 127
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
|
@ -1,11 +1,5 @@
|
||||||
package(default_visibility = ["//visibility:public"])
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
cc_library(
|
|
||||||
name = "pre_generated_otp_header",
|
|
||||||
includes = ["."],
|
|
||||||
hdrs = ["rp2350.json.h"],
|
|
||||||
)
|
|
||||||
|
|
||||||
cc_binary(
|
cc_binary(
|
||||||
name = "otp_header_parser",
|
name = "otp_header_parser",
|
||||||
srcs = ["otp_header_parse.cpp"],
|
srcs = ["otp_header_parse.cpp"],
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#include "nlohmann/json.hpp"
|
#include "nlohmann/json.hpp"
|
||||||
|
|
||||||
// missing __builtins on windows
|
// missing __builtins on windows
|
||||||
#if defined(_MSC_VER) && !defined(__clang__)
|
#ifdef _MSC_VER
|
||||||
# include <intrin.h>
|
# include <intrin.h>
|
||||||
# define __builtin_popcount __popcnt
|
# define __builtin_popcount __popcnt
|
||||||
static __forceinline int __builtin_ctz(unsigned x) {
|
static __forceinline int __builtin_ctz(unsigned x) {
|
||||||
|
|
|
@ -9,7 +9,6 @@ cc_library(
|
||||||
hdrs = [
|
hdrs = [
|
||||||
"picoboot_connection.h",
|
"picoboot_connection.h",
|
||||||
"picoboot_connection_cxx.h",
|
"picoboot_connection_cxx.h",
|
||||||
"//:flash_id_bin.h",
|
|
||||||
],
|
],
|
||||||
defines = ["HAS_LIBUSB=1"], # Bazel build always has libusb.
|
defines = ["HAS_LIBUSB=1"], # Bazel build always has libusb.
|
||||||
includes = ["."],
|
includes = ["."],
|
||||||
|
@ -17,8 +16,6 @@ cc_library(
|
||||||
"//elf",
|
"//elf",
|
||||||
"@libusb",
|
"@libusb",
|
||||||
"@pico-sdk//src/common/boot_picoboot_headers",
|
"@pico-sdk//src/common/boot_picoboot_headers",
|
||||||
"@pico-sdk//src/rp2_common/boot_bootrom_headers",
|
|
||||||
"@pico-sdk//src/rp2_common/pico_bootrom:pico_bootrom_headers",
|
"@pico-sdk//src/rp2_common/pico_bootrom:pico_bootrom_headers",
|
||||||
"@pico-sdk//src/rp2_common/pico_stdio_usb:reset_interface_headers",
|
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
|
@ -10,8 +10,7 @@
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
#include "picoboot_connection.h"
|
#include "picoboot_connection.h"
|
||||||
#include "boot/bootrom_constants.h"
|
#include "pico/bootrom_constants.h"
|
||||||
#include "pico/stdio_usb/reset_interface.h"
|
|
||||||
|
|
||||||
#if ENABLE_DEBUG_LOG
|
#if ENABLE_DEBUG_LOG
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -88,11 +87,7 @@ enum picoboot_device_result picoboot_open_device(libusb_device *device, libusb_d
|
||||||
case PRODUCT_ID_PICOPROBE:
|
case PRODUCT_ID_PICOPROBE:
|
||||||
return dr_vidpid_picoprobe;
|
return dr_vidpid_picoprobe;
|
||||||
case PRODUCT_ID_RP2040_STDIO_USB:
|
case PRODUCT_ID_RP2040_STDIO_USB:
|
||||||
*model = rp2040;
|
|
||||||
res = dr_vidpid_stdio_usb;
|
|
||||||
break;
|
|
||||||
case PRODUCT_ID_STDIO_USB:
|
case PRODUCT_ID_STDIO_USB:
|
||||||
*model = rp2350;
|
|
||||||
res = dr_vidpid_stdio_usb;
|
res = dr_vidpid_stdio_usb;
|
||||||
break;
|
break;
|
||||||
case PRODUCT_ID_RP2040_USBBOOT:
|
case PRODUCT_ID_RP2040_USBBOOT:
|
||||||
|
@ -120,15 +115,15 @@ enum picoboot_device_result picoboot_open_device(libusb_device *device, libusb_d
|
||||||
if (vid == 0 || strlen(ser) != 0) {
|
if (vid == 0 || strlen(ser) != 0) {
|
||||||
// didn't check vid or ser, so treat as unknown
|
// didn't check vid or ser, so treat as unknown
|
||||||
return dr_vidpid_unknown;
|
return dr_vidpid_unknown;
|
||||||
} else if (res == dr_vidpid_stdio_usb) {
|
} else if (res != dr_vidpid_unknown) {
|
||||||
return dr_vidpid_stdio_usb_cant_connect;
|
return res;
|
||||||
} else {
|
} else {
|
||||||
return dr_vidpid_bootrom_cant_connect;
|
return dr_vidpid_bootrom_cant_connect;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ret && res == dr_vidpid_stdio_usb) {
|
if (res == dr_vidpid_stdio_usb) {
|
||||||
if (strlen(ser) != 0) {
|
if (strlen(ser) != 0) {
|
||||||
// Check USB serial number
|
// Check USB serial number
|
||||||
char ser_str[128];
|
char ser_str[128];
|
||||||
|
@ -143,17 +138,6 @@ enum picoboot_device_result picoboot_open_device(libusb_device *device, libusb_d
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Runtime reset interface with thirdparty VID
|
|
||||||
if (!ret) {
|
|
||||||
for (int i = 0; i < config->bNumInterfaces; i++) {
|
|
||||||
if (config->interface[i].altsetting[0].bInterfaceClass == 0xff &&
|
|
||||||
config->interface[i].altsetting[0].bInterfaceSubClass == RESET_INTERFACE_SUBCLASS &&
|
|
||||||
config->interface[i].altsetting[0].bInterfaceProtocol == RESET_INTERFACE_PROTOCOL) {
|
|
||||||
return dr_vidpid_stdio_usb;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
if (config->bNumInterfaces == 1) {
|
if (config->bNumInterfaces == 1) {
|
||||||
interface = 0;
|
interface = 0;
|
||||||
|
@ -595,71 +579,36 @@ static const uint8_t picoboot_peek_cmd[] = {
|
||||||
};
|
};
|
||||||
#define PICOBOOT_PEEK_CMD_PROG_SIZE (size_t)(12 + 4)
|
#define PICOBOOT_PEEK_CMD_PROG_SIZE (size_t)(12 + 4)
|
||||||
|
|
||||||
// 00000000 <flash_get_unique_id_raw>:
|
// todo - compile this - currently taken from github PR #86
|
||||||
// 0: a002 add r0, pc, #8 @ (adr r0, c <FLASH_RUID_DATA_BYTES+0x4>)
|
static const size_t picoboot_flash_id_cmd_len = 152;
|
||||||
// 2: a106 add r1, pc, #24 @ (adr r1, 1c <FLASH_RUID_TOTAL_BYTES+0xf>)
|
static const uint8_t picoboot_flash_id_cmd[] = {
|
||||||
// 4: 4a00 ldr r2, [pc, #0] @ (8 <FLASH_RUID_DATA_BYTES>)
|
// void flash_get_unique_id(void)
|
||||||
// 6: e011 b.n 2c <flash_do_cmd>
|
0x02, 0xa0, 0x06, 0xa1, 0x00, 0x4a, 0x11, 0xe0,
|
||||||
// 8: 0000000d .word 0x0000000d
|
// int buflen
|
||||||
// c: 0000004b .word 0x0000004b
|
0x0d, 0x00, 0x00, 0x00,
|
||||||
// ...
|
// char txbuf[13]
|
||||||
//
|
0x4b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
// 0000002c <flash_do_cmd>:
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
// 2c: 2380 movs r3, #128 @ 0x80
|
// char rxbuf[13]
|
||||||
// 2e: b5f0 push {r4, r5, r6, r7, lr}
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
// 30: 4e17 ldr r6, [pc, #92] @ (90 <FLASH_RUID_CMD+0x45>)
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
// 32: 009b lsls r3, r3, #2
|
// void flash_do_cmd(txbuf, rxbuf, buflen)
|
||||||
// 34: 6834 ldr r4, [r6, #0]
|
0x80, 0x23, 0xf0, 0xb5, 0x17, 0x4e, 0x9b, 0x00,
|
||||||
// 36: 4063 eors r3, r4
|
0x34, 0x68, 0x63, 0x40, 0xc0, 0x24, 0xa4, 0x00,
|
||||||
// 38: 24c0 movs r4, #192 @ 0xc0
|
0x23, 0x40, 0x15, 0x4c, 0x23, 0x60, 0xc0, 0x24,
|
||||||
// 3a: 00a4 lsls r4, r4, #2
|
0x13, 0x00, 0x64, 0x05, 0x17, 0x00, 0x1f, 0x43,
|
||||||
// 3c: 4023 ands r3, r4
|
0x06, 0xd1, 0xc0, 0x23, 0x32, 0x68, 0x9b, 0x00,
|
||||||
// 3e: 4c15 ldr r4, [pc, #84] @ (94 <FLASH_RUID_CMD+0x49>)
|
0x93, 0x43, 0x0f, 0x4a, 0x13, 0x60, 0xf0, 0xbd,
|
||||||
// 40: 6023 str r3, [r4, #0]
|
0x08, 0x25, 0xa7, 0x6a, 0x3d, 0x40, 0xac, 0x46,
|
||||||
// 42: 24c0 movs r4, #192 @ 0xc0
|
0x02, 0x25, 0x2f, 0x42, 0x08, 0xd0, 0x00, 0x2a,
|
||||||
// 44: 0013 movs r3, r2
|
0x06, 0xd0, 0x9f, 0x1a, 0x0d, 0x2f, 0x03, 0xd8,
|
||||||
// 46: 0564 lsls r4, r4, #21
|
0x07, 0x78, 0x01, 0x3a, 0x27, 0x66, 0x01, 0x30,
|
||||||
// 48: 0017 movs r7, r2
|
0x65, 0x46, 0x00, 0x2d, 0xe2, 0xd0, 0x00, 0x2b,
|
||||||
// 4a: 431f orrs r7, r3
|
0xe0, 0xd0, 0x27, 0x6e, 0x01, 0x3b, 0x0f, 0x70,
|
||||||
// 4c: d106 bne.n 5c <FLASH_RUID_CMD+0x11>
|
0x01, 0x31, 0xdb, 0xe7, 0x0c, 0x80, 0x01, 0x40,
|
||||||
// 4e: 23c0 movs r3, #192 @ 0xc0
|
0x0c, 0x90, 0x01, 0x40,
|
||||||
// 50: 6832 ldr r2, [r6, #0]
|
};
|
||||||
// 52: 009b lsls r3, r3, #2
|
#define PICOBOOT_FLASH_ID_CMD_PROG_SIZE (size_t)(152)
|
||||||
// 54: 4393 bics r3, r2
|
|
||||||
// 56: 4a0f ldr r2, [pc, #60] @ (94 <FLASH_RUID_CMD+0x49>)
|
|
||||||
// 58: 6013 str r3, [r2, #0]
|
|
||||||
// 5a: bdf0 pop {r4, r5, r6, r7, pc}
|
|
||||||
// 5c: 2508 movs r5, #8
|
|
||||||
// 5e: 6aa7 ldr r7, [r4, #40] @ 0x28
|
|
||||||
// 60: 403d ands r5, r7
|
|
||||||
// 62: 46ac mov ip, r5
|
|
||||||
// 64: 2502 movs r5, #2
|
|
||||||
// 66: 422f tst r7, r5
|
|
||||||
// 68: d008 beq.n 7c <FLASH_RUID_CMD+0x31>
|
|
||||||
// 6a: 2a00 cmp r2, #0
|
|
||||||
// 6c: d006 beq.n 7c <FLASH_RUID_CMD+0x31>
|
|
||||||
// 6e: 1a9f subs r7, r3, r2
|
|
||||||
// 70: 2f0d cmp r7, #13
|
|
||||||
// 72: d803 bhi.n 7c <FLASH_RUID_CMD+0x31>
|
|
||||||
// 74: 7807 ldrb r7, [r0, #0]
|
|
||||||
// 76: 3a01 subs r2, #1
|
|
||||||
// 78: 6627 str r7, [r4, #96] @ 0x60
|
|
||||||
// 7a: 3001 adds r0, #1
|
|
||||||
// 7c: 4665 mov r5, ip
|
|
||||||
// 7e: 2d00 cmp r5, #0
|
|
||||||
// 80: d0e2 beq.n 48 <flash_do_cmd+0x1c>
|
|
||||||
// 82: 2b00 cmp r3, #0
|
|
||||||
// 84: d0e0 beq.n 48 <flash_do_cmd+0x1c>
|
|
||||||
// 86: 6e27 ldr r7, [r4, #96] @ 0x60
|
|
||||||
// 88: 3b01 subs r3, #1
|
|
||||||
// 8a: 700f strb r7, [r1, #0]
|
|
||||||
// 8c: 3101 adds r1, #1
|
|
||||||
// 8e: e7db b.n 48 <flash_do_cmd+0x1c>
|
|
||||||
// 90: 4001800c .word 0x4001800c
|
|
||||||
// 94: 4001900c .word 0x4001900c
|
|
||||||
|
|
||||||
#include "flash_id_bin.h"
|
|
||||||
#define PICOBOOT_FLASH_ID_CMD_PROG_SIZE (const size_t)(152)
|
|
||||||
|
|
||||||
// TODO better place for this e.g. the USB DPRAM location the controller has already put it in
|
// TODO better place for this e.g. the USB DPRAM location the controller has already put it in
|
||||||
#define PEEK_POKE_CODE_LOC 0x20000000u
|
#define PEEK_POKE_CODE_LOC 0x20000000u
|
||||||
|
@ -698,11 +647,10 @@ int picoboot_peek(libusb_device_handle *usb_device, uint32_t addr, uint32_t *dat
|
||||||
|
|
||||||
int picoboot_flash_id(libusb_device_handle *usb_device, uint64_t *data) {
|
int picoboot_flash_id(libusb_device_handle *usb_device, uint64_t *data) {
|
||||||
picoboot_exclusive_access(usb_device, 1);
|
picoboot_exclusive_access(usb_device, 1);
|
||||||
assert(PICOBOOT_FLASH_ID_CMD_PROG_SIZE == flash_id_bin_SIZE);
|
|
||||||
uint8_t prog[PICOBOOT_FLASH_ID_CMD_PROG_SIZE];
|
uint8_t prog[PICOBOOT_FLASH_ID_CMD_PROG_SIZE];
|
||||||
uint64_t id;
|
uint64_t id;
|
||||||
output("GET FLASH ID\n");
|
output("GET FLASH ID\n");
|
||||||
memcpy(prog, flash_id_bin, flash_id_bin_SIZE);
|
memcpy(prog, picoboot_flash_id_cmd, picoboot_flash_id_cmd_len);
|
||||||
|
|
||||||
// ensure XIP is exited before executing
|
// ensure XIP is exited before executing
|
||||||
int ret = picoboot_exit_xip(usb_device);
|
int ret = picoboot_exit_xip(usb_device);
|
||||||
|
|
|
@ -38,7 +38,6 @@ enum picoboot_device_result {
|
||||||
dr_vidpid_unknown,
|
dr_vidpid_unknown,
|
||||||
dr_error,
|
dr_error,
|
||||||
dr_vidpid_stdio_usb,
|
dr_vidpid_stdio_usb,
|
||||||
dr_vidpid_stdio_usb_cant_connect,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -81,9 +80,6 @@ int picoboot_flash_id(libusb_device_handle *usb_device, uint64_t *data);
|
||||||
|
|
||||||
// we require 256 (as this is the page size supported by the device)
|
// we require 256 (as this is the page size supported by the device)
|
||||||
#define LOG2_PAGE_SIZE 8u
|
#define LOG2_PAGE_SIZE 8u
|
||||||
#ifdef PAGE_SIZE
|
|
||||||
#undef PAGE_SIZE
|
|
||||||
#endif
|
|
||||||
#define PAGE_SIZE (1u << LOG2_PAGE_SIZE)
|
#define PAGE_SIZE (1u << LOG2_PAGE_SIZE)
|
||||||
#define FLASH_SECTOR_ERASE_SIZE 4096u
|
#define FLASH_SECTOR_ERASE_SIZE 4096u
|
||||||
|
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
package(default_visibility = ["//visibility:public"])
|
|
||||||
|
|
||||||
filegroup(
|
|
||||||
name = "picoboot_flash_id_prebuilt",
|
|
||||||
srcs = ["flash_id.bin"],
|
|
||||||
)
|
|
||||||
|
|
||||||
# TODO: Make it possible to build flash_id.bin from source.
|
|
|
@ -1,36 +0,0 @@
|
||||||
cmake_minimum_required(VERSION 3.12)
|
|
||||||
|
|
||||||
if (NOT USE_PRECOMPILED)
|
|
||||||
set(PICO_NO_PICOTOOL 1)
|
|
||||||
|
|
||||||
# default build type
|
|
||||||
set(CMAKE_BUILD_TYPE "MinSizeRel" CACHE STRING "build type")
|
|
||||||
|
|
||||||
# If the user set these environment variables to influence the picotool
|
|
||||||
# build, unset them here so that they do not influence the pico-sdk
|
|
||||||
# build. This is especially required for flags that are not supported
|
|
||||||
# by arm-none-eabi compilers.
|
|
||||||
unset(ENV{CFLAGS})
|
|
||||||
unset(ENV{CXXFLAGS})
|
|
||||||
unset(ENV{LDFLAGS})
|
|
||||||
|
|
||||||
include(${PICO_SDK_PATH}/external/pico_sdk_import.cmake)
|
|
||||||
project(flash_id C CXX ASM)
|
|
||||||
pico_sdk_init()
|
|
||||||
|
|
||||||
add_executable(flash_id flash_id.c)
|
|
||||||
target_link_libraries(flash_id PRIVATE
|
|
||||||
hardware_regs hardware_structs hardware_flash_headers
|
|
||||||
)
|
|
||||||
target_link_options(flash_id PRIVATE -nostartfiles -nodefaultlibs -Ttext=0)
|
|
||||||
pico_add_bin_output(flash_id)
|
|
||||||
pico_add_dis_output(flash_id)
|
|
||||||
else()
|
|
||||||
project(flash_id C CXX ASM)
|
|
||||||
message("Using precompiled flash_id.bin")
|
|
||||||
configure_file(${CMAKE_CURRENT_LIST_DIR}/flash_id.bin ${CMAKE_CURRENT_BINARY_DIR}/flash_id.bin COPYONLY)
|
|
||||||
# Use manually specified variables
|
|
||||||
set(NULL ${CMAKE_MAKE_PROGRAM})
|
|
||||||
set(NULL ${PICO_SDK_PATH})
|
|
||||||
set(NULL ${PICO_DEBUG_INFO_IN_RELEASE})
|
|
||||||
endif()
|
|
Binary file not shown.
|
@ -1,70 +0,0 @@
|
||||||
#include "hardware/regs/io_qspi.h"
|
|
||||||
#include "hardware/structs/ioqspi.h"
|
|
||||||
#include "hardware/structs/ssi.h"
|
|
||||||
#include "hardware/flash.h"
|
|
||||||
|
|
||||||
asm(
|
|
||||||
".macro static_assert value, msg\n"
|
|
||||||
".if !(\\value)\n"
|
|
||||||
".err \\msg\n"
|
|
||||||
".endif\n"
|
|
||||||
".endm\n"
|
|
||||||
|
|
||||||
".set FLASH_RUID_CMD, 0x4b\n"
|
|
||||||
".set FLASH_RUID_DUMMY_BYTES, 4\n"
|
|
||||||
".set FLASH_RUID_DATA_BYTES, 8\n"
|
|
||||||
".set FLASH_RUID_TOTAL_BYTES, (1 + FLASH_RUID_DUMMY_BYTES + FLASH_RUID_DATA_BYTES)\n"
|
|
||||||
);
|
|
||||||
|
|
||||||
void flash_do_cmd(const uint8_t * txbuf, uint8_t *rxbuf, size_t count);
|
|
||||||
void __attribute__((naked)) flash_get_unique_id_raw(void) {
|
|
||||||
asm(
|
|
||||||
".Lflash_get_unique_id_raw:\n"
|
|
||||||
"adr r0, .Ltxbuf\n"
|
|
||||||
"adr r1, .Lrxbuf\n"
|
|
||||||
"ldr r2, .Lbuflen\n"
|
|
||||||
"b flash_do_cmd\n"
|
|
||||||
".Lbuflen:\n"
|
|
||||||
".word FLASH_RUID_TOTAL_BYTES\n"
|
|
||||||
".Ltxbuf:\n"
|
|
||||||
".byte FLASH_RUID_CMD\n"
|
|
||||||
".zero (FLASH_RUID_TOTAL_BYTES - 1)\n"
|
|
||||||
".zero (16 - FLASH_RUID_TOTAL_BYTES)\n"
|
|
||||||
".Lrxbuf:\n"
|
|
||||||
".zero FLASH_RUID_TOTAL_BYTES\n"
|
|
||||||
".zero (16 - FLASH_RUID_TOTAL_BYTES)\n"
|
|
||||||
"static_assert ((.Lrxbuf - flash_get_unique_id_raw) == 28), \"rxbuf offset incorrect\"\n"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void __attribute__((always_inline)) flash_cs_force(_Bool high) {
|
|
||||||
uint32_t field_val = high ?
|
|
||||||
IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_VALUE_HIGH :
|
|
||||||
IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_VALUE_LOW;
|
|
||||||
hw_write_masked(&ioqspi_hw->io[1].ctrl,
|
|
||||||
field_val << IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_LSB,
|
|
||||||
IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_BITS
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void flash_do_cmd(const uint8_t * txbuf, uint8_t *rxbuf, size_t count) {
|
|
||||||
flash_cs_force(0);
|
|
||||||
size_t tx_remaining = count;
|
|
||||||
size_t rx_remaining = count;
|
|
||||||
// We may be interrupted -- don't want FIFO to overflow if we're distracted.
|
|
||||||
const size_t max_in_flight = 16 - 2;
|
|
||||||
while (tx_remaining || rx_remaining) {
|
|
||||||
uint32_t flags = ssi_hw->sr;
|
|
||||||
bool can_put = !!(flags & SSI_SR_TFNF_BITS);
|
|
||||||
bool can_get = !!(flags & SSI_SR_RFNE_BITS);
|
|
||||||
if (can_put && tx_remaining && rx_remaining - tx_remaining < max_in_flight) {
|
|
||||||
ssi_hw->dr0 = *txbuf++;
|
|
||||||
--tx_remaining;
|
|
||||||
}
|
|
||||||
if (can_get && rx_remaining) {
|
|
||||||
*rxbuf++ = (uint8_t)ssi_hw->dr0;
|
|
||||||
--rx_remaining;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
flash_cs_force(1);
|
|
||||||
}
|
|
|
@ -1,5 +1,4 @@
|
||||||
{
|
{
|
||||||
"$schema": "https://raw.githubusercontent.com/raspberrypi/picotool/develop/json/schemas/permissions-schema.json",
|
|
||||||
"10": {
|
"10": {
|
||||||
"no_key_state": 0,
|
"no_key_state": 0,
|
||||||
"key_r": 0,
|
"key_r": 0,
|
|
@ -1,5 +1,4 @@
|
||||||
{
|
{
|
||||||
"$schema": "https://raw.githubusercontent.com/raspberrypi/picotool/develop/json/schemas/whitelabel-schema.json",
|
|
||||||
"device": {
|
"device": {
|
||||||
"vid": "0x2e8b",
|
"vid": "0x2e8b",
|
||||||
"pid": "0x000e",
|
"pid": "0x000e",
|
|
@ -1,53 +1,42 @@
|
||||||
cmake_minimum_required(VERSION 3.12)
|
cmake_minimum_required(VERSION 3.12)
|
||||||
|
|
||||||
if (NOT USE_PRECOMPILED)
|
if (NOT USE_PRECOMPILED)
|
||||||
set(PICO_PLATFORM rp2350-arm-s)
|
set(PICO_PLATFORM rp2350-arm-s)
|
||||||
|
|
||||||
set(PICO_NO_PICOTOOL 1)
|
# Pull in SDK (must be before project)
|
||||||
|
include(pico_sdk_import.cmake)
|
||||||
|
|
||||||
# If the user set these environment variables to influence the picotool
|
project(xip_ram_perms C CXX ASM)
|
||||||
# build, unset them here so that they do not influence the pico-sdk
|
set(CMAKE_C_STANDARD 11)
|
||||||
# build. This is especially required for flags that are not supported
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
# by arm-none-eabi compilers.
|
|
||||||
unset(ENV{CFLAGS})
|
|
||||||
unset(ENV{CXXFLAGS})
|
|
||||||
unset(ENV{LDFLAGS})
|
|
||||||
|
|
||||||
# Pull in SDK (must be before project)
|
if (PICO_SDK_VERSION_STRING VERSION_LESS "2.0.0")
|
||||||
include(${PICO_SDK_PATH}/external/pico_sdk_import.cmake)
|
message(FATAL_ERROR "Raspberry Pi Pico SDK version 2.0.0 (or later) required. Your version is ${PICO_SDK_VERSION_STRING}")
|
||||||
|
endif()
|
||||||
|
|
||||||
project(xip_ram_perms C CXX ASM)
|
# Initialize the SDK
|
||||||
set(CMAKE_C_STANDARD 11)
|
pico_sdk_init()
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
|
||||||
|
|
||||||
if (PICO_SDK_VERSION_STRING VERSION_LESS "2.0.0")
|
# XIP Ram OTP Perm Setter
|
||||||
message(FATAL_ERROR "Raspberry Pi Pico SDK version 2.0.0 (or later) required. Your version is ${PICO_SDK_VERSION_STRING}")
|
add_executable(xip_ram_perms
|
||||||
endif()
|
set_perms.c
|
||||||
|
)
|
||||||
|
|
||||||
# Initialize the SDK
|
target_link_libraries(xip_ram_perms
|
||||||
pico_sdk_init()
|
pico_stdlib
|
||||||
|
)
|
||||||
|
|
||||||
# XIP Ram OTP Perm Setter
|
pico_set_binary_type(xip_ram_perms no_flash)
|
||||||
add_executable(xip_ram_perms
|
# create linker script to run from 0x20070000
|
||||||
set_perms.c
|
file(READ ${PICO_LINKER_SCRIPT_PATH}/memmap_no_flash.ld LINKER_SCRIPT)
|
||||||
)
|
string(REPLACE "RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 512k" "RAM(rwx) : ORIGIN = 0x13ffc000, LENGTH = 16k" LINKER_SCRIPT "${LINKER_SCRIPT}")
|
||||||
|
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/memmap_xip_ram.ld "${LINKER_SCRIPT}")
|
||||||
target_link_libraries(xip_ram_perms
|
pico_set_linker_script(xip_ram_perms ${CMAKE_CURRENT_BINARY_DIR}/memmap_xip_ram.ld)
|
||||||
pico_stdlib
|
|
||||||
)
|
|
||||||
|
|
||||||
pico_set_binary_type(xip_ram_perms no_flash)
|
|
||||||
# create linker script to run from 0x20070000
|
|
||||||
file(READ ${PICO_LINKER_SCRIPT_PATH}/memmap_no_flash.ld LINKER_SCRIPT)
|
|
||||||
string(REPLACE "RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 512k" "RAM(rwx) : ORIGIN = 0x13ffc000, LENGTH = 16k" LINKER_SCRIPT "${LINKER_SCRIPT}")
|
|
||||||
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/memmap_xip_ram.ld "${LINKER_SCRIPT}")
|
|
||||||
pico_set_linker_script(xip_ram_perms ${CMAKE_CURRENT_BINARY_DIR}/memmap_xip_ram.ld)
|
|
||||||
else()
|
else()
|
||||||
project(xip_ram_perms C CXX ASM)
|
project(xip_ram_perms C CXX ASM)
|
||||||
message("Using precompiled xip_ram_perms.elf")
|
message("Using precompiled xip_ram_perms.elf")
|
||||||
configure_file(${CMAKE_CURRENT_LIST_DIR}/xip_ram_perms.elf ${CMAKE_CURRENT_BINARY_DIR}/xip_ram_perms.elf COPYONLY)
|
configure_file(${CMAKE_CURRENT_LIST_DIR}/xip_ram_perms.elf ${CMAKE_CURRENT_BINARY_DIR}/xip_ram_perms.elf COPYONLY)
|
||||||
# Use manually specified variables
|
# Use manually specified variables
|
||||||
set(NULL ${CMAKE_MAKE_PROGRAM})
|
set(NULL ${CMAKE_MAKE_PROGRAM})
|
||||||
set(NULL ${PICO_SDK_PATH})
|
set(NULL ${PICO_SDK_PATH})
|
||||||
set(NULL ${PICO_DEBUG_INFO_IN_RELEASE})
|
|
||||||
endif()
|
endif()
|
||||||
|
|
62
xip_ram_perms/pico_sdk_import.cmake
Normal file
62
xip_ram_perms/pico_sdk_import.cmake
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
# This is a copy of <PICO_SDK_PATH>/external/pico_sdk_import.cmake
|
||||||
|
|
||||||
|
# This can be dropped into an external project to help locate this SDK
|
||||||
|
# It should be include()ed prior to project()
|
||||||
|
|
||||||
|
if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH))
|
||||||
|
set(PICO_SDK_PATH $ENV{PICO_SDK_PATH})
|
||||||
|
message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT))
|
||||||
|
set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT})
|
||||||
|
message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH))
|
||||||
|
set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH})
|
||||||
|
message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK")
|
||||||
|
set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable")
|
||||||
|
set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK")
|
||||||
|
|
||||||
|
if (NOT PICO_SDK_PATH)
|
||||||
|
if (PICO_SDK_FETCH_FROM_GIT)
|
||||||
|
include(FetchContent)
|
||||||
|
set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR})
|
||||||
|
if (PICO_SDK_FETCH_FROM_GIT_PATH)
|
||||||
|
get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}")
|
||||||
|
endif ()
|
||||||
|
FetchContent_Declare(
|
||||||
|
pico_sdk
|
||||||
|
GIT_REPOSITORY git@asic-git.pitowers.org:amethyst/pico-sdk.git
|
||||||
|
GIT_TAG use-picotool
|
||||||
|
)
|
||||||
|
if (NOT pico_sdk)
|
||||||
|
message("Downloading Raspberry Pi Pico SDK")
|
||||||
|
FetchContent_Populate(pico_sdk)
|
||||||
|
set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR})
|
||||||
|
endif ()
|
||||||
|
set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE})
|
||||||
|
else ()
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git."
|
||||||
|
)
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}")
|
||||||
|
if (NOT EXISTS ${PICO_SDK_PATH})
|
||||||
|
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake)
|
||||||
|
if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE})
|
||||||
|
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE)
|
||||||
|
|
||||||
|
include(${PICO_SDK_INIT_CMAKE_FILE})
|
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue