code wiki / _hdl_build / nx_nishi_usb_kernel.nx

nx_nishi_usb_kernel.nx

buildroot/runtime/_hdl_build/nx_nishi_usb_kernel.nx

20144 B318 linesdepth 3pulls 3 transitivereach 0 importersview sourcekind tooltopic nishi
docsdependenciesstructsconstsfunctions

about

nx_nishi_usb_kernel.nx -- x86 ladder R-KERN-1: the long-mode kernel sets up real GDT + IDT and takes a VECTORED interrupt through the IDT. This is the first OS-internals rung at the long-mode entry the operator chose: lgdt -> a real GDT, lidt -> a real IDT, int -> the CPU vectors through the IDT gate to a handler that runs ONLY because the interrupt was delivered (not a direct call). The kernel is LOADED OFF the persisted image (nishi_os_kernel.img) and booted to LONG mode, then: * builds a spec-shaped GDT (null + 64-bit code [L-bit] + data) as static data, lgdt [pseudo] * builds a spec-shaped IDT whose entry 3 is a real interrupt gate (offset split across the offset_low/offset_mid/offset_high fields, selector 0x08, type 0x8E), lidt [pseudo] * mov rsp + int 3 -> the emu reads IDT[3], reconstructs the handler offset, pushes the return address, and vectors to the handler; the handler writes a marker and IRETs back; HLT. The unified emu now fuses FOUR proven mechanisms: the 16-bit + INT 13h loader, the CR0/EFER mode transition, the 64-bit store/arith engine, and IDT interrupt delivery + iret (from nx_nishios_irq). KAT: (T1) booted off disk; (T2) LONG mode; (T3) GDTR loaded (base+limit); (T4) the GDT holds a 64-bit code descriptor (L-bit set); (T5) IDTR loaded; (T6) int 3 vectored through the IDT -> the handler ran (marker written). NEG/liar-kill (T7): a sibling image whose IDT[3] offset is ZEROED never vectors, so the handler never runs and the marker stays unwritten -- the handler runs ONLY via a real IDT gate. HONEST SCOPE: long mode is flat so the emu loads/validates the GDT but does not enforce segmentation; the IDT delivery (gate read -> reconstruct offset -> push -> vector -> iret) is real. Paging (CR3 + PML4 walk) and PIC/IRQ0 timer preemption are the next two rungs. NEVER-BRICK (Rule 26): writes a FILE; models INT 13h *reads* only; no /dev. expect_exit: 0 license_tier: ORIGINAL

dependencies 2 imports · 0 importers

nx_syscalls.nx nx_itoa_lib.nx nx_nishi_usb_kernel.nx

imports: nx_syscalls.nxnx_itoa_lib.nx

imported by: nobody (leaf or entry point)

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main k_puts sys_write sys_mmap build_image uf_movr wr16 wr64 sys_openat_wr sys_exit sys_write ↻ sys_close k_read sys_openat_rd sys_read sys_close ↻ boot_image sys_mmap ↻ emu_x86_boot_kern sys_mmap ↻ k_mode k_ld64 k_st64 k_ld16 k_ld32 k_num nxi_out nxi_fd sys_mmap ↻ ccz_cat_num sys_write ↻ sys_munmap

structs

none

consts

27const IMG_MAGIC_2000000: i64 = 2000000
28const IMG_MAGIC_32767: i64 = 32767
29const IMG_MAGIC_65536: i64 = 65536
134const IMG_SZ: i64 = 1024

functions

31func k_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
called by 1: main calls 1: sys_write
36func k_num(v: i64) -> i64 { nxi_out(v); return 0 }
called by 1: main calls 1: nxi_out
37func k_contains(hay: *u8, hn: i64, ndl: *u8, nn: i64) -> i64 { if nn==0 { return 1 } var i: i64=0; 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 } return 0 }
38func k_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 }
called by 1: emu_x86_boot_kern
39func k_st64(mem: *u8, a: i64, v: i64) -> i64 { var i: i64=0; while i<8 { mem[a+i]=((v>>(i*8))&0xff) as u8; i=i+1 } return 0 }
called by 1: emu_x86_boot_kern
40func k_ld64(mem: *u8, a: i64) -> i64 { var v: i64=0; var i: i64=0; while i<8 { v=v|((mem[a+i] as i64)<<(i*8)); i=i+1 } return v }
called by 1: emu_x86_boot_kern
41func k_ld16(mem: *u8, a: i64) -> i64 { return (mem[a] as i64) | ((mem[a+1] as i64)<<8) }
called by 1: emu_x86_boot_kern
42func k_ld32(mem: *u8, a: i64) -> i64 { return (mem[a] as i64) | ((mem[a+1] as i64)<<8) | ((mem[a+2] as i64)<<16) | ((mem[a+3] as i64)<<24) }
called by 1: emu_x86_boot_kern
46func emu_x86_boot_kern(mem: *u8, disk: *u8, entry: i64, console: *u8, clen: *i64, st: *i64) -> i64
136func uf_movr(img: *u8, base: i64, o: i64, modrm: i64, imm: i64) -> i64
called by 1: build_image
141func wr16(img: *u8, a: i64, v: i64) -> i64 { img[a]=(v&0xff) as u8; img[a+1]=((v>>8)&0xff) as u8; return 0 }
called by 1: build_image
142func wr64(img: *u8, a: i64, v: i64) -> i64 { var i: i64=0; while i<8 { img[a+i]=((v>>(i*8))&0xff) as u8; i=i+1 } return 0 }
called by 1: build_image
145func build_image(img: *u8, info: *i64) -> i64
called by 1: main calls 3: uf_movrwr16wr64
244func boot_image(img: *u8, console: *u8, clen: *i64, st: *i64, loaded: *i64) -> i64
called by 1: main calls 2: sys_mmapemu_x86_boot_kern
257func k_read(path: *u8, out: *u8, cap: i64) -> i64
called by 1: main calls 3: sys_openat_rdsys_readsys_close
266func main() -> i64