rumpk/core/kernel.nim

192 lines
5.3 KiB
Nim

# Rumpk Layer 1: The Logic Core
# Markus Maiwald (Architect) | Voxis Forge (AI)
{.push stackTrace: off, lineTrace: off.}
import fiber
import ion/memory
import ion/ion_switch
import ring
import net
# HAL Imports from Zig (Layer 0)
proc console_write(p: pointer, len: csize_t) {.importc, cdecl.}
proc rumpk_halt() {.importc, cdecl, noreturn.}
proc virtio_net_init() {.importc, cdecl.}
# Kernel I/O
proc kprint(s: string) =
if s.len > 0:
console_write(unsafeAddr s[0], csize_t(s.len))
proc kprintln(s: string) =
kprint(s)
kprint("\n")
# Panic Handler
proc nimPanic(msg: cstring) {.exportc: "panic", cdecl, noreturn.} =
kprint("\n[PANIC] ")
if msg != nil:
var i = 0
while msg[i] != '\0':
var buf: array[1, char]
buf[0] = msg[i]
console_write(addr buf[0], 1)
inc i
kprint("\n")
rumpk_halt()
# Networking Fiber
var fiber_net: FiberObject
var stack_net: array[8192, uint8]
var fiber_sniff: FiberObject
var stack_sniff: array[4096, uint8]
var fast_ring: RingBuffer[IonPacket, 256]
var sniff_flow: NetFlow
# =========================================================
# The Reflex (Zero-Copy Headers Swap)
# =========================================================
proc swap_macs(frame: ptr UncheckedArray[byte]) =
# Dst (0..5) <-> Src (6..11)
for i in 0..5:
let tmp = frame[i]
frame[i] = frame[6+i]
frame[6+i] = tmp
proc swap_ips(frame: ptr UncheckedArray[byte]) =
# IPv4 (Eth 14). Src=12, Dst=16. Total Offset = 14+12=26, 14+16=30
# Swap 4 bytes
for i in 0..3:
let tmp = frame[26+i]
frame[26+i] = frame[30+i]
frame[30+i] = tmp
proc swap_ports(frame: ptr UncheckedArray[byte]) =
# UDP (Eth 14 + IP 20). Src=0, Dst=2. Total Offset = 34, 36
# Swap 2 bytes
for i in 0..1:
let tmp = frame[34+i]
frame[34+i] = frame[36+i]
frame[36+i] = tmp
proc fast_path_consumer() {.cdecl.} =
var aliveMsg = "[ECHO] Fiber Alive! Ready to Bounce.\n"
console_write(addr aliveMsg[0], csize_t(aliveMsg.len))
while true:
var work = false
if not fast_ring.isEmpty:
let (ok, pkt) = fast_ring.pop()
if ok:
work = true
# Zero-Copy In-Place Modification
let frame = cast[ptr UncheckedArray[byte]](pkt.data)
# 1. Swap Headers
swap_macs(frame)
swap_ips(frame)
swap_ports(frame)
# 2. Log
var msg = "[ECHO] Bouncing Packet...\n"
console_write(addr msg[0], csize_t(msg.len))
# 3. Send (Pass Ownership to Driver)
ion_egress(pkt)
# Do NOT free here. Driver frees after TX.
if not work:
switch(addr fiber_net)
proc sniffer_init() =
fast_ring.init()
ion_tx_init() # Initialize the Global TX Ring
sniff_flow.port = 8080
sniff_flow.ring = addr fast_ring
sniff_flow.fType = FLOW_DIRECT
ion_register(8080, addr sniff_flow)
init_fiber(addr fiber_sniff, fast_path_consumer, addr stack_sniff[0])
proc launch_subject() {.importc, cdecl.}
var stack_subject: array[16384, byte] # Matches STACK_SIZE in fiber.nim if 16k is preferred
var fiber_subject: FiberObject
proc subject_fiber_entry() {.cdecl.} =
kprintln("[Membrane] Launching Subject Zero Canary...")
launch_subject()
proc net_fiber_entry() {.cdecl.} =
kprintln("[Net] Fiber started. Initializing stack...")
ion_pool_init()
virtio_net_init()
net_init()
sniffer_init()
kprintln("[Net] Interface UP (10.0.2.15)")
while true:
net_loop_cycle(addr rumpk_netif)
# Pump the Membrane Stack too
# (In a real scenario, this would be a separate thread or triggered by ION)
# pump_membrane_stack() # Import this?
switch(addr fiber_subject)
switch(addr fiber_sniff)
# Sovereign Syscall Table (Fixed Address: 0x801FFF00)
type
SysTable = object
s_yield*: pointer
s_alloc*: pointer
s_free*: pointer
s_tx*: pointer
s_rx*: pointer # Address of the shared RX Ring (Flow)
var guest_rx_ring: RingBuffer[IonPacket, 256]
var guest_flow: NetFlow
proc rumpk_yield_internal() {.cdecl.} =
switch(addr fiber_net)
proc rumpk_alloc_internal(): IonPacket {.cdecl.} =
return ion_alloc()
proc rumpk_free_internal(pkt: IonPacket) {.cdecl.} =
ion_free(pkt)
proc rumpk_tx_internal(pkt: IonPacket): bool {.cdecl.} =
return ion_tx_push(pkt)
proc kmain() {.exportc, cdecl.} =
# Initialize the Guest Flow
guest_rx_ring.init()
guest_flow.fType = FLOW_DIRECT
guest_flow.ring = addr guest_rx_ring
ion_register(8080, addr guest_flow)
# Register the SysTable at a fixed address for the Guest
let sys_table = cast[ptr SysTable](0x801FFF00'u64)
sys_table.s_yield = cast[pointer](rumpk_yield_internal)
sys_table.s_alloc = cast[pointer](rumpk_alloc_internal)
sys_table.s_free = cast[pointer](rumpk_free_internal)
sys_table.s_tx = cast[pointer](rumpk_tx_internal)
sys_table.s_rx = addr guest_rx_ring
kprintln("╔═══════════════════════════════════════╗")
kprintln("║ Layer 1: Nim Kernel Alive! ║")
kprintln("╚═══════════════════════════════════════╝")
init_fiber(addr fiber_subject, subject_fiber_entry, addr stack_subject[0])
init_fiber(addr fiber_net, net_fiber_entry, addr stack_net[0])
switch(addr fiber_net)
nimPanic("Main thread returned!")
{.pop.}