DIY Tools: Verification & Mount Log
The smartcard profiles ship a diy-tools.squashfs on the boot partition containing everything needed to fabricate and program a Satochip JavaCard at home (Java JDK, Ant, Satochip-DIY source). When a microSD is inserted, an mdev hook automatically verifies and mounts it at /mnt/diy.
Where the squashfs comes from
The image is built reproducibly by the seedsigner-diy-tools repository and published as a tagged GitHub Release artifact (diy-tools-<arch>.squashfs, where <arch> is armhf for Raspberry Pi boards or aarch64 for La Frite). The OS build downloads the pinned release and verifies it against a hardcoded SHA-256 before placing it on the boot partition.
Runtime verification (fail-closed)
On every microSD insert, /etc/mdev/mdev.sh (source: opt/rootfs-overlay/etc/mdev/mdev.sh):
- Mounts the microSD at
/mnt/microsd. - Computes the SHA-256 of
diy-tools.squashfsby reading the file directly (not via a stat/existence check — on 32-bit kernels,stat()of a FAT file dated after 2038 returnsEOVERFLOW, which would wrongly report the file as missing). - Compares it against the pinned hash for this device’s architecture in
/etc/diy-tools.sha256. - Mounts the squashfs at
/mnt/diyonly if the hashes match. Any other outcome (file absent, hash mismatch, missing pin file) refuses to mount — an unverified image is never mounted.
The microSD itself is mounted noexec,nosuid,nodev (untrusted removable media; see AGENTS.md). The /mnt/diy squashfs mount is deliberately left without those options: its content is trusted by construction via the pinned hash, and the tools inside (JDK/Ant) may need to be executed.
The log: /tmp/diy-mount.log
Every insert/remove appends to /tmp/diy-mount.log. Notes for reading it:
- It lives on tmpfs, so it is wiped on reboot. A missing file means “no mount events since boot”, not a failure.
- Human-readable lines are prefixed with a timestamp (e.g.
Thu Aug 27 00:30:11 UTC 2026). - Each event ends with one machine-readable result block starting at the marker line
=== diy-tools result ===. The last complete block in the file is the current state; earlier blocks are history from previous card insertions. - Block lines are plain
key=valuepairs (no timestamp). Values may contain spaces but never newlines.
Result fields
| Field | Meaning | Present when |
|---|---|---|
status | One of the statuses below — always present in a complete block | always |
reason | Short human explanation of the outcome | always |
arch | Architecture key used to look up the pinned hash (armhf / aarch64) | everything except MICROSD_MOUNT_FAILED |
computed | SHA-256 of the file actually on the card | whenever the file was readable |
pinned | Expected SHA-256 from /etc/diy-tools.sha256 | whenever a pinned value exists |
detail | One line of error text (e.g. why the file couldn’t be read) | NOT_PRESENT only |
dev | The device node that failed to mount | MICROSD_MOUNT_FAILED only |
mount | Mount point (/mnt/diy) | OK only |
Statuses, in plain English
| status | What happened | What to do about it |
|---|---|---|
OK | Hash matched; squashfs is mounted at /mnt/diy. The reason notes it if expected entries (jdk, ant, Satochip-DIY) are missing from inside. | Nothing — DIY tools are available. |
REFUSED_HASH_MISMATCH | A diy-tools.squashfs exists on the card but its hash does not match the pinned value, so it was not mounted. The block shows both hashes: computed (what’s on your card) and pinned (what this OS expects). Typical causes: a squashfs built for the wrong architecture, a modified/tampered card, or an older image carrying an outdated file. | Re-flash the image, or replace the file with the matching diy-tools-<arch>.squashfs from the pinned release of seedsigner-diy-tools. Compare computed against the release’s published hash to see which side is wrong. |
NOT_PRESENT | No readable diy-tools.squashfs on the card (detail shows the exact read error). | Put a verified squashfs at the root of the boot partition, or re-flash. |
HASH_FILE_MISSING | The OS image itself is missing /etc/diy-tools.sha256. This indicates a broken/incomplete image build. | Rebuild/re-flash from a good commit. |
NO_PINNED_HASH | The pin file exists but has no entry for this device’s architecture. | Image/build mismatch — rebuild or re-flash. |
MOUNT_FAILED | Hash verified fine, but mounting the squashfs failed (e.g. kernel lacks the needed squashfs compression support). | Check the kernel config (CONFIG_SQUASHFS_*) for the board; report if unexpected. |
MICROSD_MOUNT_FAILED | The microSD partition itself could not be mounted at all (dev shows which node). | Check the card/partition (FAT32, boot partition) and try another card. |
Examples
Success:
Thu Aug 27 00:30:11 UTC 2026 ADD /dev/mmcblk1p1: mounting microsd
=== diy-tools result ===
status=OK
reason=diy-tools verified and mounted at /mnt/diy
arch=armhf
computed=22e289c2caa58ed4d460735b03155a57537fa7e29b354ca4fc72a508fe3bdff8
pinned=22e289c2caa58ed4d460735b03155a57537fa7e29b354ca4fc72a508fe3bdff8
mount=/mnt/diy
Hash mismatch — the file on the card is not the verified one:
Thu Aug 27 01:02:44 UTC 2026 ADD /dev/mmcblk1p1: mounting microsd
=== diy-tools result ===
status=REFUSED_HASH_MISMATCH
reason=diy-tools.squashfs hash does not match the pinned value; refusing to mount an unverified image
arch=armhf
computed=deadbeef0000c0ffee...
pinned=22e289c2caa58ed4d460735b03155a57537fa7e29b354ca4fc72a508fe3bdff8
Multiple events — the last block is the current state (card removed, re-inserted without the file):
Thu Aug 27 00:30:11 UTC 2026 ADD /dev/mmcblk1p1: mounting microsd
=== diy-tools result ===
status=OK
reason=diy-tools verified and mounted at /mnt/diy
arch=armhf
computed=22e289c2caa58ed4d460735b03155a57537fa7e29b354ca4fc72a508fe3bdff8
pinned=22e289c2caa58ed4d460735b03155a57537fa7e29b354ca4fc72a508fe3bdff8
mount=/mnt/diy
Thu Aug 27 00:45:02 UTC 2026 REMOVE /dev/mmcblk1p1: unmounting
Thu Aug 27 00:45:30 UTC 2026 ADD /dev/mmcblk1p1: mounting microsd
=== diy-tools result ===
status=NOT_PRESENT
reason=no readable diy-tools.squashfs on microSD
arch=armhf
detail=sha256sum: can't open '/mnt/microsd/diy-tools.squashfs': No such file or directory
Viewing the log
- Dev builds (SSH enabled):
cat /tmp/diy-mount.logover SSH. - Non-dev builds are headless and air-gapped; the SeedSigner application reads this file itself to report the DIY-tools status in the UI, so no shell access is needed.