#!/bin/sh # som-provenance-f7 -- write the record som-mfg-f7 checks an STM32F7 SOM image # against, read from the image itself: U-Boot's banner and the prompt it carries, # or a uImage's name and size; with the file's sha256 and where it came from. set -u PROG=som-provenance-f7 F7_DIR="${SOM_FIRMWARE_DIR:-/usr/share/brintos-som/stm32f7}" usage() { cat </dev/null)) Each record also gives the file's sha256 and size. A U-Boot's record is named PROVENANCE, one per directory, so keep one U-Boot per directory. Exit status: 0 every record written, 1 a file refused, 2 usage. EOF } origin="" prompt="" while [ $# -gt 0 ]; do case "$1" in --origin) [ $# -ge 2 ] || { usage >&2; exit 2; }; origin=$2; shift 2 ;; --prompt) [ $# -ge 2 ] || { usage >&2; exit 2; }; prompt=$2; shift 2 ;; -h|--help) usage; exit 0 ;; --) shift; break ;; -*) echo "$PROG: unknown argument: $1" >&2; usage >&2; exit 2 ;; *) break ;; esac done [ $# -gt 0 ] || { usage >&2; exit 2; } [ -n "$origin" ] || origin="recorded on this station by $PROG, $(date -u '+%Y-%m-%d %H:%M:%S UTC')" rc=0 refuse() { echo "$PROG: $1: refused -- $2"; rc=1; } # The printable runs of a binary, one a line, as strings(1) prints them. Spelled # as a range: busybox tr has no [:print:] class. runs() { LC_ALL=C tr -c ' -~' '\n' < "$1"; } for f in "$@"; do if [ ! -f "$f" ] || [ ! -r "$f" ]; then refuse "$f" "not a readable file"; continue fi case "$(cd "$(dirname "$f")" && pwd -P)" in "$(cd "$F7_DIR" 2>/dev/null && pwd -P)") refuse "$f" "a built-in image: its record ships with it"; continue ;; esac size=$(stat -L -c %s "$f") sum=$(sha256sum "$f" | cut -d' ' -f1) # busybox's small od takes no -A, -t or -N. magic=$(dd if="$f" bs=4 count=1 2>/dev/null | od -b | sed -n '1{s/^[0-7]*//;s/ //g;p;}') if [ "$magic" = 047005031126 ]; then name=$(dd if="$f" bs=1 skip=32 count=32 2>/dev/null | tr '\000' '\n' | sed -n 1p) if [ -z "$name" ]; then refuse "$f" "its uImage header names no image"; continue fi rec=$f.PROVENANCE body="image: $(basename "$f") target: Emcraft STM32F7 SOM, NOR, written by U-Boot's update over TFTP version: $name origin: $origin sha256: $sum size: $size bytes" else banner=$(runs "$f" | sed -n '/^U-Boot 20[0-9][0-9]\./{p;q;}') if [ -z "$banner" ]; then refuse "$f" "neither a uImage nor a U-Boot: it carries no \"U-Boot 20...\" banner"; continue fi p=$prompt [ -n "$p" ] || p=$(sed -n 's/^prompt: *//p' "$F7_DIR/PROVENANCE" 2>/dev/null) if [ -z "$p" ]; then refuse "$f" "no prompt to record: give it with --prompt"; continue fi if ! runs "$f" | grep -q -F -- "$p"; then refuse "$f" "it does not carry the prompt '$p', so som-mfg-f7 would wait for it in vain: give its own with --prompt"; continue fi rec=$(dirname "$f")/PROVENANCE body="image: $(basename "$f") target: Emcraft STM32F7 SOM (STM32F756), eNVM at 0x08000000 version: $banner prompt: $p origin: $origin sha256: $sum size: $size bytes" fi [ -e "$rec" ] && echo "$PROG: replacing $rec" if ! printf '%s\n' "$body" > "$rec"; then refuse "$f" "cannot write $rec"; continue fi echo "$PROG: $rec" sed 's/^/ | /' "$rec" done exit $rc