code wiki / (root) / nx_printer_fw_sim.nx

nx_printer_fw_sim.nx source

↩ module page · 78 lines · 4464 B

1// nx_printer_fw_sim.nx -- VIRTUAL printer firmware/flash SIMULATOR. The operator wants to let a user flash OUR 2// firmware to escape vendor DRM -- but FLASHING WRITES PERSISTENT HARDWARE STATE, the exact hazard global rule 3// #26 (NEVER BRICK THE ELECTRONICS -- brand-critical, ABSOLUTE) governs. So we model the printer + the flash 4// process IN SOFTWARE, iterate here (a simulator cannot brick anything), and PROVE the flash is fail-safe BY 5// CONSTRUCTION before any real device is touched. **NO real hardware is written by this file.** 6// 7// NEVER-BRICK ARCHITECTURE = A/B DUAL-BANK (the only safe way to field-flash): write the INACTIVE bank, verify 8// its signature, then ATOMICALLY flip the boot pointer. The ACTIVE (running) bank is NEVER modified during a 9// flash, so a power loss at ANY step leaves a bootable bank -> never bricked. A bad-signature image is rejected 10// before the flip; an image that doesn't boot is rolled back by the bootloader to the prior bank. The gate 11// injects power loss at EVERY step x EVERY firmware quality and proves the printer ALWAYS boots something -- 12// the #26 guarantee proven MECHANICALLY, not asserted -- with a NAIVE in-place flash as the negative control 13// (it CAN brick, proving A/B is what saves us). 14// 15// State = i64[9]: [0]=active_bank(0=A,1=B); bank b at base (1 + b*4) = [present, sig_valid, boots, version]. 16// PURE (caller-owned state, no syscalls) -> safe by construction. license_tier: ORIGINAL 17// genealogy_id: project-printer-management-ipp-sclass-2026-06-20 ; honors global rule #26. 18 19const NX_FW_BRICKED: i64 = 0 - 1 20 21func fw_base(b: i64) -> i64 { return 1 + b * 4 } 22 23func fw_set_bank(st: *i64, b: i64, present: i64, sig: i64, boots: i64, ver: i64) -> i64 { 24 let x: i64 = fw_base(b) 25 st[x] = present; st[x + 1] = sig; st[x + 2] = boots; st[x + 3] = ver 26 return 0 27} 28 29// A bank boots only if it is present, signature-valid, and the image actually boots. 30func fw_bank_bootable(st: *i64, b: i64) -> i64 { 31 let x: i64 = fw_base(b) 32 if st[x] != 1 { return 0 } 33 if st[x + 1] != 1 { return 0 } 34 if st[x + 2] != 1 { return 0 } 35 return 1 36} 37 38// BOOT: run the active bank; if it won't boot, the bootloader ROLLS BACK to the other bank (updating the 39// active pointer). Returns the bank that actually boots (0/1), or NX_FW_BRICKED if NEITHER boots. 40func fw_boot(st: *i64) -> i64 { 41 let a: i64 = st[0] 42 if fw_bank_bootable(st, a) == 1 { return a } 43 let o: i64 = 1 - a 44 if fw_bank_bootable(st, o) == 1 { st[0] = o; return o } 45 return NX_FW_BRICKED 46} 47 48// FAIL-SAFE A/B FLASH. Writes the INACTIVE bank only; verifies signature; atomically flips. power_loss_step: 49// 0=none 1=during-write 2=after-write/before-verify 3=after-verify/before-flip 4=after-flip 50// The ACTIVE bank is NEVER written -> never-brick BY CONSTRUCTION. Returns 1 if flipped (new fw active), else 0. 51func fw_flash_ab(st: *i64, new_ver: i64, new_sig: i64, new_boots: i64, power_loss_step: i64) -> i64 { 52 let inact: i64 = 1 - st[0] 53 let x: i64 = fw_base(inact) 54 if power_loss_step == 1 { 55 st[x] = 1; st[x + 1] = 0; st[x + 2] = 0; st[x + 3] = new_ver // partial write -> inactive corrupt; active intact 56 return 0 57 } 58 st[x] = 1; st[x + 1] = new_sig; st[x + 2] = new_boots; st[x + 3] = new_ver 59 if power_loss_step == 2 { return 0 } // power loss before verify -> no flip 60 if st[x + 1] != 1 { return 0 } // bad signature -> reject, never flip 61 if power_loss_step == 3 { return 0 } // power loss before flip -> no flip 62 st[0] = inact // atomic flip (new fw now active) 63 return 1 64} 65 66// NEGATIVE CONTROL: a NAIVE in-place flash (single-bank, writes the ACTIVE bank) -- the brick-prone vendor 67// style. Power loss during the write corrupts the running firmware -> BRICK. Proves the gate can DETECT a 68// brick and that the A/B design is what makes flashing safe. NEVER used against real hardware. 69func fw_flash_naive(st: *i64, new_ver: i64, new_sig: i64, new_boots: i64, power_loss_step: i64) -> i64 { 70 let a: i64 = st[0] 71 let x: i64 = fw_base(a) 72 if power_loss_step == 1 { 73 st[x] = 1; st[x + 1] = 0; st[x + 2] = 0; st[x + 3] = new_ver // ACTIVE bank corrupted mid-write -> brick 74 return 0 75 } 76 st[x] = 1; st[x + 1] = new_sig; st[x + 2] = new_boots; st[x + 3] = new_ver 77 return 1 78}