include $(TOPDIR)/rules.mk
PKG_NAME:=bcm27xx-utils
-PKG_VERSION:=2025.03.14
+PKG_VERSION:=2026.06.21
PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/raspberrypi/utils.git
-PKG_SOURCE_VERSION:=685afa8c0d6f2310eaefe1b528627a8bf3154ca0
-PKG_MIRROR_HASH:=04528742fc5b55ba31f448a27588a9df707cbcc27823c1d219b7f877dd4ac200
+PKG_SOURCE_VERSION:=61371fa6d93463c5451131f7bb68ae145aaf1e7a
+PKG_MIRROR_HASH:=412b9faad4d37580a8316e967da65dea8f85d1622ed588bed3f2080325d9b6c9
PKG_FLAGS:=nonshared
PKG_BUILD_FLAGS:=no-lto
define Package/bcm27xx-utils
SECTION:=utils
CATEGORY:=Utilities
- DEPENDS:=@TARGET_bcm27xx +libfdt
+ DEPENDS:=@TARGET_bcm27xx +libfdt +libncurses
TITLE:=BCM27xx scripts and simple applications
PROVIDES:=bcm27xx-userland
endef
Replaces bcm27xx-userland scripts and applications.
endef
+define Package/bcm27xx-utils-rpi-fw-crypto
+ SECTION:=utils
+ CATEGORY:=Utilities
+ DEPENDS:=bcm27xx-utils +libopenssl
+ TITLE:=BCM27xx rpi-fw-crypto application
+ PROVIDES:=rpi-fw-crypto
+ DEFAULT:=m if PACKAGE_bcm27xx-utils
+endef
+
+define Package/bcm27xx-utils-rpi-fw-crypto/description
+ A command line application and shared library for the firmware
+ cryptography service. Intended for use with Raspberry Pi Connect
+ and secure-boot provisioner.
+endef
+
+define Package/bcm27xx-utils-libpiolib
+ SECTION:=libs
+ CATEGORY:=Libraries
+ DEPENDS:=@TARGET_bcm27xx bcm27xx-utils
+ TITLE:=Raspberry Pi PIO userspace library (libpiolib)
+ PROVIDES:=libpiolib
+ DEFAULT:=n
+endef
+
+define Package/bcm27xx-utils-libpiolib/description
+ PIOlib/libPIO is a user-space API to the rp1-pio driver,
+ which gives access to the PIO hardware of RP1.
+endef
+
+CMAKE_OPTIONS += \
+ -DBUILD_SHARED_LIBS=0 \
+ -DCMAKE_INSTALL_PREFIX=/usr
+
+define Build/InstallDev
+ $(INSTALL_DIR) $(1)/usr/include/piolib
+ $(CP) $(PKG_INSTALL_DIR)/usr/include/piolib/*.h \
+ $(1)/usr/include/piolib/
+
+ $(INSTALL_DIR) $(1)/usr/include/piolib/hardware
+ $(CP) $(PKG_INSTALL_DIR)/usr/include/piolib/hardware/*.h \
+ $(1)/usr/include/piolib/hardware/
+
+ $(INSTALL_DIR) $(1)/usr/include/piolib/pico
+ $(CP) $(PKG_INSTALL_DIR)/usr/include/piolib/pico/*.h \
+ $(1)/usr/include/piolib/pico/
+
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libpio.so \
+ $(1)/usr/lib/
+endef
+
define Package/bcm27xx-utils/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/pinctrl $(1)/usr/bin
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/raspinfo $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/rpi-eeprom-ab $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/rpi-gpu-usage $(1)/usr/bin
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/vcgencmd $(1)/usr/bin
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/vclog $(1)/usr/bin
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/vcmailbox $(1)/usr/bin
endef
+define Package/bcm27xx-utils-rpi-fw-crypto/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/rpi-fw-crypto $(1)/usr/bin
+endef
+
+define Package/bcm27xx-utils-libpiolib/install
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libpio.so* $(1)/usr/lib/
+endef
+
$(eval $(call BuildPackage,bcm27xx-utils))
+$(eval $(call BuildPackage,bcm27xx-utils-rpi-fw-crypto))
+$(eval $(call BuildPackage,bcm27xx-utils-libpiolib))
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
- raspinfo/raspinfo | 186 ++++------------------------------------------
- 1 file changed, 13 insertions(+), 173 deletions(-)
+ raspinfo/raspinfo | 206 +++-------------------------------------------
+ 1 file changed, 11 insertions(+), 195 deletions(-)
--- a/raspinfo/raspinfo
+++ b/raspinfo/raspinfo
-@@ -1,4 +1,4 @@
--#!/bin/bash
-+#!/bin/sh
+@@ -8,173 +8,13 @@
- # Some of the regex's used in sed
- # Catch basic IP6 address "s/\([0-9a-fA-F]\{1,4\}:\)\{7,7\}[0-9a-fA-F]\{1,4\}/y.y.y.y.y.y.y.y/g"
-@@ -6,147 +6,6 @@
- # IP4 d.d.d.d decimal "s/\([0-9]\{1,3\}\.\)\{3,3\}[0-9]\{1,3\}/x.x.x.x/g"
- # mac address "s/\([0-9a-fA-F]\{2,2\}\:\)\{5,5\}[0-9a-fA-F]\{2,2\}/m.m.m.m/g"
+ alias filter="sed -e 's/\([0-9a-fA-F]\{1,4\}:\)\{7,7\}[0-9a-fA-F]\{1,4\}/y.y.y.y.y.y.y.y/g' | sed -e 's/[0-9a-fA-F]\{1,4\}:\(:[0-9a-fA-F]\{1,4\}\)\{1,4\}/y::y.y.y.y/g' | sed -e 's/\([0-9]\{1,3\}\.\)\{3,3\}[0-9]\{1,3\}/x.x.x.x/g' | sed -e 's/\([0-9a-fA-F]\{2,2\}\:\)\{5,5\}[0-9a-fA-F]\{2,2\}/m.m.m.m/g'"
--
-display_info_drm() {
-- # If running X then can use xrandr, otherwise
-- # dump the /sys/class entries for the displays
-- if command -v xrandr > /dev/null &&
-- DISPLAY=${DISPLAY:-:0} xrandr --listmonitors &>/dev/null;
-- then
-- echo "Running (F)KMS and X"
-- echo
--
-- DISPLAY=${DISPLAY:-:0} xrandr --verbose
-- else
-- echo "Running (F)KMS, console"
-- echo
--
-- for card in /sys/class/drm/card[0-9]-*;
-- do
-- echo $card
--
-- # if kmsprint isn't installed print basic mode info
-- if ! command -v kmsprint > /dev/null; then
-- if [ -f $card/modes ];
-- then
-- cat $card/modes
-- else
-- echo "No modes found"
-- fi
-- fi
--
-- if [ -f $card/edid ];
-- then
-- base64 $card/edid
-- else
-- echo "No EDID found"
-- fi
-- echo
-- done
-- fi
--
- # kmsprint is more useful, but not always installed
-- echo
- if command -v kmsprint > /dev/null; then
- kmsprint
- echo
- kmsprint -m
+- echo
+- kmsprint -p
- else
- echo "kmsprint is not installed. Install with: sudo apt install kms++-utils"
- fi
- echo
-
- # dump the /sys/class entries for the displays
+- for card in /sys/class/drm/card[0-9]-*;
+- do
+- echo $card
+-
+- if ! command -v kmsprint > /dev/null; then
+- if [ -f $card/modes ];
+- then
+- cat $card/modes
+- else
+- echo "No modes found"
+- fi
+- echo
+- fi
+-
+- if [ -f $card/edid ];
+- then
+- base64 $card/edid
+- else
+- echo "No EDID found"
+- fi
+- echo
+- done
+-
+- # dump the /sys/kernel/debug entries for the displays
- cardfound=0
- for card in `seq 0 9`;
- do
- if sudo test -f "/sys/kernel/debug/dri/${card}/state";
- then
-- for hdmi in 0 1;
-- do
-- if sudo test -f "/sys/kernel/debug/dri/${card}/hdmi${hdmi}_regs";
-- then
-- echo "HDMI${hdmi}: $(sudo cat /sys/kernel/debug/dri/$card/hdmi${hdmi}_regs | grep HOTPLUG)"
+- for hdmi in 0 1;
+- do
+- if sudo test -f "/sys/kernel/debug/dri/${card}/hdmi${hdmi}_regs";
+- then
+- echo "HDMI${hdmi}: $(sudo cat /sys/kernel/debug/dri/$card/hdmi${hdmi}_regs | grep HOTPLUG)"
+- fi
+- done
+- echo
+- # dump the state if we don't have kmsprint
+- if ! command -v kmsprint > /dev/null; then
+- echo "/sys/kernel/debug/dri/$card/state:"
+- sudo cat "/sys/kernel/debug/dri/$card/state"
+- echo
- fi
-- done
-- echo
-- echo "/sys/kernel/debug/dri/$card/state:"
-- sudo cat "/sys/kernel/debug/dri/$card/state"
-- echo
-- cardfound=1
+- cardfound=1
- fi
- done
-- if [ "$cardfound" == "0" ];
+- if [ "$cardfound" = "0" ];
- then
- echo "kms state not found"
+- echo
- fi
-- echo
--
-}
-
-display_info_legacy() {
- # Legacy mode
-- echo "Running Legacy framebuffer"
-- echo
--
- for card in `seq 0 9`;
- do
- F="/dev/fb${card}"
- fi
- done
-
-- disps=`tvservice -l | awk '/Display Number/{print substr($3,1,1)}'`
+- if command -v tvservice > /dev/null; then
+- disps=`tvservice -l | awk '/Display Number/{print substr($3,1,1)}'`
-
-- tmp=$(mktemp)
+- tmp=$(mktemp)
-
-- for display in $disps
-- do
-- echo
-- echo "Display: " $display
+- for display in $disps
+- do
+- echo
+- echo "Display: " $display
-
-- tvservice -v $display -s
-- tvservice -v $display -n
-- tvservice -v $display -m CEA
-- tvservice -v $display -m DMT
+- tvservice -v $display -s
+- tvservice -v $display -n
+- tvservice -v $display -m CEA
+- tvservice -v $display -m DMT
-
-- echo
-- tvservice -v $display -d $tmp > /dev/null
-- base64 $tmp
-- done
+- echo
+- tvservice -v $display -d $tmp > /dev/null
+- base64 $tmp
+- echo
+- done
-
-- rm $tmp
+- rm $tmp
+- else
+- echo "tvservice not installed"
+- fi
+-
+- if pgrep Xorg > /dev/null &&
+- command -v xrandr > /dev/null &&
+- DISPLAY=${DISPLAY:-:0} xrandr --listmonitors >/dev/null 2>&1; then
+- DISPLAY=${DISPLAY:-:0} xrandr --verbose
+- echo
+- fi
-}
-
-display_info() {
- # Check if we are running a KMS/DRM system
-
+- if [ -f /proc/device-tree/soc/firmwarekms@*/status ] &&
+- grep -q okay /proc/device-tree/soc/firmwarekms@*/status; then
+- KMS=fkms
+- elif [ -f /proc/device-tree/*/v3d@*/status ] &&
+- grep -q okay /proc/device-tree/*/v3d@*/status; then
+- KMS=kms
+- else
+- KMS=legacy
+- fi
+-
+- if pgrep labwc > /dev/null; then
+- WIN=labwc
+- elif pgrep wayfire > /dev/null; then
+- WIN=wayfire
+- elif pgrep Xorg > /dev/null; then
+- WIN=Xorg
+- else
+- WIN=console
+- fi
+- echo "Using $WIN with $KMS"
+-
- if [ -d "/dev/dri" ];
- then
- display_info_drm
- fi
-}
-
- OUT=raspinfo.txt
+ network_info() {
+ cat /proc/net/wireless 2>/dev/null || echo "/proc/net/wireless not available"
+ echo
+ if command -v rfkill >/dev/null; then
+ rfkill list
+ else
+- echo "rfkill not installed"
++ echo "rfkill not found"
+ fi
+ echo
+
+@@ -188,7 +28,7 @@ network_info() {
+ if [ -d "$iface/phy80211" ]; then
+ ethtool -i $iface_name
+ else
+- sudo ethtool $iface_name
++ ethtool $iface_name
+ echo
+ ethtool --show-eee $iface_name
+ echo
+@@ -198,7 +38,7 @@ network_info() {
+ fi
+ done
+ else
+- echo "ethtool not installed"
++ echo "ethtool not found"
+ fi
+ }
- rm -f $OUT
-@@ -163,8 +22,6 @@ echo
+@@ -222,8 +62,6 @@ echo
cat /etc/os-release | head -4
echo
uname -a
cat /proc/cpuinfo | tail -3
-@@ -190,17 +47,6 @@ echo
+@@ -260,18 +98,6 @@ echo
cat /proc/swaps
echo
-echo "Package version information"
-echo "---------------------------"
+-echo
-
-apt-cache policy raspberrypi-ui-mods | head -2
-apt-cache policy raspberrypi-sys-mods | head -2
echo "Networking Information"
echo "----------------------"
echo
-@@ -212,21 +58,11 @@ echo "USB Information"
+@@ -283,21 +109,11 @@ echo "USB Information"
echo "---------------"
echo
-
-audio_info
+if command -v lsusb > /dev/null; then
-+ lsusb -t
++ lsusb -t 2>&1
+else
-+ echo usbutils not installed
++ echo "usbutils not found"
+fi
echo
- echo "config.txt"
-@@ -250,7 +86,7 @@ echo "-----------------"
+ echo "Firmware Configuration"
+@@ -322,7 +138,7 @@ echo "-----------------"
echo
if command -v pinctrl > /dev/null; then
elif command -v raspi-gpio > /dev/null; then
raspi-gpio get 2>&1
else
-@@ -263,9 +99,9 @@ echo "------------------"
+@@ -335,9 +151,9 @@ echo "------------------"
echo
if command -v vcdbg > /dev/null; then
else
echo "vcdbg not found"
fi
-@@ -275,7 +111,7 @@ echo "dmesg log"
+@@ -347,16 +163,16 @@ echo "dmesg log"
echo "---------"
echo
--sudo dmesg | sed -e "s/\([0-9a-fA-F]\{1,4\}:\)\{7,7\}[0-9a-fA-F]\{1,4\}/y.y.y.y.y.y.y.y/g" | sed -e "s/[0-9a-fA-F]\{1,4\}:\(:[0-9a-fA-F]\{1,4\}\)\{1,4\}/y::y.y.y.y/g" | sed -e "s/\([0-9a-fA-F]\{2,2\}\:\)\{5,5\}[0-9a-fA-F]\{2,2\}/m.m.m.m/g"
-+dmesg | sed -e "s/\([0-9a-fA-F]\{1,4\}:\)\{7,7\}[0-9a-fA-F]\{1,4\}/y.y.y.y.y.y.y.y/g" | sed -e "s/[0-9a-fA-F]\{1,4\}:\(:[0-9a-fA-F]\{1,4\}\)\{1,4\}/y::y.y.y.y/g" | sed -e "s/\([0-9a-fA-F]\{2,2\}\:\)\{5,5\}[0-9a-fA-F]\{2,2\}/m.m.m.m/g"
-
+-sudo dmesg | filter
++dmesg | filter
- if grep -q "^Revision\s*:\s*[ 123][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]1[13457][0-9a-fA-F]$" /proc/cpuinfo
-@@ -284,5 +120,9 @@ echo
- echo "EEPROM"
- echo "------"
- echo
--sudo rpi-eeprom-update
-+if command -v rpi-eeprom-update > /dev/null; then
-+ rpi-eeprom-update
-+else
-+ echo bcm27xx-eeprom not installed
-+fi
- fi
+-if grep -q "^Revision\s*:\s*[ 123][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]1[13457][0-9a-fA-F]$" /proc/cpuinfo
++if grep -q "^Revision\s*:\s*[ 123][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]1[0-9][0-9a-fA-F]$" /proc/cpuinfo
+ then
+ echo
+ echo "EEPROM"
+ echo "------"
+ echo
+ if command -v rpi-eeprom-update > /dev/null; then
+- sudo rpi-eeprom-update
++ rpi-eeprom-update
+ else
+ echo "rpi-eeprom-update not found"
+ fi
+++ /dev/null
-From 5249e68da31d11e0beaf9fd76a6d17ac04198b26 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
-Date: Sat, 28 Dec 2024 09:42:00 +0100
-Subject: [PATCH] cmake: disable piolib
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
----
- CMakeLists.txt | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/CMakeLists.txt
-+++ b/CMakeLists.txt
-@@ -10,7 +10,7 @@ add_subdirectory(otpset)
- add_subdirectory(overlaycheck)
- add_subdirectory(ovmerge)
- add_subdirectory(pinctrl)
--add_subdirectory(piolib)
-+# add_subdirectory(piolib)
- add_subdirectory(raspinfo)
- add_subdirectory(vcgencmd)
- add_subdirectory(vclog)
--- /dev/null
+From 74a161cc45b1f68ff4735b31c37329a97e73ea2e Mon Sep 17 00:00:00 2001
+From: Joshua Covington <joshuacov@gmail.com>
+Date: Mon, 8 Jun 2026 22:46:01 +0000
+Subject: [PATCH 1/2] rpifwcrypto: switch from GnuTLS to OpenSSL
+
+Switch rpi-fw-crypto from GnuTLS to OpenSSL
+
+Signed-off-by: Joshua Covington <joshuacov@gmail.com>
+---
+ CMakeLists.txt | 9 +++---
+ rpifwcrypto/CMakeLists.txt | 8 +++---
+ rpifwcrypto/main.c | 57 +++++++++++++++++++++++---------------
+ 3 files changed, 43 insertions(+), 31 deletions(-)
+
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -22,11 +22,10 @@ add_subdirectory(vcgencmd)
+ add_subdirectory(vclog)
+ add_subdirectory(vcmailbox)
+
+-# Only build rpifwcrypto if GnuTLS is available
+-include(CheckIncludeFile)
+-check_include_file(gnutls/crypto.h HAVE_GNUTLS_CRYPTO_H)
+-if(HAVE_GNUTLS_CRYPTO_H)
++# Only build rpifwcrypto if OpenSSL is available
++find_package(OpenSSL QUIET)
++if(OpenSSL_FOUND)
+ add_subdirectory(rpifwcrypto)
+ else()
+- message(STATUS "gnutls/crypto.h not found - skipping rpifwcrypto")
++ message(STATUS "OpenSSL not found - skipping rpifwcrypto")
+ endif()
+--- a/rpifwcrypto/CMakeLists.txt
++++ b/rpifwcrypto/CMakeLists.txt
+@@ -10,8 +10,8 @@ endif()
+ # Set project name
+ project(rpifwcrypto)
+
+-# Find GnuTLS package
+-find_package(GnuTLS REQUIRED)
++# Find OpenSSL package
++find_package(OpenSSL REQUIRED)
+
+ option(BUILD_SHARED_LIBS "Build using shared libraries" ON)
+
+@@ -23,8 +23,8 @@ set_target_properties(rpifwcrypto PROPER
+
+ # Create the executable
+ add_executable(rpi-fw-crypto main.c)
+-target_link_libraries(rpi-fw-crypto rpifwcrypto ${GNUTLS_LIBRARIES})
+-target_include_directories(rpi-fw-crypto PRIVATE ${GNUTLS_INCLUDE_DIRS})
++# OpenSSL::Crypto automatically provides the correct include directories.
++target_link_libraries(rpi-fw-crypto PRIVATE rpifwcrypto OpenSSL::Crypto)
+
+ # Install rules
+ install(TARGETS rpi-fw-crypto RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
+--- a/rpifwcrypto/main.c
++++ b/rpifwcrypto/main.c
+@@ -2,7 +2,7 @@
+ #include <stdlib.h>
+ #include <string.h>
+ #include <stdint.h>
+-#include <gnutls/crypto.h>
++#include <openssl/evp.h>
+ #include "rpifwcrypto.h"
+
+ #define SHA256_HASH_SIZE 32
+@@ -69,53 +69,66 @@ static void usage(const char *progname)
+
+ static int hash_file(const char *filename, unsigned char *hash, size_t hash_size)
+ {
+- FILE *f;
+- gnutls_hash_hd_t hash_handle;
++ FILE *f = NULL;
++ EVP_MD_CTX *hash_ctx = NULL;
+ unsigned char buffer[4096];
+- unsigned char temp_hash[SHA256_HASH_SIZE];
++ unsigned char temp_hash[EVP_MAX_MD_SIZE];
++ unsigned int temp_hash_len = 0;
+ size_t bytes;
+- int rc;
++ int rc = -1;
+
+ if (hash_size < SHA256_HASH_SIZE) {
+ fprintf(stderr, "Hash buffer too small. Need at least %d bytes\n", SHA256_HASH_SIZE);
+ return -1;
+ }
+
+- if ((rc = gnutls_hash_init(&hash_handle, GNUTLS_DIG_SHA256)) < 0) {
+- fprintf(stderr, "Error initializing hash: %s\n", gnutls_strerror(rc));
++ hash_ctx = EVP_MD_CTX_new();
++ if (!hash_ctx) {
++ fprintf(stderr, "Error allocating hash context\n");
+ return -1;
+ }
+
++ if (EVP_DigestInit_ex(hash_ctx, EVP_sha256(), NULL) != 1) {
++ fprintf(stderr, "Error initializing SHA256 hash\n");
++ goto out;
++ }
++
+ f = fopen(filename, "rb");
+ if (!f) {
+ perror("Failed to open input file");
+- gnutls_hash_deinit(hash_handle, NULL);
+- return -1;
++ goto out;
+ }
+
+ while ((bytes = fread(buffer, 1, sizeof(buffer), f)) > 0) {
+- if ((rc = gnutls_hash(hash_handle, buffer, bytes)) < 0) {
+- fprintf(stderr, "Error updating hash: %s\n", gnutls_strerror(rc));
+- fclose(f);
+- gnutls_hash_deinit(hash_handle, NULL);
+- return -1;
++ if (EVP_DigestUpdate(hash_ctx, buffer, bytes) != 1) {
++ fprintf(stderr, "Error updating SHA256 hash\n");
++ goto out;
+ }
+ }
+
+ if (ferror(f)) {
+ perror("Error reading file");
+- fclose(f);
+- gnutls_hash_deinit(hash_handle, NULL);
+- return -1;
++ goto out;
+ }
+
+- fclose(f);
++ if (EVP_DigestFinal_ex(hash_ctx, temp_hash, &temp_hash_len) != 1) {
++ fprintf(stderr, "Error finalizing SHA256 hash\n");
++ goto out;
++ }
++
++ if (temp_hash_len != SHA256_HASH_SIZE) {
++ fprintf(stderr, "Unexpected SHA256 hash length: %u\n", temp_hash_len);
++ goto out;
++ }
+
+- /* Get the hash output, ensuring we don't write beyond the provided buffer */
+- gnutls_hash_deinit(hash_handle, temp_hash);
+- memcpy(hash, temp_hash, hash_size < SHA256_HASH_SIZE ? hash_size : SHA256_HASH_SIZE);
++ memcpy(hash, temp_hash, SHA256_HASH_SIZE);
++ rc = 0;
+
+- return 0;
++out:
++ if (f)
++ fclose(f);
++ EVP_MD_CTX_free(hash_ctx);
++ return rc;
+ }
+
+ static int write_hex_output_to_stream(FILE *f, const unsigned char *data, size_t len)
--- /dev/null
+From fc43ae46c05acfcc4d5ce74162bb171989db2c20 Mon Sep 17 00:00:00 2001
+From: Joshua Covington <joshuacov@gmail.com>
+Date: Mon, 8 Jun 2026 22:46:43 +0000
+Subject: [PATCH 2/2] piolib: make piolib a shared library
+
+Make PIOlib/libPIO a shared library.
+
+Signed-off-by: Joshua Covington <joshuacov@gmail.com>
+---
+ piolib/CMakeLists.txt | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/piolib/CMakeLists.txt
++++ b/piolib/CMakeLists.txt
+@@ -19,7 +19,7 @@ if (CMAKE_COMPILER_IS_GNUCC)
+ add_definitions (-ffunction-sections)
+ endif ()
+
+-add_library (pio piolib.c library_piochips.c pio_rp1.c)
++add_library (pio SHARED piolib.c library_piochips.c pio_rp1.c)
+ target_include_directories(pio PUBLIC include)
+ set_target_properties(pio PROPERTIES SOVERSION 0)
+
+@@ -34,7 +34,7 @@ set(INCLUDE_FILES
+ "pico/stdlib.h"
+ )
+
+-install(TARGETS pio ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT piolib)
++install(TARGETS pio LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT piolib)
+ foreach ( file ${INCLUDE_FILES} )
+ get_filename_component( dir ${file} DIRECTORY )
+ install( FILES "include/${file}" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/piolib/${dir}" COMPONENT piolib)