diff --git a/apps/init/init.nim b/apps/init/init.nim index c0ba080..5291422 100644 --- a/apps/init/init.nim +++ b/apps/init/init.nim @@ -25,6 +25,10 @@ proc main() = print(cstring("[INIT] System Ready. Starting heartbeat...\n")) + # Initialize Network Stack (Phase 4) + print(cstring("[INIT] Initializing Membrane Network Stack...\n")) + membrane_init() + # Spawn mksh as a separate fiber (NOT execv - we stay alive as supervisor) proc spawn_fiber(path: cstring): int = # SYS_SPAWN_FIBER = 0x300 @@ -38,13 +42,32 @@ proc main() = else: print(cstring("\x1b[1;31m[INIT] Failed to spawn shell!\x1b[0m\n")) - # Supervisor loop - stay alive, check fiber health periodically - print(cstring("[INIT] Entering supervisor mode...\n")) + + # Supervisor loop - REACTIVE MODE (Silence Doctrine) + # Only wake when network packets arrive or other I/O events occur + print(cstring("[INIT] Entering supervisor mode (REACTIVE)...\n")) + + # Slot 2 is CMD_NET_RX (0x501) granted by Kernel + const SLOT_NET_RX = 2 + let wait_mask = 1'u64 shl SLOT_NET_RX # Wait for network events + + + var loop_count = 0 while true: - # Sleep 1 second between checks - discard syscall(0x65, 1000000000'u64) # nanosleep: 1 second + # Process network events and LwIP timers pump_membrane_stack() - yield_fiber() + + # Heartbeat every iteration + loop_count += 1 + if loop_count mod 1 == 0: + print(cstring("[INIT] Heartbeat\n")) + + # Busy Wait Sleep (10ms) to bypass broken WFI/Timer + # TODO: Restore nanosleep once HAL Timer Driver is implemented + proc sys_now(): uint32 {.importc, cdecl.} + let start_sleep = sys_now() + while sys_now() - start_sleep < 10: + discard syscall(0x100, 0, 0, 0) # YIELD when isMainModule: main() diff --git a/core/kernel.nim b/core/kernel.nim index be1d61d..ffdd906 100644 --- a/core/kernel.nim +++ b/core/kernel.nim @@ -195,7 +195,7 @@ proc compositor_fiber_entry() {.cdecl.} = kprintln("[Compositor] Fiber Entry reached.") while true: if matrix_enabled: - fiber_sleep(10) + fiber_sleep(100) else: term.term_render() fiber_sleep(33) # 30Hz @@ -286,7 +286,7 @@ proc ion_fiber_entry() {.cdecl.} = fiber_child.satp_value = mm_create_worker_map(cast[uint64](addr stack_child[0]), uint64(sizeof(stack_child)), SYSTABLE_BASE, cell_base, cell_size) kprintln("[ION] Child fiber spawned successfully") else: discard - fiber_sleep(10) + fiber_sleep(100) proc fiber_yield*() {.exportc, cdecl.} = proc rumpk_yield_guard() {.importc, cdecl.} @@ -303,7 +303,7 @@ proc fiber_netswitch_entry() {.cdecl.} = if chan_netswitch_rx.recv(pkt): ion_free_raw(pkt.id) else: - fiber_sleep(2) + fiber_sleep(100) fiber_yield() proc ion_ingress*(id: uint16, len: uint16) {.exportc, cdecl.} = @@ -356,12 +356,19 @@ proc k_handle_syscall*(nr, a0, a1, a2: uint): uint {.exportc, cdecl.} = return 0 of 0x65: # NANOSLEEP let now = sched_get_now_ns() + kprint("Slp: "); kprint_hex(now); kprint(" "); kprint_hex(a0); kprint("\n") current_fiber.sleep_until = now + a0 fiber_yield() + kprint("Woke\n") return 0 of 0x100: # YIELD fiber_yield() return 0 + of 0x102: # SYS_WAIT_MULTI (Silence Doctrine) + current_fiber.blocked_on_mask = a0 + current_fiber.is_blocked = true + fiber_yield() + return 0 of 0x200: # OPEN # return uint(libc_impl.libc_impl_open(cast[cstring](a0), int(a1))) return 0 @@ -448,8 +455,7 @@ proc kmain() {.exportc, cdecl.} = var next_mmio_addr {.importc: "virtio_pci_next_mmio_addr", nodecl.}: uint32 kprint("\n[Kernel] next_mmio_addr check: ") kprint_hex(uint64(next_mmio_addr)) - kprintln("") - kprintln("\nNexus Sovereign Core v1.1 Starting...") + kprintln("\nNexus Sovereign Core v1.1.1 Starting...") ion_pool_init() proc mm_init() {.importc, cdecl.} proc mm_enable_kernel_paging() {.importc, cdecl.} diff --git a/libs/membrane/libc.nim b/libs/membrane/libc.nim index 76676d6..f05f8ba 100644 --- a/libs/membrane/libc.nim +++ b/libs/membrane/libc.nim @@ -73,6 +73,8 @@ when not defined(RUMPK_KERNEL): discard syscall(0x100, 0) proc pump_membrane_stack*() {.importc, cdecl.} + proc membrane_init*() {.importc, cdecl.} + proc ion_user_wait_multi*(mask: uint64): int32 {.importc, cdecl.} proc pledge*(promises: uint64): int {.exportc, cdecl.} = return int(syscall(0x101, promises)) @@ -367,6 +369,7 @@ proc syscall_get_time_ns*(): uint64 {.exportc, cdecl.} = """.} return ticks + proc syscall_get_random*(): uint32 {.exportc, cdecl.} = ## Generate cryptographically strong random number for TCP ISN ## Implementation: SipHash-2-4(MonolithKey, Time || CycleCount) diff --git a/libs/membrane/net_glue.nim b/libs/membrane/net_glue.nim index ea491d1..d0bd175 100644 --- a/libs/membrane/net_glue.nim +++ b/libs/membrane/net_glue.nim @@ -13,10 +13,10 @@ import ion_client # NOTE: Do NOT import ../../core/ion - it pulls in the KERNEL-ONLY 2MB memory pool! -proc debug_print(s: pointer, len: uint) {.importc: "debug_print", cdecl.} - +proc console_write(s: pointer, len: csize_t) {.importc: "console_write", cdecl.} + proc glue_print(s: string) = - debug_print(unsafeAddr s[0], uint(s.len)) + console_write(unsafeAddr s[0], csize_t(s.len)) # LwIP Imports {.passC: "-Icore/rumpk/vendor/lwip/src/include".} @@ -66,7 +66,7 @@ type # Forward declarations for LwIP callbacks proc ion_linkoutput(netif: pointer, p: pointer): int32 {.exportc, cdecl.} = ## Callback: LwIP -> Netif -> ION Ring - # glue_print("[Membrane] Egress Packet\n") + glue_print("[Membrane] Egress Packet\n") var pkt: IonPacket if not ion_user_alloc(addr pkt): return -1 # ERR_MEM @@ -139,7 +139,7 @@ proc membrane_init*() {.exportc, cdecl.} = netif_set_default(&ni_static); netif_set_up(&ni_static); - // dhcp_start(&ni_static); // DISABLED: Nuking LwIP + dhcp_start(&ni_static); `g_netif` = &ni_static; """.} @@ -148,13 +148,24 @@ proc membrane_init*() {.exportc, cdecl.} = var last_notified_ip: uint32 = 0 +# proc glue_print_hex(v: uint64) = +# const hex_chars = "0123456789ABCDEF" +# var buf: array[20, char] +# buf[0] = '0'; buf[1] = 'x' +# var val = v +# for i in countdown(15, 0): +# buf[2+i] = hex_chars[int(val and 0xF)] +# val = val shr 4 +# buf[18] = '\n'; buf[19] = '\0' +# buf[18] = '\n'; buf[19] = '\0' +# console_write(addr buf[0], 20) + proc pump_membrane_stack*() {.exportc, cdecl.} = ## The Pulse of the Membrane. Call frequently to handle timers and RX. - if not ion_net_available(): return let now = sys_now() - # proc kprint_hex_ext(v: uint64) {.importc: "kprint_hex", cdecl.} - # kprint_hex_ext(uint64(now)) # Debug: Print time (LOUD!) + # glue_print("[Membrane] Time: ") + # glue_print_hex(uint64(now)) # 3. Check for IP (Avoid continuous Nim string allocation/leak) var ip_addr: uint32 @@ -181,12 +192,14 @@ proc pump_membrane_stack*() {.exportc, cdecl.} = dhcp_fine_tmr() last_dhcp_fine = now if now - last_dhcp_coarse >= 60000: + glue_print("[Membrane] DHCP Coarse Timer\n") dhcp_coarse_tmr() last_dhcp_coarse = now # 2. RX Ingress var pkt: IonPacket while ion_net_rx(addr pkt): + glue_print("[Membrane] Ingress Packet\n") # Pass to LwIP {.emit: """ struct pbuf *p = pbuf_alloc(PBUF_RAW, `pkt`.len, PBUF_POOL);