BFE EngineeringandClaude Opus 4.8 5e1b02ba60 kernel-build: apply patches outside the checkout + fail-loud sentinel (#1)
The kernel-build job set WORK inside the repo checkout, so build-kernel.sh's
`git apply` ran from a subdirectory of the warden-sdk git repo — where git apply
silently ignores out-of-subdir paths and exits 0 without applying anything. The
build then failed at the (never-created) rv1106-warden.dtb target, and the
unconditional `echo "applied"` had masked it.

- ci.yml: WORK -> ${{ runner.temp }}/kbuild-out (outside the checkout); artifact
  paths follow.
- build-kernel.sh: the patch loop now fails loudly instead of echoing on silent
  failure, and a post-apply sentinel assert (rv1106-warden.dts must exist) makes a
  silent no-op impossible to ship — the regression guard for this class.

Refs #1.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017wB8KB3MMQztRDXCMCkPrf
2026-08-25 16:55:46 -06:00
2026-08-25 13:46:08 -06:00

warden-sdk

ci Lines of code Tests Coverage

The build, driver, and simulation SDK for WardenOS (the Luckfox Pico 86-Panel / RV1106 HMI). A from-scratch replacement for the twice-ported vendor stack (Rockchip SDK → Luckfox SDK → our patched fork), built to the same standard as the rest of the firmware: tested, benchmarked, reproducible, and honest about what runs on real silicon versus what we simulate.

Status: bringup. The hardware simulator and its tests, the RV1106 kernel forward-port as a reviewable patches/ series, the hermetic kernel build, and two Tier-1 drivers at 100% MC/DC are all in and CI-green on main. What remains before this is on the production build path: installing the self-hosted kernel-build runner (see docs/ci-cd.md) and having flare-edge consume warden-sdk as a dependency — both [maintainer]-gated. Until then, flare-edge still builds firmware from the vendored SDK + sdk-patches/.

Why a new SDK

The vendored SDK is a ~2 GB opaque fork of a fork. Our real changes to it lived, until recently, as uncommitted edits in one working copy (flare-edge/sdk-patches/ is the tracked form). It bakes absolute paths, needs python (not python3), silently drops Kconfig options, and — the failure that motivated this repo — gives us no way to test hardware-dependent code off the device. Every driver change had to be validated by flashing a panel. That is slow, and it is dangerous: it is how a boot-loaded-watchdog change bricked a bench unit (the load address collided with unreserved kernel RAM — a mistake a target-config check or a memory-map model would have caught before any flash).

The SDK's job is to make the firmware buildable, testable, and hardenable without a panel in the loop, and to move us onto a modern, maintained kernel.

Goals (from future-features)

  1. Modern kernel. A self-built Linux 6.18.46, forward-ported directly from the vendor 5.10.160 tree (no plan44/OpenWrt code) on our current Buildroot LTS (2025.02.x). This is done and hardware-verified on warden-c8a3: essentially every RV1106 block the 86-Panel uses boots and works — clk, pinctrl, eMMC, GMAC, TRNG, OTP, SARADC/TSADC, RTC, USB host, PWM/backlight, VOP display, GT911 touch, AIC8800 wifi, RGA, I2S audio, HPMCU mailbox, the open NPU driver, and PVTM. Mainline was not viable (no DT/clk/display/RGA/NPU/ flash-boot upstream for RV1106); the direct 5.10→6.18 forward-port reuses the already-in-mainline rv1126 register data where it matches and carries our deltas as a reviewable patch series (patches/).
  2. Ported, hardened drivers → 100% MC/DC on the code we own. "100% MC/DC on 100% of drivers" is infeasible as literally stated: ~97% of driver LOC is vendor blobs (the AIC8800 wifi driver alone is 88.5K lines). So the target is tiered: real MC/DC on our hardware code (modbus master, relays, RGA wrapper, HPMCU supervisor, devmem/reset ladder); fault-injection + branch hardening for the vendor blobs behind a stable seam.
  3. A proper simulator. Simulate the hardware the vendor SDK cannot: RGA (2D blitter), the RISC-V HPMCU coprocessor, and the NPU — plus the register/SRAM (/dev/mem) and sysfs surfaces the drivers touch — so driver and supervisor logic runs and is tested on the host, in CI, with no panel.
  4. Its own repo, held to firmware standards. Tests, benchmarks, reproducible builds, CI. This repo.

Architecture — one seam, two backends

The organizing idea is a thin Hardware Abstraction Seam per hardware block. Firmware code talks to the seam (a trait in Rust, a function table in C); the seam has two backends:

        firmware / driver logic
                  │
          Hardware Abstraction Seam        (devmem, hpmcu, rga, npu, modbus, gpio)
             ┌────┴────┐
        real backend   sim backend
      (/dev/mem, ioctl, (software model,
       /proc, serial)    host-testable)
  • On-device, the seam binds the real backend (mmap /dev/mem, librga ioctls, the serial port, /proc/rknpu).
  • On the host, it binds the sim backend — a faithful software model of the block. The HPMCU sim, for example, runs the SCR1 watchdog firmware's exact state machine (boot-grace, heartbeat-timeout, fire) against an in-memory mailbox, so the flared supervisor's arm/beat protocol is exercised end-to-end in a unit test.

The seam is the same object the driver-hardening effort measures MC/DC against, and the same object the simulator implements — so the two goals reinforce rather than duplicate each other.

Layout

sim/        the hardware simulator (Rust): membus/devmem, HPMCU, CRU, Modbus, RGA, NPU.
drivers/    our own hardened drivers + their seams (relays, freshness; more migrate in).
patches/    the RV1106 kernel forward-port delta onto pristine linux-6.18.46 (subsystem-split).
kernel/     forward-port docs + provenance (rv1106-enablement/, PROVENANCE.md).
build/      the hermetic kernel build (fetch pristine → apply patches → zImage + dtb).
docs/       architecture + ADRs (decisions/) + ci-cd + generated workflow flowcharts.
tools/      dev tooling. config-lint: static target-config gates (MCU-load-vs-reserved-memory,
            the 0x40000 brick class); flowgen: the workflow-flowchart generator.
.github/    CI (workflows/ci.yml): patches-apply, host tests, coverage, MC/DC, benchmarks, badges.

Principles

Evaluated against the stack philosophy — openness, hardness, modernness:

  • Open over closed where we can: rkdeveloptool over the closed upgrade_tool; source-buildable librga over blobs where a source path exists; the simulator is fully open and ours.
  • Hard: every seam has a fault-injection path (a wedged SDIO link, a stalled MCU, an RGA timeout) so recovery code is tested against failure, not just success. On-device claims still need on-device evidence; the sim narrows which claims need a panel, it does not replace that rule.
  • Modern: newest kernel we can actually run; current Buildroot LTS; Rust for new host-testable code; reproducible builds.

Relationship to flare-edge

flare-edge (WardenOS: the LVGL UI + the flared daemon) is the product; warden-sdk is what builds and tests it. During bootstrap, flare-edge consumes warden-sdk piece by piece: first the simulator (as a dev/test dependency), later the image build. No flare-edge code moves here — only the SDK/build/sim/driver-seam layer.

S
Description
No description provided
Readme GPL-2.0
2.1 MiB
Languages
C 52%
Rust 22.9%
Shell 15.9%
Python 4.2%
Makefile 2.4%
Other 2.6%