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}