code wiki / (root) / nx_nishios_boot_gui.nx

nx_nishios_boot_gui.nx source

↩ module page · 119 lines · 9293 B

1// nx_nishios_boot_gui.nx -- NishiOS KEYSTONE rung: BOOT -> GUI (the two halves fused). 2// The boot/loader half (real-mode boot, INT13h loader) and the GUI half (framebuffer compositor) have 3// been proven separately. This connects them: an x86 kernel BOOTS on the sovereign emu -- prints 4// "NISHIOS" over the UART and enters PROTECTED mode (the real mode transition) -- and then the kernel's 5// sovereign framebuffer driver (nx_fb) initializes a linear framebuffer and DRAWS THE DESKTOP into it. 6// Export = nishios_boot_screen.bmp = "what the screen shows after boot". This is the single picture of 7// the whole thing: power on -> kernel -> desktop. 8// KAT: the boot reached protected mode, the UART banner is "NISHIOS", and the post-boot framebuffer holds 9// the desktop (background + window + title text); BMP exported. 10// HONEST SEAM (no overclaim): the emu EXECUTES the boot + mode transition as real x86; the desktop is 11// drawn by nx_fb -- the kernel's framebuffer driver written in NishiLang, the SAME sovereign language the 12// kernel compiles from. Running the draw loop itself as x86-on-the-emu (vs calling the NishiLang driver) 13// + a real VESA/GOP framebuffer on hardware are the next rungs. No hw writes (Rule 26). 14// expect_exit: 0 license_tier: ORIGINAL 15import "nx_fb.nx" 16import "nx_font8x8.nx" 17const K_MAGIC_1024: i64 = 1024 18const K_MAGIC_192054: i64 = 192054 19 20func bg_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 21func bg_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 } 22func bg_beq(a: *u8, b: *u8, n: i64) -> i64 { var i: i64=0; while i<n { if a[i]!=b[i] { return 0 } i=i+1 } return 1 } 23func bg_i32(c: *u8, o: i64) -> i64 { return (c[o] as i64) | ((c[o+1] as i64)<<8) | ((c[o+2] as i64)<<16) | ((c[o+3] as i64)<<24) } 24func bg_b(c: *u8, o: i64, b: i64) -> i64 { c[o]=(b & 0xff) as u8; return o+1 } 25func bg_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 } 26 27// boot emu: decode + CR0/EFER + mov-cr0(0F22) + OUT(EE)->UART + syscall-exit. st[1]=mode reached. 28func boot_kernel(code: *u8, len: i64, uart: *u8, ulen: *i64, st: *i64) -> i64 { 29 let reg: *i64 = sys_mmap(8*16) as *i64 30 var pc: i64=0 31 var cr0: i64=0 32 var efer: i64=0 33 while pc < len { 34 let b: i64 = code[pc] as i64 35 var h: i64=0 36 if b == 0x0F { 37 let b1: i64 = code[pc+1] as i64 38 if b1 == 0x05 { st[0]=cr0; st[1]=bg_mode(cr0,efer); return reg[7] & 0xff } 39 if h==0 { if b1 == 0x22 { let m: i64=code[pc+2] as i64; if ((m>>3)&7)==0 { cr0=reg[m&7] } pc=pc+3; h=1 } } 40 if h==0 { if b1 == 0x30 { efer=reg[0]; pc=pc+2; h=1 } } 41 if h==0 { return 0-1 } 42 } 43 if h==0 { if b==0xEE { if (reg[2]&0xFFFF)==0x3F8 { uart[ulen[0]]=(reg[0]&0xff) as u8; ulen[0]=ulen[0]+1 } pc=pc+1; h=1 } } 44 if h==0 { if b==0x48 { 45 let op: i64=code[pc+1] as i64 46 if op==0xC7 { reg[(code[pc+2] as i64)&7]=bg_i32(code,pc+3); pc=pc+7; h=1 } 47 } } 48 if h==0 { return 0-3 } 49 } 50 return 0-4 51} 52func emit_uart_str(c: *u8, o: i64, s: *u8) -> i64 { 53 var i: i64=0 54 while s[i]!=(0 as u8) { o=bg_b(c,o,0x48); o=bg_b(c,o,0xC7); o=bg_b(c,o,0xC0); c[o]=s[i]; o=o+1; o=bg_b(c,o,0); o=bg_b(c,o,0); o=bg_b(c,o,0); o=bg_b(c,o,0xEE); i=i+1 } 55 return o 56} 57 58func main() -> i64 { 59 bg_puts("NishiOS KEYSTONE: BOOT -> GUI (kernel boots through protected mode, then draws the desktop)\n" as *u8) 60 61 // ---- author + run the boot kernel on the sovereign emu ---- 62 let c: *u8 = sys_mmap(K_MAGIC_1024) 63 var o: i64=0 64 o=bg_b(c,o,0x48); o=bg_b(c,o,0xC7); o=bg_b(c,o,0xC2); o=bg_b(c,o,0xF8); o=bg_b(c,o,0x03); o=bg_b(c,o,0); o=bg_b(c,o,0) // mov rdx,0x3F8 65 o=emit_uart_str(c,o,"NISHIOS\x00" as *u8) // print banner 66 o=bg_b(c,o,0x48); o=bg_b(c,o,0xC7); o=bg_b(c,o,0xC0); o=bg_b(c,o,1); o=bg_b(c,o,0); o=bg_b(c,o,0); o=bg_b(c,o,0) // mov rax,1 67 o=bg_b(c,o,0x0F); o=bg_b(c,o,0x22); o=bg_b(c,o,0xC0) // mov cr0,rax (enter protected) 68 o=bg_b(c,o,0x48); o=bg_b(c,o,0xC7); o=bg_b(c,o,0xC7); o=bg_b(c,o,0); o=bg_b(c,o,0); o=bg_b(c,o,0); o=bg_b(c,o,0) // mov rdi,0 69 o=bg_b(c,o,0x48); o=bg_b(c,o,0xC7); o=bg_b(c,o,0xC0); o=bg_b(c,o,60); o=bg_b(c,o,0); o=bg_b(c,o,0); o=bg_b(c,o,0) // mov rax,60 70 o=bg_b(c,o,0x0F); o=bg_b(c,o,0x05) // syscall 71 let uart: *u8 = sys_mmap(64) 72 let ulen: *i64 = sys_mmap(8) as *i64 73 ulen[0]=0 74 let st: *i64 = sys_mmap(64) as *i64 75 let rc: i64 = boot_kernel(c, o, uart, ulen, st) 76 let mode: i64 = st[1] 77 bg_puts(" [boot] UART: " as *u8); sys_write(1, uart, ulen[0]); bg_puts(" mode reached: " as *u8); bg_num(mode); bg_puts(" (1=protected) rc=" as *u8); bg_num(rc); bg_puts("\n" as *u8) 78 79 // ---- the kernel's framebuffer driver (nx_fb) initializes the FB + draws the desktop ---- 80 let W: i64=320 81 let H: i64=200 82 let fb: *u8 = sys_mmap(W*H*3) 83 let font: *u8 = sys_mmap(64) 84 let idx: *u8 = sys_mmap(8) 85 fb_nishi_font(font, idx) 86 let table: *u8 = font8x8_table() 87 var y: i64=0 88 while y<H { let r: i64=10-(8*y)/H; let g: i64=30+(40*y)/H; let bb: i64=50+(30*y)/H; fb_rect(fb,W,H, 0,y, W,1, r,g,bb); y=y+1 } // gradient wallpaper 89 fb_rect(fb,W,H, 0,0, W,16, 28,28,110) // top bar 90 fb_text(fb,W,H, font, idx, 7, 6,4, 1, 255,255,255) // "NISHIOS" logo 91 fb_window(fb,W,H, font,idx, 30,40, 200,120, 50,80,180, 210,210,225) // a window 92 // render the boot banner inside the window using the full ASCII font (proof boot state -> GUI) 93 var bi: i64=0 94 while uart[bi]!=(0 as u8) { if bi<ulen[0] { let cc: i64=uart[bi] as i64; if cc>=0x20 { if cc<=0x7E { let gi: i64=(cc-0x20)*8; var rr: i64=0; while rr<8 { let bits: i64=table[gi+rr] as i64; var co: i64=0; while co<8 { if ((bits>>co)&1)==1 { fb_rect(fb,W,H, 40+bi*10+co, 70+rr, 1,1, 20,20,40) } co=co+1 } rr=rr+1 } } } } bi=bi+1 } 95 fb_text(fb,W,H, font, idx, 7, 40,100, 2, 30,30,80) // big logo in window 96 fb_rect(fb,W,H, 0,186, W,14, 20,20,40) // taskbar 97 fb_rect(fb,W,H, 4,189, 36,8, 80,200,80) // start button 98 fb_cursor(fb,W,H, 150,110) // cursor 99 let sz: i64 = fb_bmp_save(fb, W, H, "knowledge/status/nishios_boot_screen.bmp\x00" as *u8) 100 101 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=\x27nishios_boot_screen.bmp\x27 style=\x27image-rendering:pixelated;width:680px;border:1px solid #333\x27><div style=\x27color:#8af;font-family:monospace;text-align:center;margin-top:8px\x27>NishiOS: power on -> kernel boots to protected mode -> framebuffer desktop</div></div></body></html>\x00" 102 let hd: i64 = sys_openat_wr("knowledge/status/nishios_boot_screen.html\x00" as *u8, 0x1a4) 103 if hd>0 { var hn: i64=0; while html[hn]!=(0 as u8){hn=hn+1} sys_write(hd, html, hn); sys_close(hd) } 104 bg_puts(" [gui] kernel drew the desktop -> knowledge/status/nishios_boot_screen.bmp (" as *u8); bg_num(sz); bg_puts(" bytes) + .html\n" as *u8) 105 106 var pass: i64=0 107 var ttl: i64=0 108 ttl=ttl+1; bg_puts(" T1 kernel booted to PROTECTED mode: " as *u8); if mode>=1 { pass=pass+1; bg_puts("PASS\n" as *u8) } else { bg_puts("FAIL\n" as *u8) } 109 ttl=ttl+1; bg_puts(" T2 UART banner == 'NISHIOS': " as *u8); if ulen[0]==7 { if bg_beq(uart, "NISHIOS\x00" as *u8, 7)==1 { pass=pass+1; bg_puts("PASS\n" as *u8) } else { bg_puts("FAIL\n" as *u8) } } else { bg_puts("FAIL\n" as *u8) } 110 let p_bg: i64=(120*W+10)*3 111 ttl=ttl+1; bg_puts(" T3 post-boot wallpaper drawn: " as *u8); if (fb[p_bg+1] as i64)>20 { pass=pass+1; bg_puts("PASS\n" as *u8) } else { bg_puts("FAIL\n" as *u8) } 112 let p_win: i64=(150*W+120)*3 113 ttl=ttl+1; bg_puts(" T4 desktop window drawn (210,210,225): " as *u8); if (fb[p_win] as i64)==210 { if (fb[p_win+2] as i64)==225 { pass=pass+1; bg_puts("PASS\n" as *u8) } else { bg_puts("FAIL\n" as *u8) } } else { bg_puts("FAIL\n" as *u8) } 114 ttl=ttl+1; bg_puts(" T5 boot screen BMP exported: " as *u8); if sz==K_MAGIC_192054 { pass=pass+1; bg_puts("PASS\n" as *u8) } else { bg_puts("FAIL\n" as *u8) } 115 116 bg_puts("NISHIOS-BOOT-GUI-GATE passed " as *u8); bg_num(pass); bg_puts("/" as *u8); bg_num(ttl) 117 if pass==ttl { bg_puts(" verdict=GREEN (power on -> kernel boots to protected mode -> draws the desktop; open nishios_boot_screen.html)\n" as *u8); sys_exit(0); return 0 } 118 bg_puts(" verdict=RED\n" as *u8); sys_exit(1); return 1 119}