code wiki / _hdl_build / nx_nishi_install_os.nx
nx_nishi_install_os.nx source
↩ module page · 244 lines · 13034 B
1// nx_nishi_install_os.nx -- ladder C5 (the INSTALL-OUR-OS capstone): install the OS AS a content-addressed NishiFS.
2//
3// Fuses the whole installer/disk side into ONE flow: FORMAT the OS as a NishiFS disk (C1 partition table +
4// C2/C4 content-addressed FS: superblock + Merkle dir + objects) -> INSTALL it onto a target with the C3
5// never-brick installer (refuse-system-disk + sha256 read-back verify + golden recovery) -> MOUNT the
6// INSTALLED copy and read a file by CID, and prove the WHOLE-OS root CID survived the install bit-for-bit.
7// KAT 6/6: T1 install OK + sha256 byte-perfect; T2 never-brick (refuse /dev/sda); T3 the installed target
8// MOUNTS as NishiFS (partition->superblock->file-by-CID, bytes match); T4 the whole-OS root CID is PRESERVED
9// (installed root == source root = the entire filesystem verified through the install); T5 golden recovery
10// (corrupt install -> RECOVERED + still mounts); T6 integrity survives install (tamper installed object ->
11// MNT_INTEGRITY). composes nx_sha256 + nx_syscalls; reuses the proven C3 installer + C4 format/mount.
12// NEVER-BRICK (Rule 26): refuses the system disk; writes FILES only (knowledge/status/); no /dev. expect_exit: 0 license_tier: ORIGINAL
13import "nx_syscalls.nx"
14import "nx_sha256.nx"
15
16const DISK_SZ: i64 = 4096
17const PBYTE: i64 = 512
18const OBJSTART_REL: i64 = 512
19const PART_TYPE_NISHI: i64 = 0x9E
20const MNT_OK: i64 = 0
21const MNT_BADMAGIC: i64 = 1
22const MNT_ROOT_MISMATCH: i64 = 2
23const MNT_NOTFOUND: i64 = 3
24const MNT_INTEGRITY: i64 = 4
25const INST_OK: i64 = 0
26const INST_RECOVERED: i64 = 2
27const INST_UNSAFE: i64 = 7
28const INST_FATAL: i64 = 5
29
30func ui_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
31func ui_num(v: i64) -> i64 { let b: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m;sys_write(1,"-" as *u8,1)} let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} var i: i64=0; while i<k{b[i]=t[k-1-i];i=i+1} sys_write(1,b,k); return 0 }
32func ui_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n }
33func cid_eq(a: *u8, b: *u8) -> i64 { var i: i64=0; while i<32 { if a[i]!=b[i] { return 0 } i=i+1 } return 1 }
34func wr_u32_le(d: *u8, off: i64, v: i64) -> i64 { d[off]=(v & 0xFF) as u8; d[off+1]=((v>>8)&0xFF) as u8; d[off+2]=((v>>16)&0xFF) as u8; d[off+3]=((v>>24)&0xFF) as u8; return 0 }
35func rd_u32_le(d: *u8, off: i64) -> i64 { return (d[off] as i64) | ((d[off+1] as i64)<<8) | ((d[off+2] as i64)<<16) | ((d[off+3] as i64)<<24) }
36func sha_slice(d: *u8, off: i64, len: i64, out: *u8) -> i64 { sha256_digest(((d as i64)+off) as *u8, len, out); return 0 }
37func w_file(path: *u8, buf: *u8, n: i64) -> i64 { let fd: i64=sys_openat_wr(path, 0x1a4); if fd<=0 { return 0-1 } sys_write(fd, buf, n); sys_close(fd); return 0 }
38func ui_read(path: *u8, out: *u8, cap: i64) -> i64 { let fd: i64=sys_openat_rd(path); if fd<0 { return 0-1 } var n: i64=0; var go: i64=1; while go==1 { let rr: i64=sys_read(fd, ((out as i64)+n) as *u8, cap-n); if rr<=0 { go=0 } else { n=n+rr } if n>=cap { go=0 } } sys_close(fd); return n }
39
40// ---- C3 never-brick installer primitives ----
41func fl_safe(target: *u8) -> i64 {
42 if target[0]==(47 as u8) { if target[1]==(100 as u8) { if target[2]==(101 as u8) { if target[3]==(118 as u8) { if target[4]==(47 as u8) { if target[5]==(115 as u8) { if target[6]==(100 as u8) { if target[7]==(97 as u8) { return 0 } } } } } } } }
43 return 1
44}
45func fl_verify(img: *u8, n: i64, target: *u8) -> i64 {
46 let lenp: *i64 = sys_mmap(8) as *i64
47 let rb: *u8 = sys_read_file(target, lenp)
48 if (rb as i64)==0 { return 0-3 }
49 if lenp[0] != n { return 0-1 }
50 let h1: *u8 = sys_mmap(40)
51 let h2: *u8 = sys_mmap(40)
52 sha256_digest(img, n, h1)
53 sha256_digest(rb, lenp[0], h2)
54 if cid_eq(h1, h2)==1 { return 0 }
55 return 0-1
56}
57func nx_install(src: *u8, n: i64, target: *u8, golden: *u8, corrupt: i64) -> i64 {
58 if fl_safe(target)==0 { return INST_UNSAFE }
59 w_file(golden, src, n)
60 if corrupt==1 {
61 let bad: *u8 = sys_mmap(n+16)
62 var i: i64=0; while i<n { bad[i]=src[i]; i=i+1 }
63 bad[600] = (((bad[600] as i64)+1) & 0xFF) as u8
64 w_file(target, bad, n)
65 } else { w_file(target, src, n) }
66 var v: i64 = fl_verify(src, n, target)
67 if v==0 { return INST_OK }
68 let lenp: *i64 = sys_mmap(8) as *i64
69 let g: *u8 = sys_read_file(golden, lenp)
70 if (g as i64)==0 { return INST_FATAL }
71 w_file(target, g, lenp[0])
72 v = fl_verify(src, n, target)
73 if v==0 { return INST_RECOVERED }
74 return INST_FATAL
75}
76
77// ---- C2/C4 content-addressed NishiFS: format + mount ----
78func put_obj(d: *u8, cursor: i64, blob: *u8, n: i64, cidout: *u8) -> i64 {
79 sha256_digest(blob, n, cidout)
80 var i: i64=0; while i<32 { d[cursor+i]=cidout[i]; i=i+1 }
81 wr_u32_le(d, cursor+32, n)
82 i=0; while i<n { d[cursor+36+i]=blob[i]; i=i+1 }
83 return cursor + 36 + n
84}
85func find_obj(d: *u8, start: i64, endb: i64, cid: *u8, outlen: *i64) -> i64 {
86 var c: i64 = start
87 while c + 36 <= endb {
88 var same: i64 = 1
89 var i: i64 = 0
90 while i < 32 { if d[c+i]!=cid[i] { same=0; i=32 } else { i=i+1 } }
91 let ln: i64 = rd_u32_le(d, c+32)
92 if same==1 { outlen[0]=ln; return c+36 }
93 c = c + 36 + ln
94 }
95 return 0 - 1
96}
97func dir_find(d: *u8, base: i64, len: i64, name: *u8, cidout: *u8) -> i64 {
98 var c: i64 = base
99 let endd: i64 = base + len
100 while c < endd {
101 var k: i64 = 0
102 var same: i64 = 1
103 while d[c] != (0 as u8) { if name[k] != d[c] { same=0 } c=c+1; k=k+1 }
104 if name[k] != (0 as u8) { same=0 }
105 c = c + 1
106 if same==1 { var i: i64=0; while i<32 { cidout[i]=d[c+i]; i=i+1 } return 1 }
107 c = c + 32
108 }
109 return 0
110}
111func format_disk(d: *u8, nameA: *u8, A: *u8, nA: i64, nameB: *u8, B: *u8, nB: i64) -> i64 {
112 var z: i64=0; while z<DISK_SZ { d[z]=0 as u8; z=z+1 }
113 let p: i64 = 446
114 d[p+0]=0x80 as u8; d[p+2]=0x02 as u8; d[p+4]=PART_TYPE_NISHI as u8; d[p+5]=0xFE as u8; d[p+6]=0xFF as u8; d[p+7]=0xFF as u8
115 wr_u32_le(d, p+8, 1)
116 wr_u32_le(d, p+12, (DISK_SZ/512) - 1)
117 d[510]=0x55 as u8; d[511]=0xAA as u8
118 let cidA: *u8 = sys_mmap(40)
119 let cidB: *u8 = sys_mmap(40)
120 var cur: i64 = PBYTE + OBJSTART_REL
121 cur = put_obj(d, cur, A, nA, cidA)
122 cur = put_obj(d, cur, B, nB, cidB)
123 let dir_abs: i64 = cur
124 var w: i64 = dir_abs
125 var i: i64=0; while nameA[i]!=(0 as u8) { d[w]=nameA[i]; w=w+1; i=i+1 } d[w]=0 as u8; w=w+1
126 i=0; while i<32 { d[w]=cidA[i]; w=w+1; i=i+1 }
127 i=0; while nameB[i]!=(0 as u8) { d[w]=nameB[i]; w=w+1; i=i+1 } d[w]=0 as u8; w=w+1
128 i=0; while i<32 { d[w]=cidB[i]; w=w+1; i=i+1 }
129 let dir_len: i64 = w - dir_abs
130 let root: *u8 = sys_mmap(40)
131 sha_slice(d, dir_abs, dir_len, root)
132 let mg: *u8 = "NISHIFS1\x00" as *u8
133 i=0; while i<8 { d[PBYTE+i]=mg[i]; i=i+1 }
134 i=0; while i<32 { d[PBYTE+8+i]=root[i]; i=i+1 }
135 wr_u32_le(d, PBYTE+40, 2)
136 wr_u32_le(d, PBYTE+44, OBJSTART_REL)
137 wr_u32_le(d, PBYTE+48, dir_abs - PBYTE)
138 wr_u32_le(d, PBYTE+52, dir_len)
139 return 0
140}
141// extract the superblock root CID by parsing the partition table (0 ok, neg on failure)
142func get_root(d: *u8, out: *u8) -> i64 {
143 var lba: i64 = 0-1
144 var e: i64=0
145 while e<4 { let off: i64=446+e*16; if (d[off] as i64)==0x80 { if (d[off+4] as i64)==PART_TYPE_NISHI { lba=rd_u32_le(d,off+8); e=4 } else { e=e+1 } } else { e=e+1 } }
146 if lba<0 { return 0-1 }
147 let pb: i64=lba*512
148 let mg: *u8="NISHIFS1\x00" as *u8
149 var i: i64=0; while i<8 { if d[pb+i]!=mg[i] { return 0-2 } i=i+1 }
150 i=0; while i<32 { out[i]=d[pb+8+i]; i=i+1 }
151 return 0
152}
153func mount_read(d: *u8, name: *u8, out: *u8, cap: i64, lenout: *i64) -> i64 {
154 var lba: i64 = 0 - 1
155 var e: i64 = 0
156 while e < 4 { let off: i64 = 446 + e*16; if (d[off] as i64)==0x80 { if (d[off+4] as i64)==PART_TYPE_NISHI { lba = rd_u32_le(d, off+8); e=4 } else { e=e+1 } } else { e=e+1 } }
157 if lba < 0 { return MNT_NOTFOUND }
158 let pb: i64 = lba * 512
159 let mg: *u8 = "NISHIFS1\x00" as *u8
160 var i: i64=0; while i<8 { if d[pb+i]!=mg[i] { return MNT_BADMAGIC } i=i+1 }
161 let objstart_rel: i64 = rd_u32_le(d, pb+44)
162 let dir_off_rel: i64 = rd_u32_le(d, pb+48)
163 let dir_len: i64 = rd_u32_le(d, pb+52)
164 let dir_abs: i64 = pb + dir_off_rel
165 let root_stored: *u8 = sys_mmap(40)
166 i=0; while i<32 { root_stored[i]=d[pb+8+i]; i=i+1 }
167 let root_calc: *u8 = sys_mmap(40)
168 sha_slice(d, dir_abs, dir_len, root_calc)
169 if cid_eq(root_calc, root_stored)==0 { return MNT_ROOT_MISMATCH }
170 let fcid: *u8 = sys_mmap(40)
171 if dir_find(d, dir_abs, dir_len, name, fcid)==0 { return MNT_NOTFOUND }
172 let lenp: *i64 = sys_mmap(8) as *i64
173 let boff: i64 = find_obj(d, pb + objstart_rel, dir_abs, fcid, lenp)
174 if boff < 0 { return MNT_NOTFOUND }
175 let h: *u8 = sys_mmap(40)
176 sha_slice(d, boff, lenp[0], h)
177 if cid_eq(h, fcid)==0 { return MNT_INTEGRITY }
178 var m: i64 = lenp[0]
179 if m > cap { m = cap }
180 var j: i64=0; while j<m { out[j]=d[boff+j]; j=j+1 }
181 lenout[0]=lenp[0]
182 return MNT_OK
183}
184
185func main() -> i64 {
186 ui_puts("ladder C5: INSTALL the OS as a content-addressed NishiFS (C1 partition + C2/C4 FS + C3 never-brick installer)\n" as *u8)
187 let A: *u8 = "NishiOS readme: sovereign content-addressed filesystem\x00" as *u8
188 let B: *u8 = "kernel payload bytes v1 -- the OS image\x00" as *u8
189 let nA: i64 = ui_slen(A)
190 let nB: i64 = ui_slen(B)
191
192 // FORMAT the OS as a NishiFS disk
193 let src: *u8 = sys_mmap(DISK_SZ+16)
194 format_disk(src, "readme\x00" as *u8, A, nA, "kernel\x00" as *u8, B, nB)
195 let rootSrc: *u8 = sys_mmap(40)
196 get_root(src, rootSrc)
197
198 let target: *u8 = "knowledge/status/nishi_os_fs_target.img\x00" as *u8
199 let golden: *u8 = "knowledge/status/nishi_os_fs_golden.img\x00" as *u8
200
201 let r1: i64 = nx_install(src, DISK_SZ, target, golden, 0)
202 let v1: i64 = fl_verify(src, DISK_SZ, target)
203 let tgt: *u8 = sys_mmap(DISK_SZ+16)
204 let trn: i64 = ui_read(target, tgt, DISK_SZ)
205
206 let outK: *u8 = sys_mmap(512)
207 let lenK: *i64 = sys_mmap(8) as *i64
208 let r3: i64 = mount_read(tgt, "kernel\x00" as *u8, outK, 512, lenK)
209 var mok: i64=0
210 if r3==MNT_OK { if lenK[0]==nB { mok=1; var i: i64=0; while i<nB { if outK[i]!=B[i] { mok=0; i=nB } else { i=i+1 } } } }
211
212 let rootTgt: *u8 = sys_mmap(40)
213 get_root(tgt, rootTgt)
214
215 let r2: i64 = nx_install(src, DISK_SZ, "/dev/sda\x00" as *u8, golden, 0)
216
217 let r5: i64 = nx_install(src, DISK_SZ, target, golden, 1)
218 let tgt2: *u8 = sys_mmap(DISK_SZ+16)
219 let t2n: i64 = ui_read(target, tgt2, DISK_SZ)
220 let outK2: *u8 = sys_mmap(512)
221 let lenK2: *i64 = sys_mmap(8) as *i64
222 let r5m: i64 = mount_read(tgt2, "kernel\x00" as *u8, outK2, 512, lenK2)
223
224 let bad: *u8 = sys_mmap(DISK_SZ+16)
225 var c: i64=0; while c<DISK_SZ { bad[c]=tgt[c]; c=c+1 }
226 let aData: i64 = PBYTE + OBJSTART_REL + 36 + 5
227 bad[aData] = (((bad[aData] as i64)+1) & 0xFF) as u8
228 let outx: *u8 = sys_mmap(512)
229 let lenx: *i64 = sys_mmap(8) as *i64
230 let r6: i64 = mount_read(bad, "readme\x00" as *u8, outx, 512, lenx)
231
232 var pass: i64=0
233 var ttl: i64=0
234 ttl=ttl+1; ui_puts(" T1 install OS-FS to target -> OK + sha256 byte-perfect: " as *u8); if r1==INST_OK { if v1==0 { pass=pass+1; ui_puts("PASS\n" as *u8) } else { ui_puts("FAIL\n" as *u8) } } else { ui_puts("FAIL\n" as *u8) }
235 ttl=ttl+1; ui_puts(" T2 never-brick: refuse install to /dev/sda: " as *u8); if r2==INST_UNSAFE { pass=pass+1; ui_puts("PASS\n" as *u8) } else { ui_puts("FAIL\n" as *u8) }
236 ttl=ttl+1; ui_puts(" T3 installed target MOUNTS as NishiFS (read 'kernel' by CID, bytes match): " as *u8); if mok==1 { pass=pass+1; ui_puts("PASS\n" as *u8) } else { ui_puts("FAIL (r3="); ui_num(r3); ui_puts(")\n" as *u8) }
237 ttl=ttl+1; ui_puts(" T4 whole-OS root CID PRESERVED through install (installed root == source root): " as *u8); if cid_eq(rootTgt, rootSrc)==1 { pass=pass+1; ui_puts("PASS\n" as *u8) } else { ui_puts("FAIL\n" as *u8) }
238 ttl=ttl+1; ui_puts(" T5 golden recovery: corrupt install -> RECOVERED + still mounts: " as *u8); if r5==INST_RECOVERED { if r5m==MNT_OK { pass=pass+1; ui_puts("PASS\n" as *u8) } else { ui_puts("FAIL\n" as *u8) } } else { ui_puts("FAIL (r5="); ui_num(r5); ui_puts(")\n" as *u8) }
239 ttl=ttl+1; ui_puts(" T6 integrity survives install (tamper installed object -> MNT_INTEGRITY): " as *u8); if r6==MNT_INTEGRITY { pass=pass+1; ui_puts("PASS\n" as *u8) } else { ui_puts("FAIL (r6="); ui_num(r6); ui_puts(")\n" as *u8) }
240
241 ui_puts("NISHI-INSTALL-OS-GATE passed " as *u8); ui_num(pass); ui_puts("/" as *u8); ui_num(ttl)
242 if pass==ttl { ui_puts(" verdict=GREEN (the OS installs AS a content-addressed NishiFS: never-brick install + mountable + whole-OS root-CID preserved + integrity survives; CoW snapshot + encryption + R10 hardware = next)\n" as *u8); sys_exit(0); return 0 }
243 ui_puts(" verdict=RED\n" as *u8); sys_exit(1); return 1
244}