code wiki / (root) / nx_nishi_usb_fbkernel.nx

nx_nishi_usb_fbkernel.nx source

↩ module page · 287 lines · 18095 B

1// nx_nishi_usb_fbkernel.nx -- x86 ladder R9-FBKERNEL: the disk-loaded kernel DRAWS its own framebuffer. 2// 3// Closes the seam nx_nishi_usb_desktop honestly flagged: there the desktop was drawn by the NishiLang 4// nx_fb driver AFTER the emu returned. HERE the booted kernel's framebuffer write is REAL x86 5// INSTRUCTIONS executed on the emu: the kernel that the MBR loads off the persisted image, after it 6// reaches LONG mode, runs an authored fill loop (mov-imm / store [rax],rcx / add / cmp / jne) that writes 7// a computed value into every framebuffer word. Afterward we read the framebuffer straight out of the 8// emu's memory -- the pixels were written by x86 the booted kernel executed, not by a NishiLang call -- 9// and encode it to BMP via nx_fb (now ONLY the encoder). 10// 11// This fuses THREE proven emus into ONE: the 16-bit real-mode + INT 13h loader (nx_nishi_usb_image), 12// the CR0/EFER mode transition (nx_nishi_usb_longmode), and the 64-bit store/arith/loop engine 13// (nx_nishios_fb_x86's ek_emu). 16-bit ops use named regs; 64-bit ops use a reg[] file; the boot 14// phases (banner -> mode-switch -> fill) each init their own registers, so there is no aliasing. 15// 16// Boot flow, executed off the PERSISTED on-disk bytes: 17// sector 0 (MBR) --INT 13h--> loads sector 1 (kernel) to 0x8000, jmps to it 18// sector 1 (kernel) prints "NishiOS" (INT 10h) -> CR0.PE/EFER.LME/CR0.PG (LONG mode) -> 19// x86 fill loop writes the framebuffer at 0x9000 -> HLT 20// 21// KAT: (T1) booted off disk; (T2) reached LONG mode; (T3) banner; (T4) the framebuffer holds EXACTLY 22// what the x86 loop computed at word 1 / 200 / last (proves the booted kernel's x86 ran to completion); 23// (T5) BMP exported. NEG/liar-kill (T6): a 0-sector-load sibling never runs the kernel, so the 24// framebuffer stays ZERO and long mode is never reached -- the pixels exist ONLY because the disk-loaded 25// kernel executed. 26// 27// HONEST SCOPE: the loop fills a computed ramp = proof of per-pixel x86 writes by the booted kernel; 28// richer chrome (rects/text drawn purely in x86) + a real VESA/GOP framebuffer on hardware are the 29// continuation. NEVER-BRICK (Rule 26): writes FILE artifacts; models INT 13h *reads* only; no /dev. 30// expect_exit: 0 license_tier: ORIGINAL 31import "nx_fb.nx" 32import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc) 33const IMG_MAGIC_2000000: i64 = 2000000 34const IMG_MAGIC_32767: i64 = 32767 35const IMG_MAGIC_65536: i64 = 65536 36const IMG_MAGIC_18432: i64 = 18432 37const IMG_MAGIC_2304: i64 = 2304 38 39func uf_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 40// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer 41// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the 42// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls). 43// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign. 44func uf_num(v: i64) -> i64 { nxi_out(v); return 0 } 45func uf_contains(hay: *u8, hn: i64, ndl: *u8, nn: i64) -> i64 { 46 if nn==0 { return 1 } 47 var i: i64 = 0 48 while i + nn <= hn { var j: i64 = 0; var ok: i64 = 1; while j < nn { if hay[i+j]!=ndl[j] { ok=0; j=nn } else { j=j+1 } } if ok==1 { return 1 } i=i+1 } 49 return 0 50} 51func uf_mode(cr0: i64, efer: i64) -> i64 { let pe: i64=cr0&1; let pg: i64=(cr0>>31)&1; let lme: i64=(efer>>8)&1; if pe==0 { return 0 } if pg==1 { if lme==1 { return 2 } } return 1 } 52func uf_st64(mem: *u8, addr: i64, v: i64) -> i64 { var i: i64=0; while i<8 { mem[addr+i]=((v>>(i*8))&0xff) as u8; i=i+1 } return 0 } 53 54// UNIFIED boot emu: 16-bit real-mode + INT 13h/INT 10h + CR0/EFER mode transition + 64-bit 55// store/arith/loop (the framebuffer-fill engine). st[0]=final cr0, st[1]=final mode. 56func emu_x86_boot_fb(mem: *u8, disk: *u8, entry: i64, console: *u8, clen: *i64, st: *i64) -> i64 { 57 let reg: *i64 = sys_mmap(8 * 16) as *i64 // 64-bit register file (mmap zero-inits) 58 var ip: i64=entry 59 var ax: i64=0 60 var bx: i64=0 61 var cx: i64=0 62 var dx: i64=0 63 var si: i64=0 64 var zf: i64=0 65 var cr0: i64=0 66 var efer: i64=0 67 var guard: i64=0 68 st[0]=0; st[1]=0 69 while guard < IMG_MAGIC_2000000 { 70 guard = guard + 1 71 let op: i64 = mem[ip] as i64 72 if op == 0xF4 { st[0]=cr0; st[1]=uf_mode(cr0,efer); return 0 } 73 var h: i64 = 0 74 // ---- 64-bit ops (REX.W = 0x48): mov-imm32 / store / add / cmp ---- 75 if h==0 { if op==0x48 { 76 let o2: i64 = mem[ip+1] as i64 77 if o2==0xC7 { // mov r64, imm32 78 let m: i64 = mem[ip+2] as i64 79 let imm: i64 = (mem[ip+3] as i64) | ((mem[ip+4] as i64)<<8) | ((mem[ip+5] as i64)<<16) | ((mem[ip+6] as i64)<<24) 80 reg[m & 7] = imm; ip=ip+7; h=1 81 } 82 if h==0 { if o2==0x89 { // mov [r/m], reg (store) or reg,reg 83 let m: i64 = mem[ip+2] as i64 84 if ((m>>6)&3)==3 { reg[m & 7] = reg[(m>>3) & 7] } else { uf_st64(mem, reg[m & 7], reg[(m>>3) & 7]) } 85 ip=ip+3; h=1 86 } } 87 if h==0 { if o2==0x01 { let m: i64=mem[ip+2] as i64; reg[m & 7] = reg[m & 7] + reg[(m>>3) & 7]; ip=ip+3; h=1 } } // add 88 if h==0 { if o2==0x39 { let m: i64=mem[ip+2] as i64; let t: i64 = reg[m & 7] - reg[(m>>3) & 7]; if t==0 { zf=1 } else { zf=0 } ip=ip+3; h=1 } } // cmp 89 if h==0 { return 0 - 1 } 90 } } 91 // ---- two-byte 0F ops: mov cr0 / wrmsr / syscall ---- 92 if h==0 { if op==0x0F { 93 let b1: i64 = mem[ip+1] as i64 94 if b1==0x22 { let m: i64=mem[ip+2] as i64; if ((m>>3)&7)==0 { cr0=reg[0] }; ip=ip+3; h=1 } 95 if h==0 { if b1==0x30 { efer=reg[0]; ip=ip+2; h=1 } } 96 if h==0 { if b1==0x05 { st[0]=cr0; st[1]=uf_mode(cr0,efer); return reg[7] & 0xff } } 97 if h==0 { return 0 - 1 } 98 } } 99 // ---- jne rel8 (64-bit loop branch) ---- 100 if h==0 { if op==0x75 { var r: i64 = mem[ip+1] as i64; if r>127 { r=r-256 } if zf==0 { ip=ip+2+r } else { ip=ip+2 } h=1 } } 101 // ---- 16-bit real-mode + BIOS INT services ---- 102 if h==0 { if op==0xBE { si = (mem[ip+1] as i64) | ((mem[ip+2] as i64)<<8); ip=ip+3; h=1 } } 103 if h==0 { if op==0xB8 { ax = (mem[ip+1] as i64) | ((mem[ip+2] as i64)<<8); ip=ip+3; h=1 } } 104 if h==0 { if op==0xBB { bx = (mem[ip+1] as i64) | ((mem[ip+2] as i64)<<8); ip=ip+3; h=1 } } 105 if h==0 { if op==0xB9 { cx = (mem[ip+1] as i64) | ((mem[ip+2] as i64)<<8); ip=ip+3; h=1 } } 106 if h==0 { if op==0xBA { dx = (mem[ip+1] as i64) | ((mem[ip+2] as i64)<<8); ip=ip+3; h=1 } } 107 if h==0 { if op==0xAC { let al: i64 = mem[si] as i64; ax = (ax & 0xFF00) | al; si=si+1; ip=ip+1; h=1 } } 108 if h==0 { if op==0x08 { let al2: i64 = ax & 0xFF; if al2==0 { zf=1 } else { zf=0 } ip=ip+2; h=1 } } 109 if h==0 { if op==0x74 { var r: i64 = mem[ip+1] as i64; if r>127 { r=r-256 } if zf==1 { ip=ip+2+r } else { ip=ip+2 } h=1 } } 110 if h==0 { if op==0xB4 { ax = (ax & 0xFF) | ((mem[ip+1] as i64)<<8); ip=ip+2; h=1 } } 111 if h==0 { if op==0xEB { var r2: i64 = mem[ip+1] as i64; if r2>127 { r2=r2-256 } ip=ip+2+r2; h=1 } } 112 if h==0 { if op==0xE9 { var r3: i64 = (mem[ip+1] as i64) | ((mem[ip+2] as i64)<<8); if r3>IMG_MAGIC_32767 { r3=r3-IMG_MAGIC_65536 } ip=ip+3+r3; h=1 } } 113 if h==0 { if op==0xCD { 114 let vec: i64 = mem[ip+1] as i64 115 let ah: i64 = (ax >> 8) & 0xFF 116 if vec==0x10 { if ah==0x0E { console[clen[0]]=(ax & 0xFF) as u8; clen[0]=clen[0]+1 } } 117 if vec==0x13 { if ah==0x02 { 118 let count: i64 = ax & 0xFF 119 let sector: i64 = cx & 0xFF 120 let lba: i64 = sector - 1 121 var s: i64 = 0 122 while s < count*512 { mem[bx + s] = disk[lba*512 + s]; s=s+1 } 123 ax = ax & 0xFF 124 } } 125 ip=ip+2; h=1 126 } } 127 if h==0 { return 0 - 1 } 128 } 129 return 0 - 2 130} 131 132const IMG_SZ: i64 = 1024 133const FB_BASE: i64 = 0x9000 // framebuffer in emu RAM, above the kernel (0x8000) -- no overlap 134const FB_W: i64 = 96 135const FB_H: i64 = 64 136 137// emit "mov r64,imm32" (48 C7 <modrm> imm32 LE) at img[base+o]. 138func uf_movr(img: *u8, base: i64, o: i64, modrm: i64, imm: i64) -> i64 { 139 img[base+o]=0x48 as u8; img[base+o+1]=0xC7 as u8; img[base+o+2]=(modrm&0xff) as u8 140 img[base+o+3]=(imm&0xff) as u8; img[base+o+4]=((imm>>8)&0xff) as u8; img[base+o+5]=((imm>>16)&0xff) as u8; img[base+o+6]=((imm>>24)&0xff) as u8 141 return o+7 142} 143 144func build_image(img: *u8, nwords: i64) -> i64 { 145 var z: i64=0 146 while z<IMG_SZ { img[z]=0 as u8; z=z+1 } 147 // ---- sector 0: MBR loads the kernel (sector 1) to 0x8000 and jmps to it ---- 148 img[0]=0xB8 as u8; img[1]=0x01 as u8; img[2]=0x02 as u8 149 img[3]=0xBB as u8; img[4]=0x00 as u8; img[5]=0x80 as u8 150 img[6]=0xB9 as u8; img[7]=0x02 as u8; img[8]=0x00 as u8 151 img[9]=0xBA as u8; img[10]=0x80 as u8; img[11]=0x00 as u8 152 img[12]=0xCD as u8; img[13]=0x13 as u8 153 let rel16: i64 = 0x8000 - (0x7C00 + 14 + 3) 154 img[14]=0xE9 as u8; img[15]=(rel16 & 0xFF) as u8; img[16]=((rel16>>8) & 0xFF) as u8 155 img[510]=0x55 as u8; img[511]=0xAA as u8 156 157 // ---- sector 1: the kernel (loads at 0x8000) ---- 158 var r: i64 = 0 159 // banner: print "NishiOS" over INT 10h 160 img[512+r]=0xBE as u8; let si_r: i64 = r+1; r=r+3 161 let loop_r: i64 = r 162 img[512+r]=0xAC as u8; r=r+1 163 img[512+r]=0x08 as u8; img[512+r+1]=0xC0 as u8; r=r+2 164 img[512+r]=0x74 as u8; let jz_r: i64 = r+1; r=r+2 165 img[512+r]=0xB4 as u8; img[512+r+1]=0x0E as u8; r=r+2 166 img[512+r]=0xCD as u8; img[512+r+1]=0x10 as u8; r=r+2 167 img[512+r]=0xEB as u8; img[512+r+1]=((loop_r-(r+2)) & 0xFF) as u8; r=r+2 168 let after_r: i64 = r 169 // mode transition: real -> protected -> long 170 r = uf_movr(img, 512, r, 0xC0, 1) // mov rax,1 171 img[512+r]=0x0F as u8; img[512+r+1]=0x22 as u8; img[512+r+2]=0xC0 as u8; r=r+3 // mov cr0,rax (PE) 172 r = uf_movr(img, 512, r, 0xC0, 0x100) // mov rax,0x100 173 img[512+r]=0x0F as u8; img[512+r+1]=0x30 as u8; r=r+2 // wrmsr (EFER.LME) 174 r = uf_movr(img, 512, r, 0xC0, 0x80000001) // mov rax,0x80000001 175 img[512+r]=0x0F as u8; img[512+r+1]=0x22 as u8; img[512+r+2]=0xC0 as u8; r=r+3 // mov cr0,rax (PE|PG -> LONG) 176 // x86 framebuffer fill loop (the booted kernel draws its own pixels) 177 r = uf_movr(img, 512, r, 0xC0, FB_BASE) // mov rax, FB_BASE 178 r = uf_movr(img, 512, r, 0xC1, 0) // mov rcx, 0 (counter + stored value) 179 r = uf_movr(img, 512, r, 0xC6, nwords) // mov rsi, nwords (limit) 180 r = uf_movr(img, 512, r, 0xC2, 8) // mov rdx, 8 (byte step) 181 r = uf_movr(img, 512, r, 0xC3, 1) // mov rbx, 1 (increment) 182 let fill_r: i64 = r 183 img[512+r]=0x48 as u8; img[512+r+1]=0x89 as u8; img[512+r+2]=0x08 as u8; r=r+3 // mov [rax], rcx 184 img[512+r]=0x48 as u8; img[512+r+1]=0x01 as u8; img[512+r+2]=0xD0 as u8; r=r+3 // add rax, rdx 185 img[512+r]=0x48 as u8; img[512+r+1]=0x01 as u8; img[512+r+2]=0xD9 as u8; r=r+3 // add rcx, rbx 186 img[512+r]=0x48 as u8; img[512+r+1]=0x39 as u8; img[512+r+2]=0xF1 as u8; r=r+3 // cmp rcx, rsi 187 img[512+r]=0x75 as u8; img[512+r+1]=((fill_r-(r+2)) & 0xFF) as u8; r=r+2 // jne fill_loop 188 img[512+r]=0xF4 as u8; r=r+1 // hlt 189 let msg_r: i64 = r 190 let msg: *u8 = "NishiOS\x0D\x0A\x00" 191 var mi: i64=0 192 while msg[mi]!=(0 as u8) { img[512+r]=msg[mi]; r=r+1; mi=mi+1 } 193 img[512+r]=0 as u8; r=r+1 194 img[512+jz_r] = ((after_r - (jz_r+1)) & 0xFF) as u8 // patch jz -> afterprint 195 let si_abs: i64 = 0x8000 + msg_r 196 img[512+si_r] = (si_abs & 0xFF) as u8 197 img[512+si_r+1] = ((si_abs>>8) & 0xFF) as u8 198 return 0 199} 200 201func boot_image(img: *u8, console: *u8, clen: *i64, st: *i64, loaded: *i64, fbout: *i64) -> i64 { 202 let mem: *u8 = sys_mmap(IMG_MAGIC_65536) 203 var k: i64=0 204 while k<IMG_MAGIC_65536 { mem[k]=0 as u8; k=k+1 } 205 var j: i64=0 206 while j<512 { mem[0x7C00+j]=img[j]; j=j+1 } 207 loaded[0] = mem[0x8000] as i64 208 clen[0]=0 209 let rc: i64 = emu_x86_boot_fb(mem, img, 0x7C00, console, clen, st) 210 loaded[1] = mem[0x8000] as i64 211 fbout[0] = (mem as i64) + FB_BASE // pointer to the framebuffer the kernel wrote 212 return rc 213} 214 215func uf_read(path: *u8, out: *u8, cap: i64) -> i64 { 216 let fd: i64 = sys_openat_rd(path) 217 if fd < 0 { return 0 - 1 } 218 var n: i64 = 0; var go: i64 = 1 219 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 } } 220 sys_close(fd) 221 return n 222} 223 224func main() -> i64 { 225 uf_puts("x86 ladder R9-FBKERNEL: the disk-loaded kernel boots to long mode + DRAWS its framebuffer in x86\n" as *u8) 226 let fb_bytes: i64 = FB_W*3*FB_H // IMG_MAGIC_18432 227 let nwords: i64 = fb_bytes/8 // IMG_MAGIC_2304 228 229 let img: *u8 = sys_mmap(IMG_SZ + 16) 230 build_image(img, nwords) 231 let fd: i64 = sys_openat_wr("knowledge/status/nishi_os_fbkernel.img\x00" as *u8, 0x1a4) 232 if fd<=0 { uf_puts("R9-FBKERNEL RED: cannot write image\n" as *u8); sys_exit(1); return 1 } 233 sys_write(fd, img, IMG_SZ) 234 sys_close(fd) 235 let rd: *u8 = sys_mmap(IMG_SZ + 16) 236 uf_read("knowledge/status/nishi_os_fbkernel.img\x00" as *u8, rd, IMG_SZ) 237 238 // GOOD boot: off-disk kernel -> long mode -> x86 fill loop writes the framebuffer. 239 let con: *u8 = sys_mmap(256) 240 let clen: *i64 = sys_mmap(8) as *i64 241 let st: *i64 = sys_mmap(64) as *i64 242 let ld: *i64 = sys_mmap(64) as *i64 243 let fbp_h: *i64 = sys_mmap(16) as *i64 244 let rc: i64 = boot_image(rd, con, clen, st, ld, fbp_h) 245 let fbp: *u8 = fbp_h[0] as *u8 246 247 var nz: i64=0 248 var i: i64=0 249 while i<fb_bytes { if (fbp[i] as i64)!=0 { nz=nz+1 } i=i+1 } 250 uf_puts(" boot: 0x8000 " as *u8); uf_num(ld[0]); uf_puts("->" as *u8); uf_num(ld[1]); uf_puts(" mode=" as *u8); uf_num(st[1]); uf_puts(" (2=long) banner='" as *u8); sys_write(1, con, clen[0]); uf_puts("' rc=" as *u8); uf_num(rc); uf_puts("\n" as *u8) 251 uf_puts(" the booted kernel's x86 fill loop wrote framebuffer non-zero bytes=" as *u8); uf_num(nz); uf_puts("/" as *u8); uf_num(fb_bytes); uf_puts("\n" as *u8) 252 253 let sz: i64 = fb_bmp_save(fbp, FB_W, FB_H, "knowledge/status/nishi_os_fbkernel.bmp\x00" as *u8) 254 let html: *u8 = "<!doctype html><html><body style=\x27margin:0;background:#0a0a12;display:flex;align-items:center;justify-content:center;height:100vh\x27><div><img src=\x27nishi_os_fbkernel.bmp\x27 style=\x27image-rendering:pixelated;width:480px;border:1px solid #333\x27><div style=\x27color:#8af;font-family:monospace;text-align:center;margin-top:8px\x27>NishiOS: this 96x64 framebuffer was written by REAL x86 stores in the kernel loaded off nishi_os_fbkernel.img (booted to long mode)</div></div></body></html>\x00" 255 let hd: i64 = sys_openat_wr("knowledge/status/nishi_os_fbkernel.html\x00" as *u8, 0x1a4) 256 if hd>0 { var hn: i64=0; while html[hn]!=(0 as u8){hn=hn+1} sys_write(hd, html, hn); sys_close(hd) } 257 uf_puts(" framebuffer -> knowledge/status/nishi_os_fbkernel.bmp (" as *u8); uf_num(sz); uf_puts(" bytes) + .html\n" as *u8) 258 259 // NEG CONTROL: 0-sector load -> kernel never runs -> framebuffer stays zero + never long mode. 260 let bad: *u8 = sys_mmap(IMG_SZ + 16) 261 var c: i64=0 262 while c<IMG_SZ { bad[c]=rd[c]; c=c+1 } 263 bad[1]=0x00 as u8 264 let con2: *u8 = sys_mmap(256) 265 let clen2: *i64 = sys_mmap(8) as *i64 266 let st2: *i64 = sys_mmap(64) as *i64 267 let ld2: *i64 = sys_mmap(64) as *i64 268 let fbp2_h: *i64 = sys_mmap(16) as *i64 269 boot_image(bad, con2, clen2, st2, ld2, fbp2_h) 270 let fbp2: *u8 = fbp2_h[0] as *u8 271 uf_puts(" NEG (0-sector load): mode=" as *u8); uf_num(st2[1]); uf_puts(" framebuffer word1=" as *u8); uf_num(fbp2[8] as i64); uf_puts(" (stays 0)\n" as *u8) 272 273 let banner: *u8 = "NishiOS" as *u8 274 let lastw: i64 = nwords - 1 275 var pass: i64=0 276 var ttl: i64=0 277 ttl=ttl+1; uf_puts(" T1 booted off the persisted image (0x8000: 0->0xBE): " as *u8); if ld[0]==0 { if ld[1]==0xBE { pass=pass+1; uf_puts("PASS\n" as *u8) } else { uf_puts("FAIL\n" as *u8) } } else { uf_puts("FAIL\n" as *u8) } 278 ttl=ttl+1; uf_puts(" T2 disk-loaded kernel reached LONG mode (mode==2): " as *u8); if st[1]==2 { pass=pass+1; uf_puts("PASS\n" as *u8) } else { uf_puts("FAIL\n" as *u8) } 279 ttl=ttl+1; uf_puts(" T3 UART banner == 'NishiOS': " as *u8); if uf_contains(con, clen[0], banner, 7)==1 { pass=pass+1; uf_puts("PASS\n" as *u8) } else { uf_puts("FAIL\n" as *u8) } 280 ttl=ttl+1; uf_puts(" T4 the kernel's x86 wrote the framebuffer (word 1==1, 200==200, last==" as *u8); uf_num(lastw & 0xff); uf_puts("): " as *u8); if (fbp[8*1] as i64)==1 { if (fbp[8*200] as i64)==200 { if (fbp[8*lastw] as i64)==(lastw & 0xff) { pass=pass+1; uf_puts("PASS\n" as *u8) } else { uf_puts("FAIL\n" as *u8) } } else { uf_puts("FAIL\n" as *u8) } } else { uf_puts("FAIL\n" as *u8) } 281 ttl=ttl+1; uf_puts(" T5 framebuffer encoded to BMP: " as *u8); if sz>0 { pass=pass+1; uf_puts("PASS\n" as *u8) } else { uf_puts("FAIL\n" as *u8) } 282 ttl=ttl+1; uf_puts(" T6 NEG: 0-sector load -> no long mode + framebuffer stays zero (liar-kill): " as *u8); if st2[1]!=2 { if (fbp2[8] as i64)==0 { pass=pass+1; uf_puts("PASS\n" as *u8) } else { uf_puts("FAIL\n" as *u8) } } else { uf_puts("FAIL\n" as *u8) } 283 284 uf_puts("X86-USB-FBKERNEL-GATE passed " as *u8); uf_num(pass); uf_puts("/" as *u8); uf_num(ttl) 285 if pass==ttl { uf_puts(" verdict=GREEN (the disk-loaded kernel boots to long mode and DRAWS its own framebuffer in x86 -- the draw-as-x86-on-boot seam is CLOSED)\n" as *u8); sys_exit(0); return 0 } 286 uf_puts(" verdict=RED\n" as *u8); sys_exit(1); return 1 287}