code wiki / _hdl_build / nx_cmos.nx
nx_cmos.nx source
↩ module page · 126 lines · 7161 B
1// nx_cmos.nx -- SEE + safely TWEAK CMOS, never-brick (operator 2026-06-16: "see what our cmos is
2// while we are in the os ... and tweak ... ramifications of os-managed cmos").
3//
4// module: nishi-core.genealogy.cmos
5// capability: CORE_COMPUTE (observe the live RTC/CMOS + a never-brick config-tweak model)
6//
7// TWO HALVES of PC CMOS:
8// (1) the RTC/clock + status regs [0x00..0x0F] -- we READ this LIVE from /proc/driver/rtc
9// (read-only, no root) so you can SEE the machine's real clock right now.
10// (2) the config RAM [0x10..0x7F] -- BIOS settings, protected by the classic AT
11// CHECKSUM (16-bit sum of bytes 0x10..0x2D, stored big-endian at 0x2E/0x2F). A bad checksum
12// makes the BIOS report "CMOS checksum error" and load DEFAULTS = a recoverable SOFT-brick.
13//
14// RAMIFICATIONS (why os-managed CMOS is a never-brick boundary):
15// * READS are safe. WRITES are the brick risk. The CMOS checksum means a corrupt/partial write
16// degrades to defaults (recoverable), NOT a hard brick -- so cmos_set_safe ALWAYS recomputes the
17// checksum (BIOS-acceptable) AND keeps a golden snapshot to restore. It RANGE-GUARDS: never the
18// RTC/status bytes, never the checksum bytes.
19// * The DANGEROUS cousins are UEFI variables + SPI flash (those CAN hard-brick: e.g. deleting
20// efivars bricked some laptops). Those go through the A/B + immutable-factory + signed-capsule
21// path (nx_fw_robust_flash / the ed25519 capsule), tested in nx_emu_uefi BEFORE real hardware.
22// Sandboxed/in-memory: this organ NEVER writes the real NVRAM device node or ports here -- the safe model is
23// proven first; wiring to the real device is an explicit, operator-gated step. Sovereign. license_tier: ORIGINAL
24import "nx_syscalls.nx"
25import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc)
26const CMOS_MAGIC_8208: i64 = 8208
27const CMOS_MAGIC_8192: i64 = 8192
28
29const CMOS_SIZE: i64 = 128
30const CMOS_CK_START: i64 = 16 // 0x10: first checksummed config byte
31const CMOS_CK_END: i64 = 46 // 0x2E: exclusive -> sums 0x10..0x2D
32const CMOS_CK_HI: i64 = 46 // 0x2E: checksum high byte
33const CMOS_CK_LO: i64 = 47 // 0x2F: checksum low byte
34const CMOS_CFG_END: i64 = 46 // safe-tweak range = [0x10, 0x2E): the checksummed config only
35
36const CMOS_OK: i64 = 0
37const CMOS_REFUSED: i64 = 1 // offset out of the safe config range (RTC/status/checksum byte)
38const CMOS_RESTORED: i64 = 2 // post-write invalid (shouldn't happen) -> restored from golden
39
40func c_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != 0 as u8 { n = n + 1 } sys_write(1, s, n); return 0 }
41// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer
42// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the
43// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls).
44// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign.
45func c_putn(v: i64) -> i64 { nxi_out(v); return 0 }
46func c_read(path: *u8, lb: *i64) -> *u8 {
47 let fd: i64 = sys_openat_rd(path)
48 if fd < 0 { lb[0] = 0; return 0 as *u8 }
49 let buf: *u8 = sys_mmap(CMOS_MAGIC_8208)
50 var n: i64 = 0; var go: i64 = 1
51 while go == 1 {
52 let r: i64 = sys_read(fd, ((buf as i64) + n) as *u8, CMOS_MAGIC_8192 - n)
53 if r <= 0 { go = 0 } else { n = n + r }
54 if n >= CMOS_MAGIC_8192 { go = 0 }
55 }
56 sys_close(fd); buf[n] = 0 as u8; lb[0] = n
57 return buf
58}
59
60// the classic AT CMOS checksum: 16-bit sum of bytes [0x10, 0x2E).
61func cmos_cksum(img: *u8) -> i64 {
62 var s: i64 = 0; var i: i64 = CMOS_CK_START
63 while i < CMOS_CK_END { s = s + (img[i] as i64); i = i + 1 }
64 return s & 0xffff
65}
66func cmos_stored(img: *u8) -> i64 { return (img[CMOS_CK_HI] as i64) * 256 + (img[CMOS_CK_LO] as i64) }
67func cmos_fix(img: *u8) -> i64 {
68 let ck: i64 = cmos_cksum(img)
69 img[CMOS_CK_HI] = ((ck >> 8) & 0xff) as u8
70 img[CMOS_CK_LO] = (ck & 0xff) as u8
71 return 0
72}
73func cmos_valid(img: *u8) -> i64 { if cmos_cksum(img) == cmos_stored(img) { return 1 } return 0 }
74func cmos_restore(dst: *u8, src: *u8) -> i64 { var i: i64 = 0; while i < CMOS_SIZE { dst[i] = src[i]; i = i + 1 } return 0 }
75
76// a known-good default CMOS image (illustrative config bytes; real semantics are BIOS-specific --
77// the CHECKSUM + golden + guards are the universal, real never-brick mechanism, not the byte meanings).
78func cmos_golden(img: *u8) -> i64 {
79 var i: i64 = 0; while i < CMOS_SIZE { img[i] = 0 as u8; i = i + 1 }
80 img[16] = 0x26 as u8; img[20] = 0x21 as u8; img[24] = 0x80 as u8; img[40] = 0x55 as u8
81 cmos_fix(img)
82 return 0
83}
84
85// NEVER-BRICK config tweak: range-guard, set, recompute the checksum, validate. The result is ALWAYS
86// a checksum-consistent (BIOS-acceptable) image; a golden snapshot remains for explicit restore.
87func cmos_set_safe(img: *u8, off: i64, val: i64) -> i64 {
88 if off < CMOS_CK_START { return CMOS_REFUSED } // never the RTC/clock/status bytes [0x00..0x10)
89 if off >= CMOS_CFG_END { return CMOS_REFUSED } // never the checksum bytes 0x2E/0x2F (or beyond)
90 img[off] = val as u8
91 cmos_fix(img)
92 if cmos_valid(img) == 1 { return CMOS_OK }
93 return CMOS_RESTORED
94}
95
96// simulate a bad/interrupted/bit-rot write: flip a config byte WITHOUT fixing the checksum.
97func cmos_corrupt_raw(img: *u8, off: i64) -> i64 { img[off] = ((img[off] as i64) + 1) as u8; return 0 }
98
99func cmos_show_rtc() -> i64 {
100 let lb: *i64 = sys_mmap(16) as *i64; lb[0] = 0
101 let b: *u8 = c_read("/proc/driver/rtc" as *u8, lb)
102 if (b as i64) == 0 { c_puts(" (no /proc/driver/rtc -- RTC not exposed in this environment)\n"); return 0 }
103 c_puts(" LIVE CMOS RTC right now (read-only, /proc/driver/rtc):\n")
104 sys_write(1, b, lb[0])
105 return 0
106}
107
108func main() -> i64 {
109 c_puts("=== NISHI CMOS: SEE the live clock + never-brick config TWEAK model ===\n")
110 cmos_show_rtc()
111 let g: *u8 = sys_mmap(CMOS_SIZE + 16)
112 let w: *u8 = sys_mmap(CMOS_SIZE + 16)
113 cmos_golden(g); cmos_restore(w, g)
114 c_puts(" config CMOS: valid="); c_putn(cmos_valid(w)); c_puts(" checksum="); c_putn(cmos_stored(w)); c_puts("\n")
115 let r1: i64 = cmos_set_safe(w, 24, 0x40)
116 c_puts(" safe tweak [0x18]=0x40 -> status="); c_putn(r1); c_puts(" valid="); c_putn(cmos_valid(w)); c_puts(" byte="); c_putn(w[24] as i64); c_puts("\n")
117 cmos_corrupt_raw(w, 20)
118 c_puts(" RAW corruption [0x14]++ (no checksum fix) -> valid="); c_putn(cmos_valid(w)); c_puts(" (0 => BIOS flags CMOS-checksum-error + loads DEFAULTS = recoverable soft-brick)\n")
119 cmos_restore(w, g)
120 c_puts(" restore from golden -> valid="); c_putn(cmos_valid(w)); c_puts("\n")
121 let r2: i64 = cmos_set_safe(w, 46, 0x00)
122 let r3: i64 = cmos_set_safe(w, 5, 0x00)
123 c_puts(" guard: tweak checksum-byte 0x2E -> status="); c_putn(r2); c_puts(" (1=REFUSED); tweak RTC-byte 0x05 -> status="); c_putn(r3); c_puts(" (1=REFUSED)\n")
124 c_puts(" INVARIANT: every accepted tweak keeps the checksum valid (BIOS-acceptable); golden always restores -> never soft-brick we can't undo\n")
125 sys_exit(0); return 0
126}