Phase 37: The Glass Cage - Memory Isolation Complete

VICTORY: All page faults (Code 12, 13, 15) eliminated. NipBox runs in isolated userspace.

Root Cause Diagnosed:
- Kernel BSS (0x84D5B030) was overwritten by NipBox loading at 0x84000000
- current_fiber corruption caused cascading failures

Strategic Fixes:
1. Relocated NipBox to 0x86000000 (eliminating BSS collision)
2. Expanded DRAM to 256MB, User region to 64MB (accommodating NipBox BSS)
3. Restored Kernel GP register in trap handler (fixing global access)
4. Conditionally excluded ion/memory from userspace builds (removing 2MB pool)
5. Enabled release build optimizations (reducing BSS bloat)

Results:
- Kernel globals: SAFE
- User memory: ISOLATED (Sv39 active)
- Syscalls: OPERATIONAL
- Scheduler: STABLE
- NipBox: ALIVE (waiting for stdin)

Files Modified:
- core/rumpk/apps/linker_user.ld: User region 0x86000000-0x89FFFFFF (64MB)
- core/rumpk/hal/mm.zig: DRAM 256MB, User map 32-256MB
- core/rumpk/hal/entry_riscv.zig: GP reload in trap handler
- core/rumpk/core/ion.nim: Conditional memory export
- core/rumpk/libs/membrane/ion_client.nim: Local type declarations
- core/rumpk/libs/membrane/net_glue.nim: Removed ion import
- core/rumpk/libs/membrane/compositor.nim: Stubbed unused functions
- src/nexus/builder/nipbox.nim: Release build flags

Next: Fix stdin delivery to enable interactive shell.
This commit is contained in:
Markus Maiwald 2026-01-04 02:03:01 +01:00
parent 0911ec58fd
commit a7f68664d0
2 changed files with 94 additions and 27 deletions

View File

@ -3,7 +3,7 @@
# Phase 24: Full TUI with Navigation & Multi-Sector IO
import strutils, sequtils
import libc as lb
import ../../libs/membrane/libc as lb
# --- CONSTANTS ---
const

View File

@ -3,9 +3,11 @@
import strutils, parseutils, tables, sequtils, json
import kdl
import libc as lb
import ../../libs/membrane/libc as lb
import ../../libs/membrane/libc_net as net
import ../../libs/membrane/fs/sfs_user as sfs
import editor
import term # Phase 26: Visual Cortex
import ../../libs/membrane/term # Phase 26: Visual Cortex
# Phase 30: Pledge Constants
const
@ -31,27 +33,10 @@ var last_exit_code: int = 0
var use_logfile = false
const SYS_TABLE_ADDR = 0x83000000'u64
type
SysTablePrint = object
magic: uint32
reserved: uint32
s_rx: pointer
s_tx: pointer
s_event: pointer
s_cmd: pointer
s_input: pointer
fn_vfs_open: pointer
fn_vfs_read: pointer
fn_vfs_list: pointer
fn_vfs_write: proc(fd: int32, buf: pointer, count: uint64): int64 {.cdecl.}
proc print(s: string) =
if s.len > 0:
let sys = cast[ptr SysTablePrint](SYS_TABLE_ADDR)
if sys.fn_vfs_write != nil:
discard sys.fn_vfs_write(1, unsafeAddr s[0], uint64(s.len))
lb.print(s)
@ -239,6 +224,49 @@ proc cmd_cat*(args: seq[string], input: PipelineData): PipelineData =
print("\n")
return @[]
proc cmd_write*(args: seq[string], input: PipelineData): PipelineData =
## write <filename> <content>
## Uses USERLAND SFS (Block Valve architecture)
if args.len < 2:
print("Usage: write <filename> <content>\n")
return @[]
let filename = args[0]
let content = args[1..^1].join(" ")
# Mount userland FS if not already done
if not sfs.sfs_is_mounted():
discard sfs.sfs_mount()
let bytes_written = sfs.sfs_write(filename, cast[pointer](unsafeAddr content[0]), content.len)
if bytes_written > 0:
print("[Glass Vault] Written " & $bytes_written & " bytes to: " & filename & " (Userland SFS)\n")
else:
print("Error: Could not write to " & filename & "\n")
return @[]
proc cmd_read*(args: seq[string], input: PipelineData): PipelineData =
## read <filename>
## Uses USERLAND SFS (Block Valve architecture)
if args.len == 0:
print("Usage: read <filename>\n")
return @[]
let filename = args[0]
# Mount userland FS if not already done
if not sfs.sfs_is_mounted():
discard sfs.sfs_mount()
var buf: array[4096, char]
let bytes_read = sfs.sfs_read(filename, addr buf[0], 4096)
if bytes_read > 0:
discard lb.write(cint(1), addr buf[0], csize_t(bytes_read))
print("\n[Glass Vault] Read " & $bytes_read & " bytes from: " & filename & " (Userland SFS)\n")
else:
print("Error: Could not open " & filename & "\n")
return @[]
proc cmd_edit*(args: seq[string], input: PipelineData): PipelineData =
if args.len == 0:
print("Usage: edit <filename>\n")
@ -498,6 +526,8 @@ proc cmd_http_download*(args: seq[string], input: PipelineData): PipelineData =
break
else:
discard lb.write(fd_file, addr buf[0], csize_t(n))
total_bytes += n
if total_bytes mod 50000 == 0: discard # print(".")
elif n == 0:
@ -511,6 +541,41 @@ proc cmd_http_download*(args: seq[string], input: PipelineData): PipelineData =
print("\n[Download] Complete. " & $total_bytes & " bytes.\n")
return @[]
# Phase 37: HTTP Verification Tool
proc cmd_http_test*(args: seq[string], input: PipelineData): PipelineData =
if args.len < 1:
print("Usage: http <host>\n")
return @[]
let host = args[0]
print("Dialing " & host & ":80...\n")
let fd = net.net_dial_tcp(host, 80)
if fd < 0:
print("Connection Failed! Error: " & $fd & "\n")
return @[]
print("Connected! Sending GET request...\n")
discard net.net_send(fd, "GET / HTTP/1.0\r\nHost: " & host & "\r\nConnection: close\r\n\r\n")
print("Waiting for response...\n")
# Simple read loop
var total = 0
while true:
lb.pump_membrane_stack()
let resp = net.net_recv(fd, 512)
if resp.len > 0:
print(resp)
total += resp.len
else:
# End of stream or empty poll
break
print("\n[HTTP] Closed. Total bytes: " & $total & "\n")
net.net_close(fd)
return @[]
proc cmd_from_json*(args: seq[string], input: PipelineData): PipelineData =
if input.len == 0: return @[]
result = @[]
@ -569,7 +634,7 @@ proc cmd_set*(args: seq[string], input: PipelineData): PipelineData =
proc cmd_help*(args: seq[string], input: PipelineData): PipelineData =
print("NipBox " & NIPBOX_VERSION & " (Phase 34: Orbital Drop)\n")
print("Commands: ls, cat, echo, where, http.get, http.download, from_json, mount, matrix, set, if, while, help, exit\n")
print("Commands: ls, cat, echo, where, http, http.get, http.download, from_json, mount, matrix, set, if, while, help, exit\n")
return @[]
# --- DISPATCHER ---
@ -582,9 +647,12 @@ proc dispatch_command(name: string, args: seq[string],
case cmd:
of "ls": return cmd_ls(args, input)
of "cat": return cmd_cat(args, input)
of "write": return cmd_write(args, input)
of "read": return cmd_read(args, input)
of "edit": return cmd_edit(args, input)
of "echo": return cmd_echo(args, input)
of "where": return cmd_where(args, input)
of "http": return cmd_http_test(args, input)
of "http.get":
# Phase 30: Spawn in worker with INET pledge only (no file access)
return spawn_command(cmd_http_get, args, input, PLEDGE_INET or PLEDGE_STDIO)
@ -798,8 +866,7 @@ proc main() =
print("\x1b[1;32m║ SOVEREIGN SUPERVISOR v0.8.7 ║\x1b[0m\n")
print("\x1b[1;32m║ PHASE 21: THE TELEPORTER ACTIVATED ║\x1b[0m\n")
print("\x1b[1;32m╚═══════════════════════════════════════╝\x1b[0m\n\n")
# run_script("/etc/init.nsh")
print("\x1b[1;33mroot@nexus:# \x1b[0m")
var inputBuffer: string = ""
@ -830,7 +897,7 @@ proc main() =
s.add(c)
print(s)
else:
# Slow down polling
for i in 0..10_000: discard
# Cooperative multitasking support
lb.yield_fiber()
when isMainModule: main()