192 lines
5.3 KiB
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.}
|