kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

Plan: Microcontroller development (STM32 Cortex-M, Espressif RISC-V)

Status — 2026-06-17 — first last-mile image formats landed

Kit's core compile→link→object pipeline is already in good shape for bare-metal MCU work — the hard part (an embedded-grade linker with full MEMORY/SECTIONS/ AT> linker-script support, --gc-sections, freestanding ET_EXEC) is done, and both 32-bit backends produce correct -O0/-O1 code. The gaps are concentrated in last-mile workflow (startup stubs, target docs, on-target debug) and a few defaults footguns. Intel HEX and Motorola S-record output are now covered by kit image --format ... and kit objcopy -O ....

This doc owns the MCU workflow integration roadmap. The ARM backend follow-ons that MCU work depends on (hard-float, .ARM.attributes, GNU numeric local labels, the kit-compiled reset stub) are tracked in ARM32.md — referenced here by MCU impact, not duplicated. The RV32 backend contract lives in ../RUNTIME.md; the linker-script surface in LINKER.md / ../LINK.md.

Scope

In scope (the two named ecosystems, minus Xtensa):

Explicitly out of scope (for now):

§0 — Target coverage matrix

Vendor / family Core (ISA) Status
STM32 F1/L1/F2 Cortex-M3 (ARMv7-M) Works — soft-float, correct (no FPU on part)
STM32 F3/F4/L4/G4 Cortex-M4(F) (ARMv7E-M) Compiles soft-float only; FPv4-SP idle until §4
STM32 F7/H7 Cortex-M7 (ARMv7E-M) Same — soft-float; no FPU/DP-FPU use
STM32 F0/L0/G0/C0 Cortex-M0/M0+ (ARMv6-M) Out of scope (ARMv7-M-only insns)
STM32 L5/U5/H5 Cortex-M33 (ARMv8-M) Out of scope (untested)
ESP32-C2 / -C3 RV32IMC Works — soft-float by default now (§1); add -march=rv32imc to drop the A ext
ESP32-C6 / -H2 RV32IMAC Works (-march=rv32imac)
ESP32-P4 RV32IMAFC Works; single-float hard, double soft
ESP32 / -S2 / -S3, ESP8266 Xtensa Out of scope (no backend)

§1 — Footguns to fix first (cheap, high-impact)

These are correctness/UX traps that bite before any feature work and are nearly free to fix.

§2 — Flashing: object → image formats

The flash workflow needs an image format the flasher ingests. Today objcopy -O binary works (driver/cmd/objcopy.c:226, via KIT_IMAGE_FORMAT_BIN) and this implementation adds Intel HEX / S-record support.

§3 — Startup: crt0 / vector table

The runtime ships no crt0 by design (../RUNTIME.md:240), so today every firmware hand-writes the reset handler, vector table, .data copy-from-flash, .bss zero, and stack setup. Correct reference stubs already exist in the test harness (test/smoke/arm32.sh:70, test/smoke/rv32.sh, test/link/harness/start.c) — the work is promoting a reusable, overridable startup into the shippable runtime so users start from working code, not a blank page.

§4 — ARM hard-float (FPv4-SP / FPv5)

Cortex-M4F/M7 (STM32 F4/F7/H7 — very common) have FPUs that current soft-float codegen leaves idle. This is an ARM backend item, owned by ARM32.md ("Hard-float (FPv4-SP, arm-none-eabihf): VFP codegen + softfp/hard axis"). Listed here only for MCU prioritization: it is the largest single performance lever for the STM32 mid/high range. Needs the VFP register file, hard-float AAPCS variant, and -mfloat-abi/-mfpu plumbing.

§5 — SDK / toolchain interop

To use kit alongside vendor SDKs (CMSIS, STM32 HAL, ESP-IDF) rather than fully standalone, kit objects must link cleanly with GNU-toolchain libraries.

§6 — On-target debug

kit dbg is an in-process JIT debugger (KitDebugSession); it cannot speak the GDB remote serial protocol to an OpenOCD/J-Link/probe-rs server, so it can't debug on real silicon today.

§7 — Runtime polish (optional, demand-driven)

Ordering

Roughly by leverage-per-effort:

  1. §1 footguns (RV32 soft-float default, per-part doc) — hours, prevents silent bad images.
  2. §2 objcopy -O ihex — small, unblocks STM32 flashing.
  3. §3 startup + starter linker script — removes the biggest "blank page" barrier.
  4. §6 verify external-gdb on-target debug — near-free if it works.
  5. §4 ARM hard-float (via ARM32.md) — biggest perf lever for STM32 F4/F7/H7.
  6. §5 SDK interop (.ARM.attributes, GNU labels, vendor .ld) — gates using kit with existing vendor code.
  7. §7 polish, §6 native remote-debug — demand-driven.