code wiki / _hdl_build / nx_fw_safeflash.nx

nx_fw_safeflash.nx

buildroot/runtime/_hdl_build/nx_fw_safeflash.nx

10774 B224 linesdepth 5pulls 6 transitivereach 5 importersview sourcekind tooltopic fw
docsdependenciesstructsconstsfunctions

about

nx_fw_safeflash.nx -- THE NEVER-BRICK firmware flash, proven in the sandbox. module: nishi-core.genealogy.fw_safeflash capability: CORE_COMPUTE (model + PROVE the never-brick guarantee for firmware flashing) THE LAW (operator 2026-06-16, CLAUDE.md #26): no Nishi capability may EVER brick the electronics. Flashing firmware is the canonical brick risk. This organ models the SAME mechanism real motherboards use to make a flash un-brickable -- DUAL-IMAGE GOLDEN RECOVERY (dual-BIOS / BIOS-flashback) -- and PROVES the guarantee against deliberate failures: * a firmware image = magic "NXFW" + payload_len + payload + sha256(payload); it is BOOTABLE iff the magic is intact AND the sha256 matches (a corrupt/zeroed image is NOT bootable); * fw_safe_flash(active, golden, new, corrupt): 0) REFUSE any path not under /tmp/ (the emu sandbox -- this organ CANNOT touch the host firmware/dev; never-brick by construction, not by promise); 1) PRE-VALIDATE the new image -- a bad source image is REJECTED, active untouched; 2) REQUIRE a bootable GOLDEN anchor -- with no recovery copy, REFUSE to flash; 3) write active (optionally inject mid-write corruption to simulate a bad/interrupted flash); 4) POST-VERIFY active; if not bootable, AUTO-RESTORE from golden and re-verify. INVARIANT (the never-brick property): given a bootable golden anchor, `active` is BOOTABLE after EVERY safe_flash, on every path. A "brick" costs at most a restore, never the device. Sandboxed: operates ONLY on /tmp/ files; touches no real /dev or host firmware. Sovereign: imports nx_syscalls + the sovereign nx_sha256 (no gcc/.sh). license_tier: ORIGINAL

dependencies 3 imports · 4 importers

nx_syscalls.nx nx_itoa_lib.nx nx_sha256.nx nx_fw_safeflash.nx nx_fw_boot_proof_gate.nx nx_fw_real_flash_gate.nx nx_fw_robust_flash.nx nx_fw_safeflash_gate.nx

imports: nx_syscalls.nxnx_itoa_lib.nxnx_sha256.nx

imported by: nx_fw_boot_proof_gate.nxnx_fw_real_flash_gate.nxnx_fw_robust_flash.nxnx_fw_safeflash_gate.nx

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main fw_puts sys_write sys_now_realtime_sec sys_mmap sys_clock_gettime_real sys_mmap ↻ fw_path fw_cat fw_catn sys_mmap ↻ fw_make sys_mmap ↻ fw_wr_u32 sha256_digest sys_mmap ↻ sha256_init sys_mmap ↻ sha256_k sha256_update sha256_compress_ni_blocks blk_set_byte sha256_compress sha256_compress_ni blk_word blk_byte sha256_final blk_set_byte ↻ sha256_compress ↻ fw_write_bytes sys_openat_wr sys_write ↻ sys_close fw_putn nxi_out nxi_fd sys_mmap ↻ ccz_cat_num sys_write ↻ sys_munmap

structs

none

consts

27const FW_MAGIC_65536: i64 = 65536
28const FW_MAGIC_16777216: i64 = 16777216
30const FW_OK: i64 = 0 // flashed + verified bootable
31const FW_REJECTED_PRE: i64 = 1 // new image was itself bad -> active untouched
32const FW_RECOVERED: i64 = 2 // active went bad mid-flash -> auto-restored from golden
33const FW_REFUSED_NO_ANCHOR: i64 = 3 // no bootable golden -> refused to flash (never flash blind)
34const FW_SANDBOX_VIOLATION: i64 = 4 // a path was not under /tmp/ -> refused (cannot touch host)
35const FW_FATAL: i64 = 5 // unreachable while a golden anchor exists (the proof)
67const FW_DIGEST: i64 = 32
81const FW_MAXIMG: i64 = 16777216

functions

37func fw_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != 0 as u8 { n = n + 1 } sys_write(1, s, n); return 0 }
called by 8: bp_rowmainrf_rowmainmainmain+2 calls 1: sys_write
42func fw_putn(v: i64) -> i64 { nxi_out(v); return 0 }
called by 4: mainmainmainmain calls 1: nxi_out
45func fw_is_sandbox(p: *u8) -> i64
52func fw_wr_u32(buf: *u8, off: i64, v: i64) -> i64
called by 1: fw_make
59func fw_rd_u32(buf: *u8, off: i64) -> i64
68func fw_dig_eq(a: *u8, b: *u8) -> i64 { var i: i64 = 0; while i < FW_DIGEST { if a[i] != b[i] { return 0 } i = i + 1 } return 1 }
called by 1: fw_bootable
70func fw_write_bytes(path: *u8, buf: *u8, n: i64) -> i64
82func fw_read(path: *u8, lb: *i64) -> *u8
99func fw_make(path: *u8, payload: *u8, plen: i64) -> i64
111func fw_bootable(path: *u8) -> i64
130func fw_copy(src: *u8, dst: *u8) -> i64
140func fw_unwrap(nxfw: *u8, rawout: *u8) -> i64
156func fw_corrupt_byte(path: *u8) -> i64
167func fw_safe_flash(active: *u8, golden: *u8, newimg: *u8, corrupt: i64) -> i64
181func fw_cat(dst: *u8, off: i64, s: *u8) -> i64 { var i: i64 = 0; while s[i] != 0 as u8 { dst[off + i] = s[i]; i = i + 1 } return off + i }
182func fw_catn(dst: *u8, off: i64, v: i64) -> i64
called by 5: mainmainmainfw_pathmain calls 1: sys_mmap
192func fw_path(out: *u8, stem: *u8, epoch: i64, pid: i64) -> i64
203func main() -> i64