code wiki / _hdl_build / nx_emu_uefi.nx
nx_emu_uefi.nx
buildroot/runtime/_hdl_build/nx_emu_uefi.nx
about
nx_emu_uefi.nx -- the sovereign UEFI EXECUTION-PROOF harness (NOS execution gate).
A purpose-built minimal x86-64 interpreter WITH a flat memory model + stack + a hooked
UEFI SystemTable, just enough to EXECUTE the entry of an emitted nx_boot_uefi*.efi and
PROVE it does what it claims -- the in-house analog of running the RV64 boot stub on
rv64im_min_sim (no qemu, no real laptop). It sets up a mock SystemTable/ConOut whose
OutputString is a sentinel HOOK; when the executed code calls it, we CAPTURE the UTF-16
string it asked to print. A correct nx_boot_uefi prints "NISHI"; the buggy off-by-one
variant would capture garbage -- so this is a real gate, not a structural rubber-stamp.
Memory is the flat image space with ImageBase=0: .text loaded at its RVA (0x1000), so
RIP-relative leas resolve to the real string RVAs. Mock UEFI placed elsewhere in MEM.
Decoded forms (exactly what the nx_boot_uefi* / nx_gop_efi emitters produce):
50+r push r64 | 58+r pop r64 | C3 ret | 31 /r xor r/m,r (reg-direct)
48 83 grp1 (add/sub/and/cmp imm8) | 48 C7 mov r64,imm32 | 48 C1/D3 shr | 48 01/29/39 add/sub/cmp
48 31 /r xor r64,r64 (reg-direct) | 48 89 /r mov store | 48 8B /r mov load (disp8/SIB+disp8/disp32/reg)
48 8D lea [rip+disp32] (mod00) or [SIB-base+disp8] (mod01) | B8+rd mov r32,imm32 (zero-extended)
FC cld | F3 AB rep stosd (one interpreter step, bounds-refused -34)
FF /2 call [base+disp8] (mod01) or call r64 (mod11) -- HOOK-aware
EB FE jmp $ -> distinct HOLD return: a painting app KEEPS the screen; the verdict is then
decided by MEASURING the modeled framebuffer (color read from the artifact, never assumed):
nonzero color AND 100% fill -> PAINTED-AND-HOLDING, anything less -> RED.
Mock UEFI hooks: ConOut->OutputString (capture) | BootServices->GetMemoryMap (writes 0x1800) |
BootServices->LocateProtocol (GUID-CHECKED: only the GOP GUID is served, wrong GUID -> -33)
-> modeled GOP: gop->Mode->FrameBufferBase/Size = a real 1280x800x32 in-MEM framebuffer
(mirrors the OVMF oracle mode, so sovereign + foreign engines judge the same geometry).
Usage: nx_emu_uefi <path.efi> [expect-prefix] | nx_emu_uefi selftest (4 teeth incl. negative controls)
Gate: captured console output begins "NISHI" -> GREEN. Log -> knowledge/status/nishi_os.log
Sovereign: syscalls only, no gcc/qemu/.sh. license_tier: ORIGINAL
dependencies 1 imports · 0 importers
imports: nx_syscalls.nx
imported by: nobody (leaf or entry point)
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| 32 | const RET_MAGIC_200000: i64 = 200000 |
| 34 | const MEMSZ: i64 = 0x800000 // raised for AI2: the served AI blob sits above the kernel window |
| 35 | const HOOK: i64 = 0x9000 |
| 36 | const RET_SENTINEL: i64 = 0xC0DE |
| 37 | const ST_ADDR: i64 = 0x4000 |
| 38 | const CO_ADDR: i64 = 0x4800 |
| 39 | const FV_ADDR: i64 = 0x4900 |
| 40 | const STACK_TOP: i64 = 0x20000 // RAISED: the loader's virtual image (code + reserves) now ends |
| 45 | const BS_ADDR: i64 = 0x4C00 |
| 46 | const HOOK2: i64 = 0x9100 |
| 47 | const HOOK3: i64 = 0x9200 |
| 48 | const HOOK4: i64 = 0x9300 |
| 49 | const HOOK5: i64 = 0x9400 |
| 50 | const CI_ADDR: i64 = 0x4A00 |
| 51 | const KEYQ_ADDR: i64 = 0x4B00 |
| 52 | const EFI_NOT_READY: i64 = 6 |
| 53 | const EFI_NOT_FOUND: i64 = 14 // what real firmware returns for a file that is not there -- |
| 55 | const EFI_INVALID_PARAM: i64 = 2 |
| 56 | const EFI_BUFFER_TOO_SMALL: i64 = 5 |
| 61 | const MM_REQ_BYTES: i64 = 0x1800 // required map size the modeled firmware reports |
| 62 | const MM_DESC_SIZE: i64 = 0x30 // EFI_MEMORY_DESCRIPTOR stride |
| 63 | const MM_MAPKEY: i64 = 0x5AFEC0DE // the key a SUCCESSFUL GetMemoryMap issues |
| 64 | const EBS_STATE: i64 = 0x4D00 // [0]=exited? [8]=issued map key |
| 67 | const HOOK6: i64 = 0x9500 // BootServices->HandleProtocol |
| 68 | const HOOK7: i64 = 0x9600 // SimpleFileSystem->OpenVolume |
| 69 | const HOOK8: i64 = 0x9700 // File->Open |
| 70 | const HOOK9: i64 = 0x9800 // File->Read |
| 75 | const HOOK10: i64 = 0x9900 // BootServices->LocateHandleBuffer (BS + 0x138) |
| 76 | const DEV2_HANDLE: i64 = 0x501100 // the DATA partition's device handle |
| 77 | const FS2_ADDR: i64 = 0x502100 // its EFI_SIMPLE_FILE_SYSTEM |
| 78 | const ROOT2_ADDR: i64 = 0x503100 // its root EFI_FILE |
| 79 | const HBUF_ADDR: i64 = 0x509000 // the handle array firmware hands back |
| 80 | const HCNT_ADDR: i64 = 0x50A000 // and its count |
| 86 | const LI_ADDR: i64 = 0x500000 // EFI_LOADED_IMAGE_PROTOCOL (+0x18 DeviceHandle) |
| 87 | const DEV_HANDLE: i64 = 0x501000 // the ESP device handle we hand back |
| 88 | const FS_ADDR: i64 = 0x502000 // EFI_SIMPLE_FILE_SYSTEM (+0x08 OpenVolume) |
| 89 | const ROOT_ADDR: i64 = 0x503000 // root EFI_FILE_PROTOCOL (+0x08 Open) |
| 90 | const FILE_ADDR: i64 = 0x504000 // opened EFI_FILE_PROTOCOL (+0x20 Read) |
| 91 | const KFILE_LEN: i64 = 0x505000 // [0] = served file length |
| 92 | const KFILE_DATA: i64 = 0x580000 |
| 96 | const AIFILE_ADDR: i64 = 0x507000 // opened EFI_FILE_PROTOCOL for the AI blob |
| 97 | const AIFILE_LEN: i64 = 0x508000 // [0] = served AI blob length (0 = ABSENT, Open must refuse) |
| 98 | const AIFILE_DATA: i64 = 0x600000 // served AI bytes (above the kernel window, inside MEMSZ) |
| 103 | const PCI_ADDR_PORT: i64 = 0xCF8 |
| 104 | const PCI_DATA_PORT: i64 = 0xCFC |
| 105 | const PCI_LATCH: i64 = 0x506000 // last value written to CONFIG_ADDRESS |
| 106 | const PCI_NDEV: i64 = 3 // modeled devices on bus 0, functions 0 // served file bytes (well clear of the framebuffer) |
| 110 | const PS2_STATE: i64 = 0x4E00 // [0]=count [8]=index [16+8i]=scancodes |
| 111 | const PS2_PORT_STATUS: i64 = 0x64 |
| 112 | const PS2_PORT_DATA: i64 = 0x60 |
| 113 | const GOP_ADDR: i64 = 0x5000 |
| 114 | const MODE_ADDR: i64 = 0x5100 |
| 115 | const FB_ADDR: i64 = 0x100000 |
| 116 | const FB_SIZE: i64 = 0x3E8000 |
| 117 | const FB_W_PIX: i64 = 1280 |
| 118 | const FB_H_PIX: i64 = 800 |
| 121 | const R_RAX: i64 = 0 |
| 122 | const R_RCX: i64 = 1 |
| 123 | const R_RDX: i64 = 2 |
| 124 | const R_RSP: i64 = 4 |
| 125 | const R_RDI: i64 = 7 |
functions
| 128 | func m_r8(mem: *u8, a: i64) -> i64 { return mem[a] as i64 } |
| 129 | func m_r64(mem: *u8, a: i64) -> i64 |
| 134 | func m_w64(mem: *u8, a: i64, v: i64) -> i64 |
| 139 | func m_w16(mem: *u8, a: i64, v: i64) -> i64 |
| 143 | func m_i32(mem: *u8, off: i64) -> i64 called by 1: emu_run |
| 149 | func f_u32(fb: *u8, off: i64) -> i64 called by 1: main |
| 152 | func sx8(b: i64) -> i64 { if b >= 128 { return b - 256 } return b } called by 1: emu_run |
| 155 | func cap_str(mem: *u8, straddr: i64, out: *u8, outn: i64) -> i64 called by 1: emu_run |
| 169 | func li_guid_b(i: i64) -> i64 |
| 176 | func fs_guid_b(i: i64) -> i64 |
| 185 | func esp_name_ch(which: i64, i: i64) -> i64 called by 1: u16_name_is |
| 195 | func u16_name_is(mem: *u8, at: i64, which: i64) -> i64 |
| 209 | func guid_eq(mem: *u8, at: i64, which: i64) -> i64 |
| 226 | func pci_cfg_read(latch: i64) -> i64 called by 1: emu_run |
| 248 | func emu_hook_call(mem: *u8, tgt: i64, reg: *i64) -> i64 |
| 324 | func gop_guid_b(i: i64) -> i64 called by 1: emu_run |
| 332 | func emu_run(mem: *u8, entry: i64, out: *u8, trace: i64) -> i64 |
| 692 | func e_p(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } |
| 693 | func e_fp(fd: i64, s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(fd, s, n); return 0 } |
| 694 | func e_fn(fd: i64, v: i64) -> i64 |
| 704 | func e_fx(fd: i64, v: i64) -> i64 |
| 714 | func fb_dump_bmp(mem: *u8, base: i64, w: i64, h: i64, path: *u8) -> i64 |
| 746 | func m_w32b(b: *u8, o: i64, v: i64) -> i64 |
| 753 | func s_atoi(s: *u8) -> i64 |
| 767 | func px_probe(mem: *u8, base: i64, argc: i64, argv: *i64) -> i64 |
| 786 | func s_eq(a: *u8, b: *u8) -> i64 |
| 796 | func fb_measure(mem: *u8, base: i64, size: i64, outp: *i64) -> i64 |
| 821 | func hold_verdict(color: i64, matches: i64, ndw: i64, zeros: i64, trans: i64) -> i64 |
| 829 | func st_w(mem: *u8, o: i64, v: i64) -> i64 { mem[o] = (v & 0xff) as u8; return o + 1 } |
| 830 | func st_i32(mem: *u8, o: i64, v: i64) -> i64 |
| 837 | func emu_selftest() -> i64 |
| 1075 | func main(argc: i64, argv: *i64) -> i64 |