Word-by-word copy from .data's LMA (__data_load_start) to its VMA
(__data_start..__data_end). On qemu-virt LMA == VMA so the loop is
identity; on the C6 it pulls flash → SRAM. Same asm shape, target-
selected behaviour driven entirely by the linker script.
toolchain/qemu-virt.ld: defines __data_load_start = LOADADDR(.data)
so the symbol resolves at link time on either target.
Static disassembly checks: three auipc/addi pairs for the bounds,
matched lw/sw word pair, two increments per iteration, ret, no
callee-saved writes.
First asm function through the canonical loop end-to-end:
make build → firmware.elf → ./verify _reset → green
(spec-validate, 4 tests, kat-only verifier).
_reset: real implementation. Sets sp ← __stack_top, gp ←
__global_pointer$, calls _main, defensive wfi/j loop. Tests assert
ELF entry point matches _reset, prologue order (sp before gp before
call), and the halt-loop tail.
_init_bss / _init_data / _main: stubs (unimp body) per CLAUDE.md
workflow step 3. Test files exist with @pytest.mark.skip so the
spec-block @tests references resolve.
tests/harness/build.py: thin shell over `make build`, plus objdump
helpers (entry_point, symbol_address, per-symbol disassemble) used
by the boot tests.
FUNCTIONS.md: _reset → ◉ verified; the three stubs → ◐ in-progress.