codegen-validation
Use when building or debugging a compiler backend, codegen, or assembler and you need to prove the generated machine code is correct by executing it on a real…
Use when bringing up bare-metal or kernel code on a new architecture, SoC, or board (RISC-V, ARM, x86, ESP32) and it won't boot, hangs after boot, or faults early; covers trap vectors, MMU/PMP, syscall ABI, and boot ordering
$ npx -y skills add Midstall/claude-for-hardware --skill bare-metal-bringup --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/bare-metal-bringupContext preview
The summary Claude sees to decide when to auto-load this skill.
Use when bringing up bare-metal or kernel code on a new architecture, SoC, or board (RISC-V, ARM, x86, ESP32) and it won't boot, hangs after boot, or faults early; covers trap vectors, MMU/PMP, syscall ABI, and boot ordering
name: bare-metal-bringup description: Use when bringing up bare-metal or kernel code on a new architecture, SoC, or board (RISC-V, ARM, x86, ESP32) and it won't boot, hangs after boot, or faults early; covers trap vectors, MMU/PMP, syscall ABI, and boot ordering
Bringing up code on new silicon or a new architecture is a sequence of "does the most basic thing work yet" checkpoints. Each layer has a small number of mistakes that produce total silence or a single cryptic fault, and they are almost always init ordering, trap setup, address translation, or ABI mismatches.
**Core principle:** Get one character out the door first, then build up one checkpoint at a time. Until you have output, you are debugging blind, so the first job is always a working console, not the feature you wanted.
Climb in order. Don't debug a higher rung until the one below it is solid.
1. **Earliest output.** Poke the UART directly (no driver, no allocator). One known byte. If you can't get a byte, nothing else is debuggable. 2. **Stack and BSS.** A valid, correctly-placed stack and a zeroed BSS before any C/Zig/Rust runs. On some boots the stack must live inside a specific LOAD segment or the loader drops your initrd on top of it. 3. **Trap/exception vectors.** Install the vector table, prove it by taking a deliberate trap and returning. Get this working before timers or interrupts. 4. **Timer.** Architectural timer init MUST run before any kernel timer that divides by its frequency, or you divide by zero and panic with no output. 5. **Address translation.** MMU/PMP/page tables. Identity-map what you need, then enable. Wrong here means a fault the instant translation turns on. 6. **Interrupts.** Controller (PLIC/GIC/APIC), enable bits, the right per-IRQ vs global mask model for the part. 7. **Userspace / syscalls.** Drop to user mode, take a syscall, return cleanly without clobbering caller-saved-by-the-ABI registers.
See `bringup-gotchas.md` in this skill directory for the concrete, hard-won failures at each rung.
A bug that only appears under KVM (and not plain TCG) is usually a real hardware-ordering or state-save bug that TCG's looser model hides: FP/SIMD state not saved on the trap path, per-CPU pointer not set before the first IRQ, a sleeper list reusing a runqueue link. Treat "works in TCG, dies in KVM" as a genuine bug in your save/restore or ordering, not an emulator quirk.
1. Bisect by checkpoint: which rung's "hello" still prints? 2. Add a raw byte at the suspect transition (before/after enabling translation, before/after the first trap). 3. Suspect ordering first (init A before B), then ABI (who clobbered what), then translation (what's mapped). 4. Fix the root cause. Do not add a retry loop or a save-on-failure hatch to paper over a corruption; find what corrupts. See `silicon-grade-discipline`.
Claude Code skills for hardware design, validation, and bring-up. A plugin of focused skills that teach Claude how to do real hardware work: designing reusable HDL, integrating an SoC, bringing up FPGAs and bare-metal targets, building firmware boot chains,
Repo: Midstall/claude-for-hardware
Use when building or debugging a compiler backend, codegen, or assembler and you need to prove the generated machine code is correct by executing it on a real…
Use when verifying a hardware DUT (a CPU core, FPGA, or netlist) against a golden reference model, building coverage-guided fuzzing, or detecting where silicon…
Use when building or debugging a firmware and boot chain (RISC-V SBI, UEFI, ACPI, a bootloader handoff like Limine to an OS) or adding measured boot with a…
Use when loading a bitstream onto a physical FPGA and driving or observing it over JTAG or GPIO, especially bit-banged JTAG from a host like a Raspberry Pi, or…
Use when synthesizing RTL to an FPGA with yosys/nextpnr (ECP5/Lattice and similar), fighting area or routing congestion, measuring Fmax, deciding why a design…
Use when writing, refactoring, or deciding how to test an HDL module, component, or IP block (ROHD, Chisel, SpinalHDL, Verilog, VHDL) and you need it…