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}