Skip to content

← Firmware Downloads

Post-install setup · Reborn (Y2Linux) · Y2

Platform Rust port — handoff (2026-10-29, updated after test build 170)

Debian-based Linux with a fast clickwheel interface for the Innioasis Y2.

Instructions published by the project, shown here word for word.

Platform Rust port — handoff (2026-10-29, updated after test build 170)

Update 2026-10-29 (afternoon): test build 170 is on the owner's player. The ten defects carried 1:1 are fixed (CONTRACT.md table), the Python reference platform (tools/platform) is deleted, its ≈630 unit tests are Rust tests (608 Rust tests in all), the differential harness is a golden suite against the Rust binary (tests/platform_golden.py, tests/platform_goldens/, 1 063 goldens recorded from Python), host tools live in tools/host/ and tools/production/. 170 (sequence 11150) was installed by the **first Rust `update stage/apply` on a player** (stage 8.8 s, apply to Acknowledged 86 s, application_ready 37.7 s) and Acknowledged; SFTP opens Internal Storage there (the fixed defect, checked over a real SFTP session). Owed: the owner's hardware checks (§6 A) on 170. Next after them: PLATFORM-RUST-REFACTOR-PLAN.md. Next free label 171, sequence above 11150. Sections below are from the port's end (build 169) where not updated.

Read this first when you pick the platform port up again. It says where things stand, where everything lives, how to build, test and install, what the owner decided, what is owed, and what we learned. The plan is PLATFORM-RUST-PORT-PLAN.md, the contract and the accepted differences are in platform/CONTRACT.md, and the device evidence is in roadmap-gap-audit.md (entries "PLATFORM-RUST phase 1", "phase 2 part 1", "phases 2–6").

1. Where it stands

2. What the owner decided

DateQuestionDecision
2026-10-28Where does the shared contract crate live?"deem as you think is best" → platform/crates/y2p-contract in Y2Linux (MIT); Y2Reborn vendors a copy stamped Y2LINUX-SOURCE; release.py sync-contract copies it, release.py build refuses a mismatch
2026-10-28Fix the defects found in the inventory during the port?"port 1:1 then fix … so that when the port is finished no more python is in the build and everything is rust" → ported unchanged, marked // DEFECT, fixed after the port (§6)
2026-10-28Overnight drain on the Python build first?Could not be done; the port went ahead without it
2026-10-29Scope"continue till all phases are done and python is removed from the platform"; "i will test that, but i want a full implementation" — the owner runs the hardware tests himself

3. Results on the player (169 against the Python platform on 165/166)

MeasurePythonRust (169)
Memory, 4 platform daemons58.4 MB RSS / 35.0 MB PSS15.2 MB RSS / 4.6 MB PSS
Idle CPU, 4 daemons91.8 s per hour19.6 s per hour (Wi-Fi on)
status --reborn --pss (Reborn's call)1.49 s0.48 s
capabilities / report status0.55 s / 1.0 s16 ms / 14 ms
Restart trail (shutdown steps)2.57 s0.46 s, every step in order
Boot to application_ready (plain restart)44.4 s36.8 s
Root file system130 MB111 MB

Measured with the idle sampler (600 s window, 11 samples) and the restart/boot trail, as in plan §7. Per daemon on 169: power-daemon 9.1 s/h, service-daemon 8.1 s/h, ssh-daemon 2.4 s/h, connectivity-daemon 0.2 s/h; each 3.3–4.2 MB RSS. Reborn itself (45 s/h, 26.7 MB) is now the largest consumer. On 173 (screen off, charging, 300 s): Reborn 19.0 s/h (main thread 9.4, watchdog 3.4), ~34 process starts/min (≈140 on 172: the Wi-Fi look's wpa_cli/ip are gone), rebornctl metrics 0.01 s instead of ≈0.36 s (Reborn's control thread answers it).

4. Where everything lives

5. How to build, test and install

Host check (≈1 min; builds the host binary, type-checks for armv7, runs the release-gate modules with the Rust comparison on):

tools/development/host-tests.sh

Only the platform:

cd platform && cargo test --offline --locked && cargo clippy --offline --locked
cd platform && cargo check --offline --locked --target armv7-unknown-linux-gnueabihf
Y2_PLATFORM_RUST=$PWD/platform/target/debug/y2-platform python3 -m unittest tests.test_platform_differential
tools/development/host-tests.sh tests.test_platform_differential tests.test_platform_argparse …  # only these

Harness environment contract: Y2_ROOT (fixture root), Y2_FIXTURE_COMMANDS (subprocess answers), Y2_FIXTURE_CALLS (recorded requests), Y2_DAEMON_TICKS (bounded daemon loops), Y2_FIXTURE_TOKEN (update staging token), Y2_PLATFORM_RUST (the host build the goldens are checked against; skipped without it), Y2_RECORD_GOLDENS=1 (re-record the goldens that differ), Y2_ARGPARSE_ECHO (prints the parse, only below a fixture root).

After changing Y2Linux's contract crate: python3 tools/production/release.py sync-contract, then commit Reborn (with the identity env vars, see §8).

Test build (do not touch the Y2Linux tree while it runs):

Y2_STOCK_PACKAGE=$PWD/donorSource/y2_v3.2.0_FM-20260813 python3 tools/production/release.py build --label 170

Add --clean after enabling/disabling a Buildroot package (a disabled package stays in the target otherwise). Output: out/release-170/{ota,update,first-install,assets,receipts,summary.json}.

Install on the player (staged OTA only; player at 10.42.0.1 over USB networking):

Y2="ssh -F /dev/null -o HostKeyAlias=y2linux-production-v1 -o BatchMode=yes -i ~/.ssh/y2linux_ed25519 [email protected]"
$Y2 'rm -rf /data/updates/owner-169; mkdir -p /data/updates/owner-170'
scp -F /dev/null -o HostKeyAlias=y2linux-production-v1 -i ~/.ssh/y2linux_ed25519 -q out/release-170/ota/* [email protected]:/data/updates/owner-170/
$Y2 'y2-platform update stage --package /data/updates/owner-170; y2-platform update apply'

After the restart: y2-platform update status must show Acknowledged; check the supervisor logs are empty and ps shows /usr/sbin/y2-platform <name>-daemon for the four daemons.

6. What is owed

A. The owner's hardware tests (now on 170) (sleep, battery and charging are now Rust, so these matter most):

  1. Several sleep/wake cycles, then two overnight runs off the charger — the drain comparison (Python reference:

    Beta 6.3 ≈7.8 mA, Beta 1 ≈9.4 mA; read the power journal afterwards).

  2. Low battery all the way to power-off.
  3. Charger plug/unplug, awake and asleep; power off on a charger (must open the charging screen, F46).
  4. SD card insert, remove and Repair; Internal Storage; copying over MTP; SSH/SFTP.
  5. An OTA from 170 to the next build, and a rollback (169 → 170 by OTA worked).
  6. Save and send an error report (upload now goes through curl).
  7. Wi-Fi join and a wrong password; Bluetooth headphones.

B. DONE 2026-10-29: the defects carried 1:1 are fixed, each with a test and the goldens re-recorded (CONTRACT.md has the fix per row; the table below is the original list, its line numbers are gone).

DefectWhere
SFTP never roots at Internal Storage: usr/libexec/sftp-server greps "state": "Ready" but the record is compact ("state":"Ready") — confirmed on the playerthe script, not Rust
media status exits 1 for a Degraded card; media write exits 0 with failure for not_mountedcommands/storage/mod.rs:213
A second update check/stage meeting the busy .stage.lock overwrites download.json with Failed [Errno 11] while the first download continuescommands/service/update.rs:769
update rollback asks the core before the battery gate: a battery refusal leaves the journal RollbackPendingcommands/service/update.rs:1265
update auto-check prints null when nothing was duecommands/service/update.rs:1548
firmware scan exits 0 with install errorscommands/service/radiofw.rs:761
Battery: after a sample with BAT0 capacity and then one without, ui is None (found during the port)commands/power/battery.rs:318
An expired media write window is re-protected only when a reconcile runs, which is skipped when nothing changedstorage reconcile; device check owed
A DHCP renew deletes dns.json: Wi-Fi may show dns_unavailable for up to 300 sconnectivity, dhcp-event

Callers rely on some of these exit codes (Reborn, scripts): check every caller (CONTRACT.md "Callers") before changing one.

C. After the fixes: plan §9 for later work (plugin SDK, platform_api_version 2). The host tests no longer use the Python reference (tools/platform): the goldens were recorded from it.

D. Smaller follow-ups:

7. Lessons from the port

8. Rules that still apply

Published by the schulzcode/y2linux project [1] [3]