diff --git a/.bazelignore b/.bazelignore
deleted file mode 100644
index dd2e8d2..0000000
--- a/.bazelignore
+++ /dev/null
@@ -1 +0,0 @@
-lib/pico-sdk
diff --git a/.github/workflows/bazel_build.yml b/.github/workflows/bazel_build.yml
deleted file mode 100644
index 2e775c7..0000000
--- a/.github/workflows/bazel_build.yml
+++ /dev/null
@@ -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
diff --git a/.github/workflows/choco_packages.config b/.github/workflows/choco_packages.config
deleted file mode 100644
index b2d3db1..0000000
--- a/.github/workflows/choco_packages.config
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
deleted file mode 100644
index 85decb5..0000000
--- a/.github/workflows/test.yml
+++ /dev/null
@@ -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
diff --git a/BUILD.bazel b/BUILD.bazel
index d120f50..2bc5b2a 100644
--- a/BUILD.bazel
+++ b/BUILD.bazel
@@ -2,8 +2,6 @@ load("//bazel:defs.bzl", "otp_header_parse", "picotool_binary_data_header")
package(default_visibility = ["//visibility:public"])
-PICOTOOL_SDK_VERSION_STRING = module_version() if module_version() != None else "0.0.1-WORKSPACE"
-
picotool_binary_data_header(
name = "rp2350_rom",
src = "bootrom.end.bin",
@@ -17,13 +15,6 @@ picotool_binary_data_header(
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(
name = "xip_ram_perms",
srcs = ["xip_ram_perms.cpp"],
@@ -46,10 +37,6 @@ otp_header_parse(
name = "otp_header",
src = "@pico-sdk//src/rp2350/hardware_regs:otp_data_header",
out = "rp2350.json.h",
- target_compatible_with = select({
- "@rules_cc//cc/compiler:msvc-cl": ["@platforms//:incompatible"],
- "//conditions:default": [],
- }),
)
cc_binary(
@@ -60,14 +47,10 @@ cc_binary(
"main.cpp",
"otp.cpp",
"otp.h",
+ "rp2350.json.h",
"rp2350.rom.h",
"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({
"@rules_cc//cc/compiler:msvc-cl": [
"/std:c++20",
@@ -81,7 +64,8 @@ cc_binary(
],
}),
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\\"',
'COMPILER_INFO=\\"local\\"',
"SUPPORT_A0=0",
@@ -114,10 +98,5 @@ cc_binary(
"@pico-sdk//src/rp2350/hardware_regs:otp_data",
"@pico-sdk//src/rp2_common/pico_bootrom:pico_bootrom_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": [],
- }),
+ ],
)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index adb47ae..d75982e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -35,7 +35,7 @@ if (PICOTOOL_FLAT_INSTALL)
set(INSTALL_DATADIR picotool)
set(INSTALL_BINDIR picotool)
else()
- set(INSTALL_CONFIGDIR lib/cmake/picotool)
+ set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/picotool)
set(INSTALL_DATADIR ${CMAKE_INSTALL_DATADIR}/picotool)
set(INSTALL_BINDIR ${CMAKE_INSTALL_BINDIR})
endif()
@@ -70,7 +70,6 @@ if (NOT PICOTOOL_NO_LIBUSB)
"-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 ""
)
@@ -85,30 +84,6 @@ if (NOT PICOTOOL_NO_LIBUSB)
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.
ExternalProject_Add(otp_header_parser
PREFIX otp_header_parser
@@ -169,10 +144,7 @@ if (NOT PICOTOOL_NO_LIBUSB)
endif()
endif()
-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}/flash_id_bin.h)
+add_custom_target(binary_data DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/rp2350.rom.h ${CMAKE_CURRENT_BINARY_DIR}/xip_ram_perms_elf.h)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/rp2350.rom.h
COMMAND ${CMAKE_COMMAND}
-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
COMMENT "Configuring xip_ram_perms_elf.h"
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)
@@ -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_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/rp2_common/boot_bootrom_headers boot_bootrom_headers)
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)
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)
add_dependencies(picotool generate_otp_header xip_ram_perms_elf binary_data)
endif()
-set(PROJECT_VERSION 2.1.0)
-set(PICOTOOL_VERSION 2.1.0)
+set(PROJECT_VERSION 2.0.0)
+set(PICOTOOL_VERSION 2.0.0)
set(SYSTEM_VERSION "${CMAKE_SYSTEM_NAME}")
set(COMPILER_INFO "${CMAKE_C_COMPILER_ID}-${CMAKE_C_COMPILER_VERSION}, ${CMAKE_BUILD_TYPE}")
target_compile_definitions(picotool PRIVATE
@@ -259,7 +224,7 @@ target_link_libraries(picotool
boot_uf2_headers
boot_picoboot_headers
boot_picobin_headers
- boot_bootrom_headers
+ pico_bootrom_headers
pico_platform_headers
pico_usb_reset_interface_headers
regs_headers
@@ -277,11 +242,7 @@ else()
endif()
if (NOT LIBUSB_FOUND)
- if (PICOTOOL_NO_LIBUSB)
- 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()
+ message("libUSB is not found - no USB support will be built")
target_compile_definitions(picotool PRIVATE HAS_LIBUSB=0)
target_link_libraries(picotool
picoboot_connection_header)
diff --git a/MODULE.bazel b/MODULE.bazel
index eedd667..2c22158 100644
--- a/MODULE.bazel
+++ b/MODULE.bazel
@@ -1,10 +1,10 @@
module(
name = "picotool",
- version = "2.1.0",
+ version = "2.0.0",
)
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 = "bazel_skylib", version = "1.6.1")
bazel_dep(name = "rules_python", version = "0.22.1")
diff --git a/README.md b/README.md
index 625259f..29231b9 100644
--- a/README.md
+++ b/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
```
-> If libusb-1.0-0-dev is not installed, picotool still builds, but it omits all options that deal with managing a pico via USB (load, save, erase, verify, reboot). Builds that do not include USB support can be recognized because these commands also do not appear in the help command. The build output message 'libUSB is not found - no USB support will be built' also appears in the build logs.
-
Then simply build like a normal CMake project:
```console
@@ -68,33 +66,32 @@ No need to download libusb separately or set `LIBUSB_ROOT`.
pacman -S $MINGW_PACKAGE_PREFIX-{toolchain,cmake,libusb}
mkdir build
cd build
-cmake .. -DCMAKE_INSTALL_PREFIX=$MINGW_PREFIX
-cmake --build .
+MSYS2_ARG_CONV_EXCL=- cmake .. -G"MSYS Makefiles" -DCMAKE_INSTALL_PREFIX=$MINGW_PREFIX
+make
+make install DESTDIR=/ # optional
```
## 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
-> ```console
-> cmake -DCMAKE_INSTALL_PREFIX=~/.local ..
-> make install
-> ```
-> This will only work if `~/.local` is included in your `PATH`
+This can be done most simply with `make install`; the SDK will use this installed version by default.
-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 ..
-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
@@ -105,23 +102,20 @@ Note for additional documentation see https://rptl.io/pico-get-started
```
$ picotool help
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:
- picotool info [-b] [-m] [-p] [-d] [--debug] [-l] [-a] [device-selection]
- picotool info [-b] [-m] [-p] [-d] [--debug] [-l] [-a] [-t ]
+ picotool info [-b] [-p] [-d] [--debug] [-l] [-a] [device-selection]
+ picotool info [-b] [-p] [-d] [--debug] [-l] [-a] [-t ]
picotool config [-s ] [-g ] [device-selection]
picotool config [-s ] [-g ] [-t ]
- picotool load [--ignore-partitions] [--family ] [-p ] [-n] [-N] [-u] [-v] [-x] [-t ] [-o ] [device-selection]
+ picotool load [-p] [-n] [-N] [-u] [-v] [-x] [-t ] [-o ] [device-selection]
picotool encrypt [--quiet] [--verbose] [--hash] [--sign] [-t ] [-o ] [-t ] [-t ] [] [-t ]
picotool seal [--quiet] [--verbose] [--hash] [--sign] [--clear] [-t ] [-o ] [-t ] [] [-t ] [] [-t ] [--major ] [--minor ] [--rollback [..]]
picotool link [--quiet] [--verbose] [-t ] [-t ] [-t ] [] [-t ] [-p]
- picotool save [-p] [-v] [--family ] [device-selection]
- picotool save -a [-v] [--family ] [device-selection]
- picotool save -r [-v] [--family ] [device-selection]
- picotool erase [-a] [device-selection]
- picotool erase -p [device-selection]
- picotool erase -r [device-selection]
+ picotool save [-p] [device-selection]
+ picotool save -a [device-selection]
+ picotool save -r [device-selection]
picotool verify [device-selection]
picotool reboot [-a] [-u] [-g ] [-c ] [device-selection]
picotool otp list|get|set|load|dump|permissions|white-label
@@ -133,21 +127,20 @@ SYNOPSIS:
COMMANDS:
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.
load Load the program / memory range stored in a file onto the device.
encrypt Encrypt the program.
seal Add final metadata to a binary, optionally including a hash and/or signature.
link Link multiple binaries into one block loop.
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.
reboot Reboot the device
otp Commands related to the RP2350 OTP (One-Time-Programmable) Memory
partition Commands related to RP2350 Partition Tables
uf2 Commands related to UF2 creation and status
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
Use "picotool help " for more info
@@ -167,18 +160,16 @@ a file. This file can be an ELF, a UF2 or a BIN file.
$ picotool help info
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
SYNOPSIS:
- picotool info [-b] [-m] [-p] [-d] [--debug] [-l] [-a] [device-selection]
- picotool info [-b] [-m] [-p] [-d] [--debug] [-l] [-a] [-t ]
+ picotool info [-b] [-p] [-d] [--debug] [-l] [-a] [device-selection]
+ picotool info [-b] [-p] [-d] [--debug] [-l] [-a] [-t ]
OPTIONS:
Information to display
-b, --basic
Include basic information. This is the default
- -m, --metadata
- Include all metadata blocks
-p, --pins
Include pin information
-d, --device
@@ -191,7 +182,7 @@ OPTIONS:
Include all information
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
Filter devices by USB bus number
--address
@@ -299,7 +290,7 @@ OPTIONS:
Filter by feature group
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
Filter devices by USB bus number
--address
@@ -373,7 +364,7 @@ OPTIONS:
--family
Specify the family ID of the file to load
- family ID to use for load
+ family id to use for load
-p, --partition
Specify the partition to load into
@@ -437,9 +428,9 @@ SAVE:
Save the program / memory stored in flash on the device to a file.
SYNOPSIS:
- picotool save [-p] [-v] [--family ] [device-selection]
- picotool save -a [-v] [--family ] [device-selection]
- picotool save -r [-v] [--family ] [device-selection]
+ picotool save [-p] [device-selection]
+ picotool save -a [device-selection]
+ picotool save -r [device-selection]
OPTIONS:
Selection of data to save
@@ -454,13 +445,6 @@ OPTIONS:
The lower 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 to save file as
Source device selection
--bus
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
```
-## 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 ] [device-selection]
- picotool erase -r [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 number to erase
- -r, --range
- Erase a range of memory. Note that erases must be 4096 byte-aligned, so the range is expanded accordingly
-
- The lower address bound in hex
-
- The upper address bound in hex
- Source device selection
- --bus
- Filter devices by USB bus number
- --address
- Filter devices by USB device address
- --vid
- Filter by vendor id
- --pid
- Filter by product id
- --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` 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:
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
-Family ID 'rp2350-arm-s' can be downloaded in partition 0:
+Family id 'rp2350-arm-s' can be downloaded in partition 0:
00002000->00201000
```
### create
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
$ picotool help partition create
@@ -799,7 +694,7 @@ OPTIONS:
--family
Specify the family if for UF2 file output
- family ID for UF2 (default absolute)
+ family id for UF2 (default absolute)
embed partition table into bootloader ELF
The file name
@@ -814,7 +709,7 @@ OPTIONS:
Don't hash the partition table
--singleton
Singleton partition table
- Errata RP2350-E10 Fix
+ Errata RP2350-E9 Fix
--abs-block
Enforce support for an absolute block
@@ -823,7 +718,7 @@ OPTIONS:
## 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
@@ -860,8 +755,8 @@ OPTIONS:
Load offset (memory address; default 0x10000000 for BIN file)
UF2 Family options
- family ID for UF2
- Errata RP2350-E10 Fix
+ family id for UF2
+ Errata RP2350-E9 Fix
--abs-block
Add an absolute block
@@ -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.
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
$ picotool help otp
@@ -917,9 +812,9 @@ OTP:
Commands related to the RP2350 OTP (One-Time-Programmable) Memory
SYNOPSIS:
- picotool otp list [-p] [-n] [-f] [-i ] [..]
+ picotool otp list [-p] [-n] [-i ] [..]
picotool otp get [-c ] [-r] [-e] [-n] [-i ] [device-selection] [-z] [..]
- picotool otp set [-c ] [-r] [-e] [-s] [-i ] [-z] [device-selection]
+ picotool otp set [-c ] [-r] [-e] [-i ] [-z] [device-selection]
picotool otp load [-r] [-e] [-s ] [-i ] [-t ] [device-selection]
picotool otp dump [-r] [-e] [device-selection]
picotool otp permissions [-t ] [--led ] [--hash] [--sign] [] [-t ] [device-selection]
@@ -942,7 +837,7 @@ These commands will set/get specific rows of OTP. By default, they will write/re
### load
-This command allows loading of a range of OTP rows onto the device. The source can be a binary file, or a JSON file such as the one output by `picotool sign`. The schema for this JSON file is [here](json/schemas/otp-schema.json)
+This command allows loading of a range of OTP rows onto the device. The source can be a binary file, or a JSON file such as the one output by `picotool 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:
```text
$ picotool sign hello_world.elf hello_world.signed.elf private.pem otp.json
@@ -954,7 +849,7 @@ $ picotool reboot
### white-label
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
$ picotool help otp white-label
@@ -992,7 +887,7 @@ OPTIONS:
```
```text
-$ picotool otp white-label -s 0x100 sample-wl.json
+$ picotool otp white-label -s 0x100 ../sample-wl.json
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,
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.
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
-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
$ picotool help otp permissions
@@ -1083,7 +978,7 @@ OPTIONS:
```
```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
page10
page10 = 0
diff --git a/bazel/mbedtls.BUILD b/bazel/mbedtls.BUILD
index 1c9fa43..c3342b1 100644
--- a/bazel/mbedtls.BUILD
+++ b/bazel/mbedtls.BUILD
@@ -9,10 +9,10 @@ cc_library(
"library/*.h",
],
),
- includes = ["include"],
linkopts = select({
"@rules_cc//cc/compiler:msvc-cl": ["-DEFAULTLIB:AdvAPI32.Lib"],
"//conditions:default": [],
}),
+ includes = ["include"],
deps = ["@picotool//lib:mbedtls_config"],
)
diff --git a/bintool/BUILD.bazel b/bintool/BUILD.bazel
index a9f4961..82ede3b 100644
--- a/bintool/BUILD.bazel
+++ b/bintool/BUILD.bazel
@@ -12,7 +12,6 @@ cc_library(
"metadata.h",
],
copts = select({
- "@rules_cc//cc/compiler:msvc-cl": ["/std:c++20"],
"@platforms//os:windows": [],
"//conditions:default": [
"-Wno-unused-variable",
diff --git a/bintool/bintool.cpp b/bintool/bintool.cpp
index c8fa8dc..c5462d2 100644
--- a/bintool/bintool.cpp
+++ b/bintool/bintool.cpp
@@ -453,120 +453,6 @@ block place_new_block(std::vector &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 bin) {
- assert(bin.size() == 252);
-
- uint32_t checksum = 0;
- crc32(bin.data(), bin.size(), &checksum);
-
- return checksum;
-}
-
-
#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 to_hash) {
std::shared_ptr hash_def = std::make_shared(PICOBIN_HASH_SHA256);
@@ -668,29 +554,21 @@ std::vector get_lm_hash_data(elf_file *elf, block *new_block, bool clea
for(const auto &entry : load_map->entries) {
std::vector data;
uint32_t current_storage_address = entry.storage_address;
- if (current_storage_address == 0) {
- std::copy(
- (uint8_t*)&entry.size,
- (uint8_t*)&entry.size + sizeof(entry.size),
- 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();
+ 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);
}
- 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());
+ 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);
+ 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 get_lm_hash_data(std::vector bin, uint32_t storage
(uint8_t*)&entry.size,
(uint8_t*)&entry.size + sizeof(entry.size),
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 {
uint32_t rel_addr = entry.storage_address - storage_addr;
std::copy(
diff --git a/bintool/bintool.h b/bintool/bintool.h
index 77e89c8..b2c6499 100644
--- a/bintool/bintool.h
+++ b/bintool/bintool.h
@@ -34,7 +34,6 @@ std::unique_ptr find_first_block(std::vector bin, uint32_t stora
std::unique_ptr get_last_block(std::vector &bin, uint32_t storage_addr, std::unique_ptr &first_block, get_more_bin_cb more_cb = nullptr);
std::vector> get_all_blocks(std::vector &bin, uint32_t storage_addr, std::unique_ptr &first_block, get_more_bin_cb more_cb = nullptr);
block place_new_block(std::vector &bin, uint32_t storage_addr, std::unique_ptr &first_block);
-uint32_t calc_checksum(std::vector bin);
#if HAS_MBEDTLS
std::vector hash_andor_sign(std::vector 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 encrypt(std::vector 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);
diff --git a/bintool/metadata.h b/bintool/metadata.h
index 605bf63..2a3d6cb 100644
--- a/bintool/metadata.h
+++ b/bintool/metadata.h
@@ -225,55 +225,8 @@ struct partition_table_item : public single_byte_size_item {
partition_table_item() = default;
explicit partition_table_item(uint32_t unpartitioned_flags, bool singleton) : unpartitioned_flags(unpartitioned_flags), singleton(singleton) {}
- template static std::shared_ptr- parse(I& it, I end, uint32_t header) {
- uint32_t size = decode_size(header);
- 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(unpartitioned_flags, singleton);
-
- std::vector 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;
+ template static std::shared_ptr
- parse(I it, I end, uint32_t header) {
+ return nullptr;
}
std::vector to_words(item_writer_context& ctx) const override {
@@ -414,11 +367,7 @@ struct load_map_item : public item {
if (absolute) {
rc.push_back(entry.storage_address);
rc.push_back(entry.runtime_address);
- if (entry.storage_address != 0) {
- rc.push_back(entry.runtime_address + entry.size);
- } else {
- rc.push_back(entry.size);
- }
+ rc.push_back(entry.runtime_address + entry.size);
} else {
if (entry.storage_address != 0) {
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);
break;
case PICOBIN_BLOCK_ITEM_PARTITION_TABLE:
- i = partition_table_item::parse(it, end, header);
+ i = ignored_item::parse(it, end, header);
break;
case PICOBIN_BLOCK_ITEM_1BS_VECTOR_TABLE:
i = vector_table_item::parse(it, end, header);
diff --git a/cli.h b/cli.h
index 6db9b4f..1bc766b 100644
--- a/cli.h
+++ b/cli.h
@@ -432,18 +432,13 @@ namespace cli {
base = 2;
}
try {
- if (std::is_signed()) {
- lvalue = std::stoll(value, &pos, base);
- } else {
- lvalue = std::stoull(value, &pos, base);
- }
+ lvalue = std::stoll(value, &pos, base);
if (pos != value.length()) {
return "Garbage after integer value: " + value.substr(pos);
}
} catch (std::invalid_argument&) {
return value + " is not a valid integer";
} catch (std::out_of_range&) {
- return value + " is out of range";
}
if (lvalue != (int64_t)lvalue) {
return value + " is too big";
diff --git a/cmake/FindLIBUSB.cmake b/cmake/FindLIBUSB.cmake
index e5defef..ab0d303 100644
--- a/cmake/FindLIBUSB.cmake
+++ b/cmake/FindLIBUSB.cmake
@@ -25,9 +25,7 @@ else (LIBUSB_INCLUDE_DIR AND LIBUSB_LIBRARIES)
if (PKG_CONFIG_FOUND)
pkg_check_modules(PC_LIBUSB libusb-1.0)
- endif()
-
- if (NOT PC_LIBUSB_FOUND)
+ else ()
# As the pkg-config was not found we are probably building under windows.
# Determine the architecture of the host, to choose right library
if (NOT DEFINED ARCHITECTURE)
@@ -58,10 +56,5 @@ else (LIBUSB_INCLUDE_DIR AND LIBUSB_LIBRARIES)
include(FindPackageHandleStandardArgs)
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)
endif (LIBUSB_INCLUDE_DIR AND LIBUSB_LIBRARIES)
diff --git a/default-pt.json b/default-pt.json
new file mode 100644
index 0000000..b057d7a
--- /dev/null
+++ b/default-pt.json
@@ -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]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/elf/elf_file.cpp b/elf/elf_file.cpp
index febb318..436e8fe 100644
--- a/elf/elf_file.cpp
+++ b/elf/elf_file.cpp
@@ -150,10 +150,7 @@ int rp_check_elf_header(const elf32_header &eh) {
if (eh.common.machine != EM_ARM && eh.common.machine != EM_RISCV) {
fail(ERROR_FORMAT, "Not an Arm or RISC-V executable");
}
- // Accept either ELFOSABI_NONE or ELFOSABI_GNU for EI_OSABI. Compilers may
- // 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 */) {
+ if (eh.common.abi != 0) {
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
@@ -230,15 +227,6 @@ void elf_file::flatten(void) {
}
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());
}
@@ -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 {
if (!eh.sh_str_index || eh.sh_str_index > eh.sh_num)
return "";
@@ -393,7 +369,6 @@ int elf_file::read_file(std::shared_ptr file) {
read_sh();
}
read_sh_data();
- read_ph_data();
}
catch (const std::ios_base::failure &e) {
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 &con
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));
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 &content) {
@@ -449,7 +423,6 @@ void elf_file::content(const elf32_sh_entry &sh, const std::vector &con
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));
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) {
@@ -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_data.push_back(std::vector(size));
ph_entries.back().offset = sh.offset;
- ph_data.push_back(std::vector(size));
eh.sh_offset = sh.offset + sh.size;
eh.sh_num++;
diff --git a/elf/elf_file.h b/elf/elf_file.h
index cd4e1f3..03b3364 100644
--- a/elf/elf_file.h
+++ b/elf/elf_file.h
@@ -55,7 +55,6 @@ private:
void read_ph(void);
void read_sh(void);
void read_sh_data(void);
- void read_ph_data(void);
void read_bytes(unsigned offset, unsigned length, void *dest);
uint32_t append_section_name(const std::string &sh_name_str);
void flatten(void);
@@ -66,7 +65,6 @@ private:
std::vector ph_entries;
std::vector sh_entries;
std::vector> sh_data;
- std::vector> ph_data;
bool verbose;
};
int rp_check_elf_header(const elf32_header &eh);
diff --git a/elf/portable_endian.h b/elf/portable_endian.h
index 347dd50..4286f91 100644
--- a/elf/portable_endian.h
+++ b/elf/portable_endian.h
@@ -43,22 +43,27 @@
# define __LITTLE_ENDIAN LITTLE_ENDIAN
# define __PDP_ENDIAN PDP_ENDIAN
-#elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
+#elif defined(__OpenBSD__)
+
+# include
+
+# 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
-#ifndef be16toh
# define be16toh(x) betoh16(x)
-#endif
-#ifndef le16toh
# define le16toh(x) letoh16(x)
-#endif
-#ifndef be32toh
+
# define be32toh(x) betoh32(x)
-#endif
-#ifndef le32toh
# define le32toh(x) letoh32(x)
-#endif
+
+# define be64toh(x) betoh64(x)
+# define le64toh(x) letoh64(x)
#elif defined(__WINDOWS__)
@@ -164,4 +169,4 @@
#endif
-#endif
+#endif
\ No newline at end of file
diff --git a/elf2uf2/elf2uf2.cpp b/elf2uf2/elf2uf2.cpp
index 63ce372..5a0e495 100644
--- a/elf2uf2/elf2uf2.cpp
+++ b/elf2uf2/elf2uf2.cpp
@@ -129,7 +129,7 @@ uf2_block gen_abs_block(uint32_t abs_block_loc) {
uf2_block block;
block.magic_start0 = UF2_MAGIC_START0;
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.num_blocks = 2;
block.file_size = ABSOLUTE_FAMILY_ID;
@@ -138,7 +138,6 @@ uf2_block gen_abs_block(uint32_t abs_block_loc) {
block.block_no = 0;
memset(block.data, 0, sizeof(block.data));
memset(block.data, 0xef, UF2_PAGE_SIZE);
- *(uint32_t*)&(block.data[UF2_PAGE_SIZE]) = UF2_EXTENSION_RP2_IGNORE_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; }) &&
block.magic_start0 == UF2_MAGIC_START0 &&
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.num_blocks == 2 &&
block.file_size == ABSOLUTE_FAMILY_ID &&
block.magic_end == UF2_MAGIC_END &&
- block.block_no == 0 &&
- !(block.flags & UF2_FLAG_EXTENSION_FLAGS_PRESENT && *(uint32_t*)&(block.data[UF2_PAGE_SIZE]) != UF2_EXTENSION_RP2_IGNORE_BLOCK);
+ block.block_no == 0;
}
int pages2uf2(std::map>& pages, std::shared_ptr in, std::shared_ptr 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) {
- uint32_t base_addr = pages.begin()->first;
- address_ranges flash_range = rp2350_address_ranges_flash;
- if (is_address_initialized(flash_range, base_addr)) {
- uf2_block block = gen_abs_block(abs_block_loc);
- out->write((char*)&block, sizeof(uf2_block));
- if (out->fail()) {
- fail_write_error();
- }
+ uf2_block block = gen_abs_block(abs_block_loc);
+ out->write((char*)&block, sizeof(uf2_block));
+ if (out->fail()) {
+ fail_write_error();
}
}
uf2_block block;
diff --git a/json/default-pt.json b/json/default-pt.json
deleted file mode 100644
index 83be3dc..0000000
--- a/json/default-pt.json
+++ /dev/null
@@ -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]
- }
- ]
-}
diff --git a/json/schemas/otp-contents-schema.json b/json/schemas/otp-contents-schema.json
deleted file mode 100644
index aa4f7ac..0000000
--- a/json/schemas/otp-contents-schema.json
+++ /dev/null
@@ -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
- }
-}
diff --git a/json/schemas/otp-schema.json b/json/schemas/otp-schema.json
deleted file mode 100644
index d59bc3a..0000000
--- a/json/schemas/otp-schema.json
+++ /dev/null
@@ -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
-}
diff --git a/json/schemas/partition-table-schema.json b/json/schemas/partition-table-schema.json
deleted file mode 100644
index 92eadcd..0000000
--- a/json/schemas/partition-table-schema.json
+++ /dev/null
@@ -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}$"
- }
- }
- }
- }
-}
diff --git a/json/schemas/permissions-schema.json b/json/schemas/permissions-schema.json
deleted file mode 100644
index 7956c62..0000000
--- a/json/schemas/permissions-schema.json
+++ /dev/null
@@ -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
-}
diff --git a/json/schemas/whitelabel-schema.json b/json/schemas/whitelabel-schema.json
deleted file mode 100644
index d96011a..0000000
--- a/json/schemas/whitelabel-schema.json
+++ /dev/null
@@ -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
-}
diff --git a/main.cpp b/main.cpp
index 1f75cd3..4f5b2fe 100644
--- a/main.cpp
+++ b/main.cpp
@@ -14,7 +14,7 @@
#include
#include
#include
-#if !defined(__APPLE__) && !defined(__FreeBSD__)
+#ifndef __APPLE__
#include
#endif
#include
@@ -42,7 +42,7 @@
#endif
#include "bintool.h"
#include "elf2uf2.h"
-#include "boot/bootrom_constants.h"
+#include "pico/bootrom_constants.h"
#include "pico/binary_info.h"
#include "pico/stdio_usb/reset_interface.h"
#include "elf.h"
@@ -57,7 +57,7 @@
#endif
// missing __builtins on windows
-#if defined(_MSC_VER) && !defined(__clang__)
+#ifdef _MSC_VER
# include
# define __builtin_popcount __popcnt
static __forceinline int __builtin_ctz(unsigned x) {
@@ -75,8 +75,6 @@ static __forceinline int __builtin_ctz(unsigned x) {
#define _CRT_SECURE_NO_WARNINGS
#endif
-#define MAX_REBOOT_TRIES 5
-
#define OTP_PAGE_COUNT 64
#define OTP_PAGE_ROWS 64
#define OTP_ROW_COUNT (OTP_PAGE_COUNT * OTP_PAGE_ROWS)
@@ -97,26 +95,25 @@ typedef map>>
auto memory_names = map{
{memory_type::sram, "RAM"},
+ {memory_type::sram_unstriped, "Unstriped RAM"},
{memory_type::flash, "Flash"},
{memory_type::xip_sram, "XIP RAM"},
{memory_type::rom, "ROM"}
};
-static const string tool_name = "picotool";
+static string tool_name = "picotool";
-static const string data_family_name = "data";
-static const string absolute_family_name = "absolute";
-static const string rp2040_family_name = "rp2040";
-static const string rp2350_arm_s_family_name = "rp2350-arm-s";
-static const string rp2350_arm_ns_family_name = "rp2350-arm-ns";
-static const string rp2350_riscv_family_name = "rp2350-riscv";
-
-static string hex_string(int64_t value, int width=8, bool prefix=true, bool uppercase=false) {
+static string hex_string(int64_t value, int width=8, bool prefix=true) {
std::stringstream ss;
if (prefix) ss << "0x";
- ss << std::setfill('0') << std::setw(width);
- if (uppercase) ss << std::uppercase;
- ss << std::hex << value;
+ ss << std::setfill('0') << std::setw(width) << std::hex << value;
+ return ss.str();
+}
+
+static string HEX_string(int64_t value, int width=8, bool prefix=true) {
+ std::stringstream ss;
+ if (prefix) ss << "0x";
+ ss << std::setfill('0') << std::setw(width) << std::uppercase << std::hex << value;
return ss.str();
}
@@ -142,7 +139,6 @@ std::array, 12> pin_functions_rp2350{{
{"SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO", "SIO"},
{"PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0", "PIO0"},
{"PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1", "PIO1"},
- {"PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2", "PIO2"},
{"XIP CS1", "CORESIGHT TRACECLK","CORESIGHT TRACEDATA0","CORESIGHT TDATA1","CORESIGHT TDATA2","CORESIGHT TDATA3","","","XIP CS1", "", "","", "CLK GPIN", "CLK GPOUT","CLK GPIN", "CLK GPOUT","", "", "", "XIP CS1", "CLK GPIN", "CLK GPOUT","CLK GPIN", "CLK GPOUT","CLK GPOUT","CLK GPOUT","", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "XIP CS1"},
{"USB OVCUR DET", "USB VBUS DET", "USB VBUS EN", "USB OVCUR DET", "USB VBUS DET", "USB VBUS EN", "USB OVCUR DET", "USB VBUS DET", "USB VBUS EN", "USB OVCUR DET", "USB VBUS DET", "USB VBUS EN", "USB OVCUR DET", "USB VBUS DET", "USB VBUS EN", "USB OVCUR DET", "USB VBUS DET", "USB VBUS EN", "USB OVCUR DET", "USB VBUS DET", "USB VBUS EN", "USB OVCUR DET", "USB VBUS DET", "USB VBUS EN", "USB OVCUR DET", "USB VBUS DET", "USB VBUS EN", "USB OVCUR DET", "USB VBUS DET", "USB VBUS EN", "USB OVCUR DET", "USB VBUS DET", "USB VBUS EN", "USB OVCUR DET", "USB VBUS DET", "USB VBUS EN", "USB OVCUR DET", "USB VBUS DET", "USB VBUS EN", "USB OVCUR DET", "USB VBUS DET", "USB VBUS EN", "USB OVCUR DET", "USB VBUS DET", "USB VBUS EN", "USB OVCUR DET", "USB VBUS DET", "USB VBUS EN"},
{"", "", "UART0 TX", "UART0 RX", "", "", "UART1 TX", "UART1 RX", "", "", "UART1 TX", "UART1 RX", "", "", "UART0 TX", "UART0 RX", "", "", "UART0 TX", "UART0 RX", "", "", "UART1 TX", "UART1 RX", "", "", "UART1 TX", "UART1 RX", "", "", "UART0 TX", "UART0 RX", "", "", "UART0 TX", "UART0 RX", "", "", "UART1 TX", "UART1 RX", "", "", "UART1 TX", "UART1 RX", "", "", "UART0 TX", "UART0 RX"}
@@ -151,16 +147,8 @@ std::array, 12> pin_functions_rp2350{{
std::map otp_regs;
#if HAS_LIBUSB
-auto bus_device_string = [](struct libusb_device *device, model_t model) {
- string bus_device;
- if (model == rp2040) {
- bus_device = string("RP2040 device at bus ");
- } else if (model == rp2350) {
- bus_device = string("RP2350 device at bus ");
- } else {
- bus_device = string("Device at bus ");
- }
- return bus_device + std::to_string(libusb_get_bus_number(device)) + ", address " + std::to_string(libusb_get_device_address(device));
+auto bus_device_string = [](struct libusb_device *device) {
+ return string("Device at bus ") + std::to_string(libusb_get_bus_number(device)) + ", address " + std::to_string(libusb_get_device_address(device));
};
#endif
@@ -307,39 +295,35 @@ struct family_id : public cli::value_base {
// note we cannot capture "this"
on_action([&t, nm](string value) {
auto ovalue = value;
- if (value == data_family_name) {
+ if (value == "data") {
t = DATA_FAMILY_ID;
- } else if (value == absolute_family_name) {
+ } else if (value == "absolute") {
t = ABSOLUTE_FAMILY_ID;
- } else if (value == rp2040_family_name) {
+ } else if (value == "rp2040") {
t = RP2040_FAMILY_ID;
- } else if (value == rp2350_arm_s_family_name) {
+ } else if (value == "rp2350-arm-s") {
t = RP2350_ARM_S_FAMILY_ID;
- } else if (value == rp2350_arm_s_family_name) {
+ } else if (value == "rp2350-arm-ns") {
t = RP2350_ARM_NS_FAMILY_ID;
- } else if (value == rp2350_riscv_family_name) {
+ } else if (value == "rp2350-riscv") {
t = RP2350_RISCV_FAMILY_ID;
} else {
- if (value.find("0x") == 0) {
- value = value.substr(2);
- size_t pos = 0;
- long lvalue = std::numeric_limits::max();
- try {
- lvalue = std::stoul(value, &pos, 16);
- if (pos != value.length()) {
- return "Garbage after hex value: " + value.substr(pos);
- }
- } catch (std::invalid_argument &) {
- return ovalue + " is not a valid hex value";
- } catch (std::out_of_range &) {
+ if (value.find("0x") == 0) value = value.substr(2);
+ size_t pos = 0;
+ long lvalue = std::numeric_limits::max();
+ try {
+ lvalue = std::stoul(value, &pos, 16);
+ if (pos != value.length()) {
+ return "Garbage after hex value: " + value.substr(pos);
}
- if (lvalue != (unsigned int) lvalue) {
- return value + " is not a valid 32 bit value";
- }
- t = (unsigned int) lvalue;
- } else {
- return value + " is not a valid family ID";
+ } catch (std::invalid_argument &) {
+ return ovalue + " is not a valid hex value";
+ } catch (std::out_of_range &) {
}
+ if (lvalue != (unsigned int) lvalue) {
+ return value + " is not a valid 32 bit value";
+ }
+ t = (unsigned int) lvalue;
}
return string("");
});
@@ -348,12 +332,12 @@ struct family_id : public cli::value_base {
};
string family_name(unsigned int family_id) {
- if (family_id == DATA_FAMILY_ID) return "'" + data_family_name + "'";
- if (family_id == ABSOLUTE_FAMILY_ID) return "'" + absolute_family_name + "'";
- if (family_id == RP2040_FAMILY_ID) return "'" + rp2040_family_name + "'";
- if (family_id == RP2350_ARM_S_FAMILY_ID) return "'" + rp2350_arm_s_family_name + "'";
- if (family_id == RP2350_ARM_NS_FAMILY_ID) return "'" + rp2350_arm_ns_family_name + "'";
- if (family_id == RP2350_RISCV_FAMILY_ID) return "'" + rp2350_riscv_family_name + "'";
+ if (family_id == DATA_FAMILY_ID) return "'data'";
+ if (family_id == ABSOLUTE_FAMILY_ID) return "'absolute'";
+ if (family_id == RP2040_FAMILY_ID) return "'rp2040'";
+ if (family_id == RP2350_ARM_S_FAMILY_ID) return "'rp2350-arm-s'";
+ if (family_id == RP2350_ARM_NS_FAMILY_ID) return "'rp2350-arm-ns'";
+ if (family_id == RP2350_RISCV_FAMILY_ID) return "'rp2350-riscv'";
if (!family_id) return "none";
return hex_string(family_id);
}
@@ -417,7 +401,6 @@ struct _settings {
int redundancy = -1;
bool raw = false;
bool ecc = false;
- bool ignore_set = false;
bool fuzzy = false;
uint32_t value = 0;
uint8_t lock0 = 0;
@@ -426,7 +409,6 @@ struct _settings {
std::vector pages;
bool list_pages = false;
bool list_no_descriptions = false;
- bool list_field_descriptions = false;
std::vector selectors;
uint32_t row = 0;
std::vector extra_files;
@@ -435,7 +417,6 @@ struct _settings {
struct {
bool show_basic = false;
bool all = false;
- bool show_metadata = false;
bool show_pins = false;
bool show_device = false;
bool show_debug = false;
@@ -474,7 +455,6 @@ struct _settings {
struct {
bool all = false;
- bool verify = false;
} save;
struct {
@@ -483,11 +463,7 @@ struct _settings {
} version;
struct {
- #if HAS_MBEDTLS
bool hash = true;
- #else
- bool hash = false;
- #endif
bool sign = false;
bool singleton = false;
} partition;
@@ -503,7 +479,6 @@ struct _settings {
};
_settings settings;
std::shared_ptr selected_cmd;
-model_t selected_model = unknown;
auto device_selection =
(
@@ -600,7 +575,6 @@ struct info_command : public cmd {
return (
(
option('b', "--basic").set(settings.info.show_basic) % "Include basic information. This is the default" +
- option('m', "--metadata").set(settings.info.show_metadata) % "Include all metadata blocks" +
option('p', "--pins").set(settings.info.show_pins) % "Include pin information" +
option('d', "--device").set(settings.info.show_device) % "Include device information" +
option("--debug").set(settings.info.show_debug) % "Include device debug information" +
@@ -609,7 +583,7 @@ struct info_command : public cmd {
).min(0).doc_non_optional(true) % "Information to display" +
(
#if HAS_LIBUSB
- device_selection % "To target one or more connected RP-series device(s) in BOOTSEL mode (the default)" |
+ device_selection % "To target one or more connected RP2040 device(s) in BOOTSEL mode (the default)" |
#endif
file_selection % "To target a file"
).major_group("TARGET SELECTION").min(0).doc_non_optional(true)
@@ -617,7 +591,7 @@ struct info_command : public cmd {
}
string get_doc() const override {
- return "Display information from the target device(s) or file.\nWithout any arguments, this will display basic information for all connected RP-series devices in BOOTSEL mode";
+ return "Display information from the target device(s) or file.\nWithout any arguments, this will display basic information for all connected RP2040 devices in BOOTSEL mode";
}
};
@@ -640,7 +614,7 @@ struct config_command : public cmd {
(option('g', "--group") & value("group").set(settings.config.group)) % "Filter by feature group" +
(
#if HAS_LIBUSB
- device_selection % "To target one or more connected RP-series device(s) in BOOTSEL mode (the default)" |
+ device_selection % "To target one or more connected RP2040 device(s) in BOOTSEL mode (the default)" |
#endif
file_selection % "To target a file"
).major_group("TARGET SELECTION").min(0).doc_non_optional(true)
@@ -691,9 +665,6 @@ struct save_command : public cmd {
hex("to").set(settings.to) % "The upper address bound in hex"
).min(0).doc_non_optional(true)
).min(0).doc_non_optional(true).no_match_beats_error(false) % "Selection of data to save" +
- option('v', "--verify").set(settings.save.verify) % "Verify the data was saved correctly" +
- (option("--family") % "Specify the family ID to save the file as" &
- family_id("family_id").set(settings.family_id) % "family ID to save file as").force_expand_help(true) +
( // note this parenthesis seems to help with error messages for say save --foo
device_selection % "Source device selection" +
file_selection % "File to save to"
@@ -714,7 +685,7 @@ struct load_command : public cmd {
(
option("--ignore-partitions").set(settings.load.ignore_pt) % "When writing flash data, ignore the partition table and write to absolute space" +
(option("--family") % "Specify the family ID of the file to load" &
- family_id("family_id").set(settings.family_id) % "family ID to use for load").force_expand_help(true) +
+ family_id("family_id").set(settings.family_id) % "family id to use for load").force_expand_help(true) +
(option('p', "--partition") % "Specify the partition to load into" &
integer("partition").set(settings.load.partition) % "partition to load into").force_expand_help(true) +
option('n', "--no-overwrite").set(settings.load.no_overwrite) % "When writing flash data, do not overwrite an existing program in flash. If picotool cannot determine the size/presence of the program in flash, the command fails" +
@@ -736,34 +707,6 @@ struct load_command : public cmd {
return "Load the program / memory range stored in a file onto the device.";
}
};
-
-struct erase_command : public cmd {
- erase_command() : cmd("erase") {}
- bool execute(device_map &devices) override;
-
- group get_cli() override {
- return (
- (
- option('a', "--all") % "Erase all of flash memory. This is the default" |
- (
- option('p', "--partition") % "Erase a partition" &
- integer("partition").set(settings.load.partition) % "Partition number to erase"
- ).min(0).doc_non_optional(true) |
- (
- option('r', "--range").set(settings.range_set) % "Erase a range of memory. Note that erases must be 4096 byte-aligned, so the range is expanded accordingly" &
- hex("from").set(settings.from) % "The lower address bound in hex" &
- hex("to").set(settings.to) % "The upper address bound in hex"
- ).min(0).doc_non_optional(true)
- ).min(0).doc_non_optional(true).no_match_beats_error(false) % "Selection of data to erase" +
- ( // note this parenthesis seems to help with error messages for say erase --foo
- device_selection % "Source device selection"
- )
- );
- }
- string get_doc() const override {
- return "Erase the program / memory stored in flash on the device.";
- }
-};
#endif
#if HAS_MBEDTLS
@@ -869,7 +812,7 @@ struct partition_info_command : public cmd {
group get_cli() override {
return (
- (option('m', "--family") & family_id("family_id").set(settings.family_id)) % "family ID (will show target partition for said family)" +
+ (option('m', "--family") & family_id("family_id").set(settings.family_id)) % "family id (will show target partition for said family)" +
device_selection % "Target device selection"
);
}
@@ -877,6 +820,9 @@ struct partition_info_command : public cmd {
string get_doc() const override {
return "Print the device's partition table.";
}
+
+ void print_permissions(unsigned int p) const;
+ void insert_default_families(uint32_t flags_and_permissions, vector &family_ids) const;
};
#endif
@@ -895,25 +841,23 @@ struct partition_create_command : public cmd {
(option('o', "--offset").set(settings.offset_set) % "Specify the load address for UF2 file output" &
hex("offset").set(settings.offset) % "Load offset (memory address; default 0x10000000)").force_expand_help(true) +
(option("--family") % "Specify the family if for UF2 file output" &
- family_id("family_id").set(settings.family_id) % "family ID for UF2 (default absolute)").force_expand_help(true)
+ family_id("family_id").set(settings.family_id) % "family id for UF2 (default absolute)").force_expand_help(true)
).min(0).force_expand_help(true) % "UF2 output options") +
optional_typed_file_selection_x("bootloader", 2, "elf") % "embed partition table into bootloader ELF" +
(
- #if HAS_MBEDTLS
// todo why doesn't this set settings.partition.sign?
((option("--sign").set(settings.partition.sign) & value("keyfile").with_exclusion_filter([](const string &value) {
return value.find_first_of('-') == 0;
}).set(settings.filenames[3])) % "The file name" +
named_file_types_x("pem", 3)) % "Sign the partition table" +
(option("--no-hash").clear(settings.partition.hash) % "Don't hash the partition table") +
- #endif
(option("--singleton").set(settings.partition.singleton) % "Singleton partition table")
).min(0).force_expand_help(true) % "Partition Table Options"
#if SUPPORT_A2
+ (
option("--abs-block").set(settings.uf2.abs_block) % "Enforce support for an absolute block" +
hex("abs_block_loc").set(settings.uf2.abs_block_loc).min(0) % "absolute block location (default to 0x10ffff00)"
- ).force_expand_help(true).min(0) % "Errata RP2350-E10 Fix"
+ ).force_expand_help(true).min(0) % "Errata RP2350-E9 Fix"
#endif
);
}
@@ -921,6 +865,9 @@ struct partition_create_command : public cmd {
string get_doc() const override {
return "Create a partition table from json";
}
+
+ void print_permissions(unsigned int p) const;
+ void insert_default_families(uint32_t flags_and_permissions, vector &family_ids) const;
};
@@ -949,7 +896,6 @@ struct otp_list_command : public cmd {
(
option('p', "--pages").set(settings.otp.list_pages) % "Show page number/page row number" +
option('n', "--no-descriptions").set(settings.otp.list_no_descriptions) % "Don't show descriptions" +
- option('f', "--field-descriptions").set(settings.otp.list_field_descriptions) % "Show all field descriptions" +
(option('i', "--include") & value("filename").add_to(settings.otp.extra_files)).min(0).max(1) % "Include extra otp definition" + // todo more than 1
(value("selector").add_to(settings.otp.selectors) %
"The row/field selector, each of which can select a whole row:\n\n" \
@@ -1068,7 +1014,6 @@ struct otp_set_command : public cmd {
(option('c', "--copies") & integer("copies").min(1).set(settings.otp.redundancy)) % "Read multiple redundant values" +
option('r', "--raw").set(settings.otp.raw) % "Set raw 24 bit values" +
option('e', "--ecc").set(settings.otp.ecc) % "Use error correction" +
- option('s', "--set-bits").set(settings.otp.ignore_set) % "Set bits only" +
(option('i', "--include") & value("filename").add_to(settings.otp.extra_files)).min(0).max(1) % "Include extra otp definition" // todo more than 1
).min(0).doc_non_optional(true) % "Redundancy/Error Correction Overrides" +
(
@@ -1190,13 +1135,13 @@ struct uf2_convert_command : public cmd {
hex("offset").set(settings.offset) % "Load offset (memory address; default 0x10000000 for BIN file)"
).force_expand_help(true) % "Packaging Options" +
(
- option("--family") & family_id("family_id").set(settings.family_id) % "family ID for UF2"
+ option("--family") & family_id("family_id").set(settings.family_id) % "family id for UF2"
).force_expand_help(true) % "UF2 Family options"
#if SUPPORT_A2
+ (
option("--abs-block").set(settings.uf2.abs_block) % "Add an absolute block" +
hex("abs_block_loc").set(settings.uf2.abs_block_loc).min(0) % "absolute block location (default to 0x10ffff00)"
- ).force_expand_help(true).min(0) % "Errata RP2350-E10 Fix"
+ ).force_expand_help(true).min(0) % "Errata RP2350-E9 Fix"
#endif
);
}
@@ -1344,7 +1289,6 @@ vector> commands {
std::shared_ptr(new link_command()),
#if HAS_LIBUSB
std::shared_ptr(new save_command()),
- std::shared_ptr(new erase_command()),
std::shared_ptr(new verify_command()),
reboot_cmd,
#endif
@@ -1409,9 +1353,9 @@ int parse(const int argc, char **argv) {
section_header(tool_name);
fos.first_column(tab);
#if HAS_LIBUSB
- fos << "Tool for interacting with RP-series device(s) in BOOTSEL mode, or with an RP-series binary" << "\n";
+ fos << "Tool for interacting with RP2040/RP2350 device(s) in BOOTSEL mode, or with an RP2040/RP2350 binary" << "\n";
#else
- fos << "Tool for interacting with an RP-series binary" << "\n";
+ fos << "Tool for interacting with an RP2040/RP2350 binary" << "\n";
#endif
}
vector synopsis;
@@ -1654,7 +1598,6 @@ SAFE_MAPPING(binary_info_named_group_t);
#define BOOTROM_MAGIC_RP2040 0x01754d
#define BOOTROM_MAGIC_RP2350 0x02754d
-#define BOOTROM_MAGIC_UNKNOWN 0x000000
#define BOOTROM_MAGIC_ADDR 0x00000010
static inline uint32_t rom_table_code(char c1, char c2) {
@@ -1740,13 +1683,11 @@ static model_t get_model(memory_access &raw_access) {
}
}
-template
-bool get_int(const std::string& s, T& out) {
+bool get_int(const std::string& s, int& out) {
return integer::parse_string(s, out).empty();
}
-template
-bool get_json_int(json value, T& out) {
+bool get_json_int(json value, int& out) {
if (value.is_string()) {
string str = value;
if (str.back() == 'k' || str.back() == 'K') {
@@ -1792,7 +1733,7 @@ uint32_t bootrom_func_lookup(memory_access& access, uint16_t tag) {
uint32_t bootrom_table_lookup_rp2350(memory_access& access, uint16_t tag, uint16_t flags) {
model_t model = get_model(access);
- // we are only used on RP2350
+ // we are only used on RP2040
if (model != rp2350) {
fail(ERROR_INCOMPATIBLE, "RP2350 BOOT ROM not found");
}
@@ -1913,13 +1854,13 @@ struct picoboot_memory_access : public memory_access {
}
}
- // note this does not automatically erase flash unless erase is set
+ // note this does not automatically erase flash
void write(uint32_t address, uint8_t *buffer, unsigned int size) override {
- vector write_data; // used when erasing flash
if (flash == get_memory_type(address, model)) {
connection.exit_xip();
if (erase) {
// Do automatically erase flash, and make it aligned
+ vector write_data;
// we have to erase in whole pages
range aligned_range(address & ~(FLASH_SECTOR_ERASE_SIZE - 1),
((address + size) & ~(FLASH_SECTOR_ERASE_SIZE - 1)) + FLASH_SECTOR_ERASE_SIZE);
@@ -1984,7 +1925,7 @@ struct iostream_memory_access : public memory_access {
}
void read(uint32_t address, uint8_t *buffer, uint32_t size, bool zero_fill) override {
- if (address == BOOTROM_MAGIC_ADDR && size == 4) {
+ if (model != unknown && address == BOOTROM_MAGIC_ADDR && size == 4) {
// return the memory model
if (model == rp2040) {
*(uint32_t*)buffer = BOOTROM_MAGIC_RP2040;
@@ -1992,9 +1933,6 @@ struct iostream_memory_access : public memory_access {
} else if (model == rp2350) {
*(uint32_t*)buffer = BOOTROM_MAGIC_RP2350;
return;
- } else {
- *(uint32_t*)buffer = BOOTROM_MAGIC_UNKNOWN;
- return;
}
}
while (size) {
@@ -2383,13 +2321,7 @@ struct bi_visitor_base {
for(unsigned int i=0; i<64; i++) {
if (pin_mask & (1ull << i)) {
if (func != -1) {
- if (pin_functions[func][i].empty()) {
- std::stringstream sstream;
- sstream << "Unknown pin function " << func;
- pin(i, sstream.str());
- } else {
- pin(i, pin_functions[func][i]);
- }
+ pin(i, pin_functions[func][i]);
} else {
auto sep = name.find_first_of('|');
auto cur = name.substr(0, sep);
@@ -2657,11 +2589,14 @@ void build_rmap_elf(std::shared_ptrfile, range_map& rmap)
}
}
-uint32_t build_rmap_uf2(std::shared_ptrfile, range_map& rmap, uint32_t family_id=0) {
+bool is_valid_family_id(uint32_t family_id) {
+ return family_id >= RP2040_FAMILY_ID && family_id <= FAMILY_ID_MAX;
+}
+
+void build_rmap_uf2(std::shared_ptrfile, range_map& rmap) {
file->seekg(0, ios::beg);
uf2_block block;
unsigned int pos = 0;
- uint32_t next_family_id = 0;
do {
file->read((char*)&block, sizeof(uf2_block));
if (file->fail()) {
@@ -2671,46 +2606,22 @@ uint32_t build_rmap_uf2(std::shared_ptrfile, range_map& r
if (block.magic_start0 == UF2_MAGIC_START0 && block.magic_start1 == UF2_MAGIC_START1 &&
block.magic_end == UF2_MAGIC_END) {
if (block.flags & UF2_FLAG_FAMILY_ID_PRESENT &&
- !(block.flags & UF2_FLAG_NOT_MAIN_FLASH) && block.payload_size == PAGE_SIZE &&
- (!family_id || block.file_size == family_id)) {
+ is_valid_family_id(block.file_size) &&
+ !(block.flags & UF2_FLAG_NOT_MAIN_FLASH) && block.payload_size == PAGE_SIZE) {
#if SUPPORT_A2
- // ignore the absolute block, but save the address
+ // ignore the absolute block
if (check_abs_block(block)) {
- DEBUG_LOG("Ignoring RP2350-E10 absolute block\n");
- settings.uf2.abs_block_loc = block.target_addr;
+ DEBUG_LOG("Ignoring RP2350-E9 absolute block\n");
} else {
rmap.insert(range(block.target_addr, block.target_addr + PAGE_SIZE), pos + offsetof(uf2_block, data[0]));
- family_id = block.file_size;
- next_family_id = 0;
}
#else
rmap.insert(range(block.target_addr, block.target_addr + PAGE_SIZE), pos + offsetof(uf2_block, data[0]));
- family_id = block.file_size;
- next_family_id = 0;
- #endif
- } else if (block.file_size != family_id && family_id && !next_family_id) {
- #if SUPPORT_A2
- if (!check_abs_block(block)) {
- #endif
- next_family_id = block.file_size;
- #if SUPPORT_A2
- }
#endif
}
}
pos += sizeof(uf2_block);
} while (true);
-
- return next_family_id;
-}
-
-void build_rmap_load_map(std::shared_ptrload_map, range_map& rmap) {
- for (unsigned int i=0; i < load_map->entries.size(); i++) {
- auto e = load_map->entries[i];
- if (e.storage_address != 0) {
- rmap.insert(range(e.runtime_address, e.runtime_address + e.size), e.storage_address);
- }
- }
}
uint32_t find_binary_start(range_map& rmap) {
@@ -2734,11 +2645,9 @@ uint32_t find_binary_start(range_map& rmap) {
return binary_start;
}
-template ACCESS get_iostream_memory_access(std::shared_ptr file, filetype type, bool writeable = false, uint32_t *next_family_id=nullptr) {
+template ACCESS get_iostream_memory_access(std::shared_ptr file, filetype type, bool writeable = false) {
range_map rmap;
uint32_t binary_start = 0;
- uint32_t tmp = 0;
- if (next_family_id != nullptr) tmp = *next_family_id;
switch (type) {
case filetype::bin:
file->seekg(0, std::ios::end);
@@ -2750,12 +2659,7 @@ template ACCESS get_iostream_memory_access(st
binary_start = find_binary_start(rmap);
break;
case filetype::uf2:
- tmp = build_rmap_uf2(file, rmap, tmp);
- if (next_family_id != nullptr) {
- *next_family_id = tmp;
- } else if (tmp) {
- fos << "WARNING: Multiple family IDs in a single UF2 file - only using first one\n";
- }
+ build_rmap_uf2(file, rmap);
binary_start = find_binary_start(rmap);
break;
default:
@@ -2770,11 +2674,11 @@ template ACCESS get_iostream_memory_access(st
return ACCESS(file, rmap, binary_start);
}
-file_memory_access get_file_memory_access(uint8_t idx, bool writeable = false, uint32_t *next_family_id=nullptr) {
+file_memory_access get_file_memory_access(uint8_t idx, bool writeable = false) {
ios::openmode mode = (writeable ? ios::out|ios::in : ios::in)|ios::binary;
auto file = get_file_idx(mode, idx);
try {
- return get_iostream_memory_access(file, get_file_type_idx(idx), writeable, next_family_id);
+ return get_iostream_memory_access(file, get_file_type_idx(idx), writeable);
} catch (std::exception&) {
file->close();
throw;
@@ -2884,74 +2788,6 @@ std::unique_ptr find_best_block(memory_access &raw_access, vector find_last_block(memory_access &raw_access, vector &bin) {
- // todo read the right amount
- uint32_t read_size = 0x1000;
- DEBUG_LOG("Reading from %x size %x\n", raw_access.get_binary_start(), read_size);
- bin = raw_access.read_vector(raw_access.get_binary_start(), read_size, true);
-
- std::unique_ptr first_block = find_first_block(bin, raw_access.get_binary_start());
- if (first_block) {
- // verify stuff
- get_more_bin_cb more_cb = [&raw_access](std::vector &bin, uint32_t new_size) {
- DEBUG_LOG("Now reading from %x size %x\n", raw_access.get_binary_start(), new_size);
- bin = raw_access.read_vector(raw_access.get_binary_start(), new_size, true);
- };
- auto last_block = get_last_block(bin, raw_access.get_binary_start(), first_block, more_cb);
- return last_block;
- }
-
- return nullptr;
-}
-
-std::shared_ptr get_bi_access(memory_access &raw_access) {
- vector bin;
- std::unique_ptr best_block = find_best_block(raw_access, bin);
- range_map rmap;
- if (best_block) {
- auto load_map = best_block->get_item();
- if (load_map != nullptr) {
- // Remap for find_binary_info
- build_rmap_load_map(load_map, rmap);
- }
- }
-
- return std::make_shared(raw_access, rmap);
-}
-
-string str_permissions(unsigned int p) {
- static_assert(PICOBIN_PARTITION_PERMISSION_S_R_BITS == (1u << 26), "");
- static_assert(PICOBIN_PARTITION_PERMISSION_S_W_BITS == (1u << 27), "");
- static_assert(PICOBIN_PARTITION_PERMISSION_NS_W_BITS == (1u << 29), "");
- static_assert(PICOBIN_PARTITION_PERMISSION_NSBOOT_W_BITS == (1u << 31), "");
-
- std::stringstream ss;
- ss << " S(";
- unsigned int r = (p >> 26) & 3;
- if (r & 1) ss << "r";
- if (r & 2) ss << "w"; else if (!r) ss << "-";
- ss << ") NSBOOT(";
- r = (p >> 30) & 3;
- if (r & 1) ss << "r";
- if (r & 2) ss << "w"; else if (!r) ss << "-";
- ss << ") NS(";
- r = (p >> 28) & 3;
- if (r & 1) ss << "r";
- if (r & 2) ss << "w"; else if (!r) ss << "-";
- ss << ")";
-
- return ss.str();
-}
-
-void insert_default_families(uint32_t flags_and_permissions, vector &family_ids) {
- if (flags_and_permissions & PICOBIN_PARTITION_FLAGS_ACCEPTS_DEFAULT_FAMILY_ABSOLUTE_BITS) family_ids.emplace_back(absolute_family_name);
- if (flags_and_permissions & PICOBIN_PARTITION_FLAGS_ACCEPTS_DEFAULT_FAMILY_RP2040_BITS) family_ids.emplace_back(rp2040_family_name);
- if (flags_and_permissions & PICOBIN_PARTITION_FLAGS_ACCEPTS_DEFAULT_FAMILY_RP2350_ARM_S_BITS) family_ids.emplace_back(rp2350_arm_s_family_name);
- if (flags_and_permissions & PICOBIN_PARTITION_FLAGS_ACCEPTS_DEFAULT_FAMILY_RP2350_ARM_NS_BITS) family_ids.emplace_back(rp2350_arm_ns_family_name);
- if (flags_and_permissions & PICOBIN_PARTITION_FLAGS_ACCEPTS_DEFAULT_FAMILY_RP2350_RISCV_BITS) family_ids.emplace_back(rp2350_riscv_family_name);
- if (flags_and_permissions & PICOBIN_PARTITION_FLAGS_ACCEPTS_DEFAULT_FAMILY_DATA_BITS) family_ids.emplace_back(data_family_name);
-}
-
#if HAS_LIBUSB
void info_guts(memory_access &raw_access, picoboot::connection *con) {
#else
@@ -2967,19 +2803,12 @@ void info_guts(memory_access &raw_access, void *con) {
vector groups;
string current_group;
map>> infos;
- // Set enable to true to enable the selected group
- auto select_group = [&](const group &g1, bool enable = false) {
+ auto select_group = [&](const group &g1, bool enabled = true) {
if (std::find_if(groups.begin(), groups.end(), [&](const group &g2) {
return g1.name == g2.name;
}) == groups.end()) {
groups.push_back(g1);
}
- auto enable_changed = std::find_if(groups.begin(), groups.end(), [&](const group &g2) {
- return g1.name == g2.name && (enable && !g2.enabled);
- });
- if (enable_changed != groups.end()) {
- enable_changed->enabled = true;
- }
current_group = g1.name;
};
auto info_pair = [&](const string &name, const string &value) {
@@ -2988,221 +2817,15 @@ void info_guts(memory_access &raw_access, void *con) {
infos[current_group].emplace_back(std::make_pair(name, value));
}
};
- auto info_metadata = [&](std::vector bin, block *current_block, bool verbose_metadata = false) {
- verified_t hash_verified = none;
- verified_t sig_verified = none;
- #if HAS_MBEDTLS
- verify_block(bin, raw_access.get_binary_start(), raw_access.get_binary_start(), current_block, hash_verified, sig_verified);
- #endif
-
- // Addresses
- if (verbose_metadata) {
- info_pair("address", hex_string(current_block->physical_addr));
- info_pair("next block address", hex_string(current_block->next_block_rel + current_block->physical_addr));
- if (current_block->get_item() != nullptr) info_pair("block type", "ignored");
- }
-
- // Image Def
- auto image_def = current_block->get_item();
- if (image_def != nullptr) {
- if (verbose_metadata) info_pair("block type", "image def");
- if (image_def->image_type() == type_exe) {
- switch (image_def->chip()) {
- case chip_rp2040:
- info_pair("target chip", "RP2040");
- break;
- case chip_rp2350:
- info_pair("target chip", "RP2350");
- switch (image_def->cpu()) {
- case cpu_riscv:
- info_pair("image type", "RISC-V");
- break;
- case cpu_varmulet:
- info_pair("image type", "Varmulet");
- break;
- case cpu_arm:
- if (image_def->security() == sec_s) {
- info_pair("image type", "ARM Secure");
- } else if (image_def->security() == sec_ns) {
- info_pair("image type", "ARM Non-Secure");
- } else if (image_def->security() == sec_unspecified) {
- info_pair("image type", "ARM");
- }
- }
- break;
- default:
- break;
- }
- } else if (image_def->image_type() == type_data) {
- info_pair("image type", "data");
- }
- }
-
- // Partition Table
- auto partition_table = current_block->get_item();
- if (partition_table != nullptr) {
- if (verbose_metadata) info_pair("block type", "partition table");
- info_pair("partition table", partition_table->singleton ? "singleton" : "non-singleton");
- std::stringstream unpartitioned;
- unpartitioned << str_permissions(partition_table->unpartitioned_flags);
- std::vector family_ids;
- insert_default_families(partition_table->unpartitioned_flags, family_ids);
- unpartitioned << ", uf2 { " << cli::join(family_ids, ", ") << " }";
- info_pair("un-partitioned space", unpartitioned.str());
-
- for (int i=0; i < partition_table->partitions.size(); i++) {
- std::stringstream pstring;
- std::stringstream pname;
- auto partition = partition_table->partitions[i];
- uint32_t flags = partition.flags;
- uint64_t id = partition.id;
- pname << "partition " << i;
- if ((flags & PICOBIN_PARTITION_FLAGS_LINK_TYPE_BITS) ==
- PICOBIN_PARTITION_FLAGS_LINK_TYPE_AS_BITS(A_PARTITION)) {
- pname << " (B w/ " << ((flags & PICOBIN_PARTITION_FLAGS_LINK_VALUE_BITS)
- >> PICOBIN_PARTITION_FLAGS_LINK_VALUE_LSB)
- << ")";
- } else if ((flags & PICOBIN_PARTITION_FLAGS_LINK_TYPE_BITS) ==
- PICOBIN_PARTITION_FLAGS_LINK_TYPE_AS_BITS(OWNER_PARTITION)) {
- pname << " (A ob/ " << ((flags & PICOBIN_PARTITION_FLAGS_LINK_VALUE_BITS)
- >> PICOBIN_PARTITION_FLAGS_LINK_VALUE_LSB)
- << ")";
- } else {
- pname << " (A)";
- }
- pstring << hex_string(partition.first_sector * 4096, 8, false) << "->" << hex_string((partition.last_sector + 1) * 4096, 8, false);
- unsigned int p = partition.permissions;
- pstring << str_permissions(p << PICOBIN_PARTITION_PERMISSIONS_LSB);
- if (flags & PICOBIN_PARTITION_FLAGS_HAS_ID_BITS) {
- pstring << ", id=" << hex_string(id, 16, false);
- }
- uint32_t num_extra_families = partition.extra_families.size();
- family_ids.clear();
- insert_default_families(flags, family_ids);
- for (auto family : partition.extra_families) {
- family_ids.emplace_back(hex_string(family));
- }
- if (flags & PICOBIN_PARTITION_FLAGS_HAS_NAME_BITS) {
- pstring << ", \"";
- pstring << partition.name;
- pstring << '"';
- }
- pstring << ", uf2 { " << cli::join(family_ids, ", ") << " }";
- pstring << ", arm_boot " << !(flags & PICOBIN_PARTITION_FLAGS_IGNORED_DURING_ARM_BOOT_BITS);
- pstring << ", riscv_boot " << !(flags & PICOBIN_PARTITION_FLAGS_IGNORED_DURING_RISCV_BOOT_BITS);
- info_pair(pname.str(), pstring.str());
- }
- }
-
- // Version
- auto version = current_block->get_item();
- if (version != nullptr) {
- info_pair("version", std::to_string(version->major) + "." + std::to_string(version->minor));
- if (version->otp_rows.size() > 0) {
- info_pair("rollback version", std::to_string(version->rollback));
- std::stringstream rows;
- for (const auto row : version->otp_rows) { rows << hex_string(row, 3) << " "; }
- info_pair("rollback rows", rows.str());
- }
- }
-
- if (verbose_metadata) {
- // Load Map
- // todo what should this really report
- auto load_map = current_block->get_item();
- if (load_map != nullptr) {
- for (unsigned int i=0; i < load_map->entries.size(); i++) {
- std::stringstream ss;
- auto e = load_map->entries[i];
- if (e.storage_address == 0) {
- ss << "Clear 0x" << std::hex << e.runtime_address;
- ss << "->0x" << std::hex << e.runtime_address + e.size;
- } else if (e.storage_address != e.runtime_address) {
- if (is_address_initialized(rp2350_address_ranges_flash, e.runtime_address)) {
- ss << "ERROR: COPY TO FLASH NOT PERMITTED ";
- }
- ss << "Copy 0x" << std::hex << e.storage_address;
- ss << "->0x" << std::hex << e.storage_address + e.size;
- ss << " to 0x" << std::hex << e.runtime_address;
- ss << "->0x" << std::hex << e.runtime_address + e.size;
- } else {
- ss << "Load 0x" << std::hex << e.storage_address;
- ss << "->0x" << std::hex << e.storage_address + e.size;
- }
- info_pair("load map entry " + std::to_string(i), ss.str());
- }
- }
-
- // Rolling Window Delta
- auto rwd = current_block->get_item();
- if (rwd != nullptr) {
- info_pair("rolling window delta", hex_string(rwd->addr));
- }
-
- // Vector Table
- auto vtor = current_block->get_item();
- if (vtor != nullptr) {
- info_pair("vector table", hex_string(vtor->addr));
- }
-
- // Entry Point
- auto entry_point = current_block->get_item();
- if (entry_point != nullptr) {
- std::stringstream ss;
- ss << "EP " << hex_string(entry_point->ep);
- ss << ", SP " << hex_string(entry_point->sp);
- if (entry_point->splim_set) ss << ", SPLIM " << hex_string(entry_point->splim);
- info_pair("entry point", ss.str());
- }
- }
-
- // Hash and Sig
- if (hash_verified != none) {
- info_pair("hash", hash_verified == passed ? "verified" : "incorrect");
- if (verbose_metadata) {
- std::shared_ptr hash_value = current_block->get_item();
- assert(hash_value != nullptr); // verify_block would return none if it's not present
- std::stringstream val;
- for(uint8_t i : hash_value->hash_bytes) {
- val << hex_string(i, 2, false, true);
- }
- info_pair("hash value", val.str());
- }
- }
- if (sig_verified != none) {
- info_pair("signature", sig_verified == passed ? "verified" : "incorrect");
- if (verbose_metadata) {
- std::shared_ptr signature = current_block->get_item();
- assert(signature != nullptr); // verify_block would return none if it's not present
- std::stringstream sig;
- for(uint8_t i : signature->signature_bytes) {
- sig << hex_string(i, 2, false, true);
- }
- info_pair("signature value", sig.str());
- std::stringstream pkey;
- for(uint8_t i : signature->public_key_bytes) {
- pkey << hex_string(i, 2, false, true);
- }
- info_pair("public key", pkey.str());
- }
- }
- };
// establish core groups and their order
- if (!settings.info.show_basic && !settings.info.all && !settings.info.show_metadata && !settings.info.show_pins && !settings.info.show_device && !settings.info.show_debug && !settings.info.show_build) {
+ if (!settings.info.show_basic && !settings.info.all && !settings.info.show_pins && !settings.info.show_device && !settings.info.show_debug && !settings.info.show_build) {
settings.info.show_basic = true;
}
if (settings.info.show_debug && !settings.info.show_device) {
settings.info.show_device = true;
}
auto program_info = group("Program Information", settings.info.show_basic || settings.info.all);
- auto no_metadata_info = group("Metadata Blocks", false);
- vector metadata_info;
- #define MAX_METADATA_BLOCKS 10
- for (int i=1; i <= MAX_METADATA_BLOCKS; i++) {
- // These groups are enabled later, depending on how many metadata blocks the binary has
- metadata_info.push_back(group("Metadata Block " + std::to_string(i), false));
- }
auto pin_info = group("Fixed Pin Information", settings.info.show_pins || settings.info.all);
auto build_info = group("Build Information", settings.info.show_build || settings.info.all);
auto device_info = group("Device Information", (settings.info.show_device || settings.info.all) & raw_access.is_device());
@@ -3210,16 +2833,11 @@ void info_guts(memory_access &raw_access, void *con) {
select_group(program_info);
select_group(pin_info);
select_group(build_info);
- for (auto mb : metadata_info) {
- select_group(mb);
- }
select_group(device_info);
binary_info_header hdr;
try {
- auto bi_access = get_bi_access(raw_access);
- bool has_binary_info = find_binary_info(*bi_access, hdr);
- if (has_binary_info) {
- auto access = remapped_memory_access(*bi_access, hdr.reverse_copy_mapping);
+ if (find_binary_info(raw_access, hdr)) {
+ auto access = remapped_memory_access(raw_access, hdr.reverse_copy_mapping);
auto visitor = bi_visitor{};
map