Return-to-root roadmap — landing the reshaped kernel as THE kernel¶
Status: LIVING migration state (reconciled 2026-08-19). Return-to-root has landed:
the reshaped core is the repository root, and the pre-reshape tree is archived read-only
under _legacy/. This document tracks what has re-attached and what has not yet been
ported forward — it is the companion to docs/requirements.md (the north star) and the
two accepted decisions docs/decisions/0001 / 0002.
1. Why this document¶
The reshape was built in isolation in sketches/kernel-reshape/ deliberately — a clean
rebuild of the kernel core (arch / boards / kernel / make / profiles / examples)
whose thesis is discharged: portable across two switch models (deferred-PendSV + trap-frame),
privilege-parametric (M/S mode), SMP on two arches, and freedom-from-interference proven on
three mechanisms (ARM MPU, RISC-V PMP, RISC-V Sv32 paging).
That sketch has now become the root. The migration is not more kernel design — it is a
re-attachment effort: the reshaped core is promoted to <root>/kernel + <root>/arch, and
the reuse layers (HAL, devices, drivers, tools, tests) are being reconnected on top, forward-
ported against the reshaped API rather than moved as-is. This is integration work, and the real
finish line.
The reuse layers listed below carry file/LOC counts from the _legacy/ tree — they measure
the size of the port-forward job, not what is at root today (most of these are not yet at
root; see §5):
|
Files / LOC |
Nature |
Verdict |
At root? |
|---|---|---|---|---|
|
40 / 2701 |
MCAL + HAL (Option-C resolver, instance model) |
Reuse (composability I1) |
Partial — a slim |
|
13 / 9174 |
|
Reuse — kernel-agnostic |
No — root |
|
19 / 1670 |
host unit tests |
Reuse + extend |
No — no |
|
12 / 1122 |
PN532, sensors, device drivers |
Reuse — sit on HAL |
No — no |
|
6 / 391 |
board-agnostic |
Reuse — one kernel touchpoint |
No — no |
|
5 / 370 |
trust-chain / heartbeat / secure-boot glue |
Reuse |
Partial — only |
|
203 / 13613 |
every board port |
Selective |
Partial — 4 reshaped boards landed |
|
18 / 4349 |
the pre-reshape kernel |
Superseded by the reshaped core |
Superseded — reshaped |
|
19 / 4298 |
pre-reshape arch ports |
Superseded where a reshaped port exists |
Superseded — reshaped |
2. The load-bearing risk: API drift¶
The reuse layers were written against the pre-reshape kernel API. The reshaped kernel
deliberately has a different, tighter surface (the [rt]/[setup] boundary settled in ADR
0002) and is missing some features the pre-reshape kernel exposed. Every reuse layer crosses one
of these seams:
Sync/thread API shape — drivers/devices that block, wake from ISR, or use sems/mutexes call kernel runtime APIs. Names/semantics mostly align (both
tk_-prefixed, pthread-shaped), but each call site must be audited, not assumed.Features present in
_legacy/but NOT yet in the reshaped core — must be ported forward before the layers that need them can re-attach. Landing state as of this reconciliation:tk_introspect.{c,h}— remote-monitor / RO introspection region — NOT ported (a lightertk_kernel_thread_snapshot+struct tk_thread_infoexist underTK_CONFIG_ENABLE_INTROSPECT, but not the seqlock region).tk_trace.h+tk_trace_ring.c+tk_sysview.h+system/tk_sysview.c— flight-recorder + SEGGER SystemView — ✅ ported (R2 half done).tk_time.c— the reshape folds the kernel-owned tick inline; root has onlykernel/tk_time.h(no.c). Parity confirmed (inlined), not a gap.tk_stack.c— root haskernel/tk_stack.has a placeholder no-op (tk_stack_prepare/tk_stack_checkare stubs; fill + canary + high-water “land here when enabled”). The L1 software-canary implementation + thetk_thread_stack_peak/free+ overflow-hook API are not yet re-hosted — reconcile against the arch canary.
HAL↔kernel independence must stay intact — composability invariants I1/I2/I3 (HAL never depends on kernel). The enforcing tool
_legacy/tools/composability_matrix.shis not yet at root; re-porting it (R4) is what restores the CI gate — until then the invariant is honored by convention, not enforced automatically.
3. Phased sequence & status¶
Each phase is independently landable and leaves the tree building + tests green.
R0 — Freeze & diff. ✅ Done (implicit in the promotion). The reshaped core was snapshotted and promoted; the pre-reshape tree is frozen under
_legacy/.R1 — Promote the core. ✅ Done. Reshaped
kernel/+arch/+make/are the root build. Host, nRF52 (arm_v7m), and RV32-QEMU (risc_v) build; the reshaped examples build from their root home. The make system wiresarm_v6m/arm_v7m/arm_v8m/pthread/risc_vand boardshost/nrf52832_pca10040/qemu_riscv32_virt(+_sbi)/rp2040_pico(+_flash)/mps2_an505.R2 — Port forward the missing kernel features. 🟡 Half done. Trace / trace-ring / SystemView are landed (
kernel/tk_trace.h,kernel/tk_trace_ring.c,kernel/tk_sysview.h,system/tk_sysview.c; demosexamples/{trace,sysview}). Not done:tk_introspectexamples/monitor; the L1-canary implementation behindtk_stack.h.tk_time.creconciled (inlined).
R3 — Re-attach HAL + devices + drivers. 🔴 Not started. A slim
hal/is present, butdevices/anddrivers/do not exist at root. Re-point them at the reshaped runtime API, fix the drift (expected: a handful of renames + the ISR→wake path), then re-assert the composability matrix gate.R4 — Retarget tests + tools. 🔴 Not started.
tests/does not exist at root;tools/has onlySEGGER/+bin2uf2.py—tkgen(pinmux) andcomposability_matrix.share not ported. Repoint host unit tests + tkgen/matrix at the promoted core.R5 — Board sweep. 🟡 Partial. Four reshaped boards landed (
host,nrf52832_pca10040,qemu_riscv32_virt,rp2040_pico). Reshaped ports drop in directly; HAL-only boards (MSP430, FR2433, STM32H723) re-attach via R3’s HAL. RA4M1, TC275, STM32, ESP32, AVR boards are not yet at root. Retire the (already archived) pre-reshapekernel/+arch/once every live board is on the new core. Do this board-by-board, not big-bang.
Boundary — what is explicitly NOT in this plan (so scope stays honest): new arch ports. The
remaining reshape arches are mostly confirmatory and should be done lazily, pulled by a board
an integration target actually needs, reusing the HW-verified _legacy/ code rather than
re-proving the pattern:
RISC-V S-standalone / SMP+U-mode — confirmatory (S-mode, U-mode, SMP each already proven; both the M-mode and S-mode/SBI QEMU targets are already at root).
C2000 / TriCore / MSP430 full reshaped ports — AXIS + CSA + small-RAM already validated. Ahead of the plan:
arch/c2000/andarch/tricore/already landed as arch directories (C2000 core compiles under cl2000; TriCore has switch + SMP + lazy-CSA) — but neither is make-wired and neither has an in-root board yet. Finish them at R5 when their board is next.Cortex-M33 / ARMv8-M + TrustZone — the one genuinely-NEW capability (secure/non-secure world isolation).
arch/arm_v8m+ themps2-an505QEMU target are already at root (QEMU-proven); the TrustZone world dimension and HW bring-up (FRDM-MCXN947) remain the deliberate slot.
4. Rough total & the honest caveat¶
Order-of-magnitude: R0–R2 are largely behind us; R3–R4 ≈ 1 focused week; R5 is open-ended
(203 _legacy board files, done incrementally and only for boards that stay alive). The dominant
cost is not writing code — it is the drift audit and keeping the composability gate green so the
HAL/kernel independence the reshape earned is not lost on the way back in. The highest-value next
slice that still delivers a coherent result is R2 (finish introspect) → R3 on one reference
board (nRF52), proving the reshaped core hosts the full reuse stack on real silicon.
5. Not yet ported to root (the standing carry-forward list)¶
The concrete backlog, reconciled against the root tree on 2026-08-19. Each item is absent at
root and present (proven) in _legacy/ unless noted.
Kernel features / observability
tk_introspect.{c,h}+examples/monitor— the seqlock-guarded ROps/topregion and its unprivileged reader. (TheTK_CONFIG_ENABLE_INTROSPECTknob andtk_kernel_thread_snapshotexist; the region + monitor do not.) → R2.L1 software-canary implementation —
kernel/tk_stack.his a no-op placeholder; the fill / canary / high-water scan andtk_thread_stack_peak/free+ overflow-hook API are not re-hosted. Note the placeholder’s stale comment says “defaultENABLE_STACK_CHECK=0” whiletk_config.hdefaults it to 1 — reconcile when the canary lands. → R2.Error / DET subsystem —
kernel/tk_det.his a no-op stub (TK_DET(...) → ((void)0)); thetk_error.*counters/hooks/28-module-ID machinery is_legacy/hal/only. → R3/R4.tk_time_us()carries only millisecond resolution — it ships as a flat `tk_kernel_now_ms()1000
rather than reading a sub-tick source, so even the host's nanosecondCLOCK_MONOTONIC` is truncated to ms before it. A real per-board sub-tick surface is a later add. → R2.
Tooling (tools/)
tkgenpinmux registry (_legacy/tools/tkgen/pingen.py) — YAML pin registry → validated const C tables. → R4.composability_matrix.sh— the HAL-never-depends-on-kernel CI gate. Not at root. See the review carry-forward below. → R4.
Reuse layers (whole directories absent at root)
tests/— 19 host unit test files; retarget at the promoted core. → R4.devices/— PN532 + sensors (sit on HAL, not kernel). → R3.drivers/—tk_button/tk_led/gpiote(one kernel touchpoint: ISR→wake). → R3.
Unported subsystems (safety/security — staged in docs/safety-and-security.md)
Crypto + verified boot — SHA-256 / HMAC / AES-CBC / P-256 ECDSA,
tk_vboottrust chain + signer pipeline. No crypto/vboot headers at root.Watchdog —
tk_wdg(mode-based HW watchdog). Nohal/tk_wdg.hat root.Cross-core heartbeat —
system/tk_heartbeat+TK_CONFIG_ENABLE_HEARTBEAT. Not at root.Reset-reason / brownout —
tk_mcu_reset_reason/ BOD warning backends. Not at root.Persistence — the
.noinit-survives-reset story: the demoexamples/noinitis at root (with its own linker script), but any broader persistence subsystem is not tracked here.
API-boundary annotations & type hygiene
[rt]/[setup]header annotations — ADR 0002 §4 fixes the runtime-vs-setup API split; the annotations ARE present inkernel/tk_kernel.h(done). ⚠ Open:[rt]-taggedtk_kernel_self/tk_kernel_nameread privileged data → a fault underTK_CONFIG_UNPRIV_THREADS(seedocs/reviews/amp-smp-review-0001.mdL2).Residual
uint8_tleak —kernel/tk_kernel.h’s publicstruct tk_thread_infostill declaresuint8_t base_priority/uint8_t state— the kind-1-as-uint8_tanti-pattern ADR 0001 (Addendum 2) forbids. Fix tounsigned charwhen the introspection surface is next touched.
Isolation — implemented in arch/+kernel/ but not wired at root
No root board provides the MPU zone symbols. The
arm_v7m(andarm_v8m/risc_v) isolation path references board-supplied linker symbols —tk_mpu_flash_base/_size,tk_mpu_ram_base/_size, plus the.privileged_bss/.thread_stackszones — and no root board defines them (verified:arch/arm_v7m/kernel_arch.c:295externs them; nothing inboards/supplies them). So a build withTK_CONFIG_ENABLE_MPU_ISOLATIONorTK_CONFIG_UNPRIV_THREADS=1will not link on any root board today — the machinery is present, the board wiring is not. Wire nRF52 first (itsarm_v7mMPU path is the most complete). → R3/R5.arch_stack_isolatable()has no caller. The fail-closed guard — reject/DET an unprivileged thread whose stack can’t be MPU-isolated — is implemented on everyARCH_HAS_MPUarch (arm_v7m/arm_v8m/risc_v) butkernel/tk_kernel.cnever calls it (verified). Add the check where unprivileged threads are admitted; until then the guard the isolation design assumes is absent. → R2/R3.
Review carry-forwards (re-verify; do not reopen the design)
SEC-4 — hard-coded MPU sub-region mask. A prior review flagged a hard-coded sub-region disable mask in the MPU region programming. Re-verify it against the reshaped
arch/arm_v7m/arch/arm_v8mMPU code; confirm it is still correct (or parameterized) — this is a re-verification, not a reopened design question.HAL-only CI build. The follow-up to prove HAL builds standalone (no kernel) was expected to be satisfied by
composability_matrix.sh. Correction: that tool is not yet at root (see Tooling above), so the automated gate is not currently satisfied here — the design is settled (the_legacymatrix), the re-port is the open action (R4). Confirm the invariant still holds; do not reopen the design.