145 lines
5.4 KiB
Nim
145 lines
5.4 KiB
Nim
# SPDX-License-Identifier: LSL-1.0
|
|
# Copyright (c) 2026 Markus Maiwald
|
|
# Stewardship: Self Sovereign Society Foundation
|
|
#
|
|
# This file is part of the Nexus Sovereign Core.
|
|
# See legal/LICENSE_SOVEREIGN.md for license terms.
|
|
|
|
## Sovereign Init: The Genesis Process
|
|
##
|
|
## Responsible for bootstrapping the system, starting core services,
|
|
## and managing the lifecycle of the user environment.
|
|
|
|
import ../../libs/membrane/libc
|
|
|
|
# --- Entry Point ---
|
|
|
|
proc main() =
|
|
# 1. Pledge Sovereignty
|
|
discard pledge(0xFFFFFFFFFFFFFFFF'u64) # PLEDGE_ALL
|
|
|
|
print(cstring("\n"))
|
|
print(cstring("\x1b[1;35m╔═══════════════════════════════════════╗\x1b[0m\n"))
|
|
print(cstring("\x1b[1;35m║ SOVEREIGN INIT (NexInit v0.1) ║\x1b[0m\n"))
|
|
print(cstring("\x1b[1;35m╚═══════════════════════════════════════╝\x1b[0m\n\n"))
|
|
|
|
print(cstring("[INIT] System Ready. Starting heartbeat...\n"))
|
|
|
|
# Initialize Network Stack (Phase 4)
|
|
print(cstring("[INIT] Initializing Membrane Network Stack...\n"))
|
|
membrane_init()
|
|
|
|
proc glue_get_ip(): uint32 {.importc: "glue_get_ip", cdecl.}
|
|
|
|
# Wait for IP (Max 30 seconds)
|
|
print(cstring("[INIT] Waiting for DHCP IP Address...\n"))
|
|
var ip: uint32 = 0
|
|
for i in 0 ..< 300:
|
|
pump_membrane_stack()
|
|
ip = glue_get_ip()
|
|
if ip != 0: break
|
|
|
|
# Sleep 100ms (100,000,000 ns)
|
|
discard syscall(0x65, 100000000'u64)
|
|
|
|
if ip == 0:
|
|
print(cstring("\x1b[1;33m[INIT] WARNING: Ongoing DHCP discovery. Proceeding with caution...\x1b[0m\n"))
|
|
else:
|
|
print(cstring("[INIT] Network ONLINE.\n"))
|
|
|
|
# --- TEST: Verify getaddrinfo with IP ---
|
|
print(cstring("[INIT] Phase 1: Verify getaddrinfo shim with IP Address...\n"))
|
|
var res: ptr AddrInfo
|
|
if getaddrinfo("8.8.8.8", nil, nil, addr res) == 0:
|
|
print(cstring("[INIT] Success: Shim correctly handled IP address string.\n"))
|
|
freeaddrinfo(res)
|
|
else:
|
|
print(cstring("\x1b[1;31m[INIT] ERROR: getaddrinfo shim failed for 8.8.8.8\x1b[0m\n"))
|
|
|
|
# --- HEPHAESTUS DIAGNOSTIC: PING TEST ---
|
|
print(cstring("\n[TEST] ══════════════════════════════════════\n"))
|
|
print(cstring("[TEST] ICMP Ping Diagnostic (Hephaestus)\n"))
|
|
print(cstring("[TEST] Target: 10.0.2.2 (QEMU Gateway)\n"))
|
|
print(cstring("[TEST] ══════════════════════════════════════\n\n"))
|
|
|
|
# The ping implementation is already in net_glue.nim (lines 58-103)
|
|
# We just need to trigger it via the existing mechanism
|
|
# For now, let's just pump the stack and let the built-in ping run
|
|
# Actually, looking at net_glue.nim line 293-302, it already auto-pings!
|
|
|
|
print(cstring("[TEST] Membrane auto-ping is enabled in net_glue.nim\n"))
|
|
print(cstring("[TEST] Pumping stack for 10 seconds to allow ICMP traffic...\n"))
|
|
|
|
for i in 1..10:
|
|
pump_membrane_stack()
|
|
discard syscall(0x65, 1000000000'u64) # 1 second
|
|
|
|
print(cstring("[TEST] Ping window complete. Check qemu_network.pcap for:\n"))
|
|
print(cstring("[TEST] - ICMP Echo Request (10.0.2.15 -> 10.0.2.2)\n"))
|
|
print(cstring("[TEST] - ICMP Echo Reply (10.0.2.2 -> 10.0.2.15)\n\n"))
|
|
|
|
# --- DNS RESOLUTION TEST ---
|
|
print(cstring("\n[TEST] ══════════════════════════════════════\n"))
|
|
print(cstring("[TEST] DNS Resolution Test\n"))
|
|
print(cstring("[TEST] Target: google.com\n"))
|
|
print(cstring("[TEST] ══════════════════════════════════════\n\n"))
|
|
|
|
var dns_success = false
|
|
for attempt in 1..3:
|
|
print(cstring("[TEST] DNS Attempt... "))
|
|
|
|
if getaddrinfo("google.com", nil, nil, addr res) == 0:
|
|
print(cstring("SUCCESS!\n"))
|
|
dns_success = true
|
|
freeaddrinfo(res)
|
|
break
|
|
else:
|
|
print(cstring("FAILED. Retrying in 2s...\n"))
|
|
for j in 1..20:
|
|
pump_membrane_stack()
|
|
discard syscall(0x65, 100000000'u64)
|
|
|
|
if dns_success:
|
|
print(cstring("[TEST] ✓ DNS: PASS\n\n"))
|
|
else:
|
|
print(cstring("[TEST] ✗ DNS: FAIL\n\n"))
|
|
|
|
# Spawn mksh as a separate fiber fibers (NOT execv - we stay alive as supervisor)
|
|
proc spawn_fiber(path: cstring): int =
|
|
# SYS_SPAWN_FIBER = 0x300
|
|
return int(syscall(0x300, cast[uint64](path), 0, 0))
|
|
|
|
let fiber_id = spawn_fiber(cstring("/bin/mksh"))
|
|
if fiber_id > 0:
|
|
print(cstring("[INIT] Spawned mksh fiber ID: "))
|
|
# Note: Can't easily print int in minimal libc, just confirm success
|
|
print(cstring("OK\n"))
|
|
else:
|
|
print(cstring("\x1b[1;31m[INIT] Failed to spawn shell!\x1b[0m\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:
|
|
# Process network events and LwIP timers
|
|
pump_membrane_stack()
|
|
|
|
# Heartbeat every iteration
|
|
loop_count += 1
|
|
if loop_count mod 1 == 0:
|
|
print(cstring("[INIT] Heartbeat\n"))
|
|
|
|
# Sleep 10ms using Timer Driver (System Call)
|
|
discard syscall(0x65, 10000000'u64)
|
|
|
|
when isMainModule:
|
|
main()
|