code wiki / (root) / nx_printer_fw_sim_test.nx

nx_printer_fw_sim_test.nx source

↩ module page · 66 lines · 3588 B

1// nx_printer_fw_sim_test.nx -- the NEVER-BRICK gate (#26, brand-critical) for the firmware-flash simulator. 2// Proves MECHANICALLY (not by promise) that the A/B flash can never brick the virtual printer, by injecting 3// power loss at EVERY step x EVERY firmware quality and asserting the device ALWAYS boots something. A naive 4// in-place flash is the negative control: it CAN brick, so the gate is proven to DETECT bricking. 5// Unique exit codes: 6// 1 EXHAUSTIVE: A/B flash never bricks (2 sig x 2 boots x 5 power-loss-steps = 20 scenarios) 7// 2-5 specific outcomes (good->new active; mid-write->old; bad-sig->old rejected; bad-boot->rolled back) 8// 10 NEGATIVE CONTROL: naive in-place flash CAN brick (single-bank, power loss mid-write) 9// 11 and the SAFE A/B flash does NOT brick that same single-bank/power-loss case 10// expect_exit: 0 ; license_tier: ORIGINAL ; genealogy_id: project-printer-management-ipp-sclass-2026-06-20 11 12import "nx_syscalls.nx" 13import "nx_printer_fw_sim.nx" 14 15func t_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 16 17// init: bank A bootable + active, bank B absent; then A/B-flash a new image and boot. Returns fw_boot result. 18func scenario(st: *i64, sig: i64, boots: i64, step: i64) -> i64 { 19 st[0] = 0 20 fw_set_bank(st, 0, 1, 1, 1, 1) 21 fw_set_bank(st, 1, 0, 0, 0, 0) 22 fw_flash_ab(st, 2, sig, boots, step) 23 return fw_boot(st) 24} 25 26func main() -> i64 { 27 let st: *i64 = sys_mmap(128) as *i64 28 29 // ===== EXHAUSTIVE never-brick: 2 sig x 2 boots x 5 power-loss steps, ALL must stay bootable ===== 30 var sig: i64 = 0 31 while sig <= 1 { 32 var boots: i64 = 0 33 while boots <= 1 { 34 var step: i64 = 0 35 while step <= 4 { 36 if scenario(st, sig, boots, step) == NX_FW_BRICKED { return 1 } 37 step = step + 1 38 } 39 boots = boots + 1 40 } 41 sig = sig + 1 42 } 43 44 // ===== specific expected outcomes ===== 45 if scenario(st, 1, 1, 0) != 1 { return 2 } // good fw, no power loss -> new fw (bank B) active + boots 46 if scenario(st, 1, 1, 1) != 0 { return 3 } // power loss mid-write -> inactive corrupt, old (bank A) still boots 47 if scenario(st, 0, 1, 0) != 0 { return 4 } // bad signature -> rejected before flip, old (A) still boots 48 if scenario(st, 1, 0, 0) != 0 { return 5 } // sig ok but image doesn't boot -> bootloader rolls back to A 49 50 // ===== NEGATIVE CONTROL: a NAIVE in-place flash CAN brick (single bank, power loss mid-write) ===== 51 st[0] = 0 52 fw_set_bank(st, 0, 1, 1, 1, 1) // only bank A present 53 fw_set_bank(st, 1, 0, 0, 0, 0) // bank B absent (no fallback) 54 fw_flash_naive(st, 2, 1, 1, 1) // power loss step 1 -> corrupts the ACTIVE bank 55 if fw_boot(st) != NX_FW_BRICKED { return 10 } // the naive flash MUST be able to brick (gate discriminates) 56 57 // ...and the SAFE A/B flash on the exact same single-bank/power-loss case does NOT brick: 58 st[0] = 0 59 fw_set_bank(st, 0, 1, 1, 1, 1) 60 fw_set_bank(st, 1, 0, 0, 0, 0) 61 fw_flash_ab(st, 2, 1, 1, 1) // power loss mid-write hits the INACTIVE bank -> A intact 62 if fw_boot(st) == NX_FW_BRICKED { return 11 } 63 64 t_puts("nx_printer_fw_sim: PASS A/B flash NEVER bricks across 20 power-loss x firmware-quality scenarios (good->new, mid-write->old, bad-sig->rejected, bad-boot->rolled-back); naive in-place flash CAN brick (neg control). #26 proven mechanically -- real flashing stays gated.\n") 65 return 0 66}