- otppad_embedded: bit-compatible port of libotppad (2386/2386 host tests pass) - otp_pad_sd: SdFat-direct SD card pad reader (FAT-only, ASCII armor + binary .otp) - pad_gen.ino: TRNG-sourced 1 MB pad generator using i.MX RT1062 TRNG registers - Linker script: moved .rodata from DTCM to FLASH (EXCLUDE_FILE ed25519), reclaiming 124 KB DTCM, free stack 5.9 KB -> 130.9 KB - check_stack.sh: build-time FlexRAM stack gauge, wired into build_signer.sh - test_otp_sd.py: 8/9 hardware tests pass (ASCII + binary round-trips, offset advance, tamper detection; 10 KB plaintext times out on perf) - test_classical.py: 16/16 pass with new memory layout (ed25519 OK) - Memory evaluation document: plans/teensy41_memory_evaluation.md
100 lines
3.8 KiB
Bash
Executable File
100 lines
3.8 KiB
Bash
Executable File
#!/bin/bash
|
|
# build_signer.sh — reproducible build + optional flash for the Teensy 4.1 n_signer.
|
|
#
|
|
# Usage:
|
|
# ./firmware/teensy41/build_signer.sh # compile only
|
|
# ./firmware/teensy41/build_signer.sh --flash # compile + upload
|
|
# ./firmware/teensy41/build_signer.sh --test # compile + upload + run test suite
|
|
#
|
|
# This script handles:
|
|
# - Copying lv_conf.h to the Arduino libraries directory (where LVGL's
|
|
# lv_conf_internal.h searches for it via ../../lv_conf.h).
|
|
# - Passing the custom linker script (imxrt1062_t41_flashmem.ld) that routes
|
|
# crypto code to FLASH instead of ITCM, freeing stack space.
|
|
# - Printing the memory usage report.
|
|
# - Optionally uploading to the first discovered Teensy port.
|
|
# - Optionally running the hardware test suite.
|
|
|
|
set -e
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
SIGNER_DIR="$SCRIPT_DIR/signer"
|
|
FQBN="teensy:avr:teensy41"
|
|
LV_CONF_SRC="$SIGNER_DIR/lv_conf.h"
|
|
LV_CONF_DST="$HOME/Arduino/libraries/lv_conf.h"
|
|
LINKER_SCRIPT="$SIGNER_DIR/imxrt1062_t41_flashmem.ld"
|
|
|
|
# --- Step 1: Copy lv_conf.h to the Arduino libraries directory ---
|
|
if [ -f "$LV_CONF_SRC" ]; then
|
|
mkdir -p "$(dirname "$LV_CONF_DST")"
|
|
cp "$LV_CONF_SRC" "$LV_CONF_DST"
|
|
echo "[build] Copied lv_conf.h to $LV_CONF_DST"
|
|
else
|
|
echo "[build] WARNING: $LV_CONF_SRC not found — LVGL may use default config."
|
|
fi
|
|
|
|
# --- Step 2: Compile with the custom linker script ---
|
|
echo "[build] Compiling..."
|
|
LINKER_FLAG="-Wl,--gc-sections,--relax,--no-warn-rwx-segments -T${LINKER_SCRIPT}"
|
|
|
|
if [ -f "$LINKER_SCRIPT" ]; then
|
|
arduino-cli compile \
|
|
--fqbn "$FQBN" \
|
|
--build-property "build.flags.ld=${LINKER_FLAG}" \
|
|
"$SIGNER_DIR" || true # size-determination step may error with custom .ld
|
|
else
|
|
echo "[build] WARNING: Linker script not found at $LINKER_SCRIPT — using default."
|
|
arduino-cli compile --fqbn "$FQBN" "$SIGNER_DIR"
|
|
fi
|
|
|
|
# --- Step 2b: FlexRAM stack gauge ---
|
|
# arduino-cli's "Error while determining sketch size" with a custom linker
|
|
# script is non-fatal (the ELF is produced), but it means we lose the built-in
|
|
# memory report. Run our own gauge against the ELF to catch DTCM stack
|
|
# overflows that the linker cannot detect (the ITCM/DTCM split is computed at
|
|
# boot, not link time).
|
|
ELF_FILE=$(find "$HOME/.cache/arduino/sketches" -name "signer.ino.elf" -newer "$LINKER_SCRIPT" 2>/dev/null | head -1)
|
|
if [ -z "$ELF_FILE" ]; then
|
|
ELF_FILE=$(find "$HOME/.cache/arduino/sketches" -name "signer.ino.elf" 2>/dev/null | head -1)
|
|
fi
|
|
if [ -n "$ELF_FILE" ] && [ -f "$ELF_FILE" ]; then
|
|
echo "[build] Running FlexRAM stack gauge..."
|
|
bash "$SCRIPT_DIR/check_stack.sh" "$ELF_FILE" 16384 || {
|
|
echo "[build] ❌ Stack gauge FAILED — refusing to flash. See check_stack.sh output above."
|
|
exit 1
|
|
}
|
|
else
|
|
echo "[build] WARNING: could not find signer.ino.elf for stack gauge — skipping."
|
|
fi
|
|
|
|
echo "[build] Compilation successful."
|
|
|
|
# --- Step 3: Find the Teensy port ---
|
|
find_teensy_port() {
|
|
arduino-cli board list 2>/dev/null | grep 'teensy Teensy Ports' | awk '{print $1}' | head -1
|
|
}
|
|
|
|
# --- Step 4: Flash (if --flash or --test) ---
|
|
if [ "$1" = "--flash" ] || [ "$1" = "--test" ]; then
|
|
PORT=$(find_teensy_port)
|
|
if [ -z "$PORT" ]; then
|
|
echo "[flash] No Teensy found. Press the PROGRAM button on the Teensy."
|
|
exit 1
|
|
fi
|
|
echo "[flash] Uploading to $PORT..."
|
|
arduino-cli upload -p "$PORT" --fqbn "$FQBN" "$SIGNER_DIR"
|
|
echo "[flash] Upload complete."
|
|
fi
|
|
|
|
# --- Step 5: Run test suite (if --test) ---
|
|
if [ "$1" = "--test" ]; then
|
|
echo "[test] Waiting for device to boot..."
|
|
sleep 4
|
|
PORT_DEV=$(arduino-cli board list 2>/dev/null | grep 'ttyACM' | awk '{print $1}' | head -1)
|
|
if [ -z "$PORT_DEV" ]; then
|
|
PORT_DEV="/dev/ttyACM0"
|
|
fi
|
|
echo "[test] Running test suite on $PORT_DEV..."
|
|
python3 "$SCRIPT_DIR/test_signer.py" --port "$PORT_DEV" || true
|
|
fi
|