166 lines
4.9 KiB
Nim
166 lines
4.9 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.
|
|
|
|
## Rumpk Layer 1: Sovereign VFS (The Loom)
|
|
##
|
|
## Freestanding implementation (No OS module dependencies).
|
|
## Uses fixed-size arrays for descriptors to ensure deterministic latency.
|
|
|
|
import tar, sfs
|
|
|
|
type
|
|
VFSMode = enum
|
|
MODE_TAR, MODE_SFS, MODE_RAM, MODE_TTY
|
|
|
|
MountPoint = object
|
|
prefix: array[32, char]
|
|
mode: VFSMode
|
|
|
|
FileHandle = object
|
|
path: array[64, char]
|
|
offset: uint64
|
|
mode: VFSMode
|
|
active: bool
|
|
|
|
const MAX_MOUNTS = 8
|
|
const MAX_FDS = 32
|
|
|
|
var mnt_table: array[MAX_MOUNTS, MountPoint]
|
|
var mnt_count: int = 0
|
|
|
|
var fd_table: array[MAX_FDS, FileHandle]
|
|
|
|
# Helper: manual string compare
|
|
proc vfs_starts_with(s, prefix: cstring): bool =
|
|
let ps = cast[ptr UncheckedArray[char]](s)
|
|
let pp = cast[ptr UncheckedArray[char]](prefix)
|
|
var i = 0
|
|
while pp[i] != '\0':
|
|
if ps[i] != pp[i]: return false
|
|
i += 1
|
|
return true
|
|
|
|
proc vfs_streq(s1, s2: cstring): bool =
|
|
let p1 = cast[ptr UncheckedArray[char]](s1)
|
|
let p2 = cast[ptr UncheckedArray[char]](s2)
|
|
var i = 0
|
|
while true:
|
|
if p1[i] != p2[i]: return false
|
|
if p1[i] == '\0': return true
|
|
i += 1
|
|
|
|
proc vfs_add_mount(prefix: cstring, mode: VFSMode) =
|
|
if mnt_count >= MAX_MOUNTS: return
|
|
let p = cast[ptr UncheckedArray[char]](prefix)
|
|
var i = 0
|
|
while p[i] != '\0' and i < 31:
|
|
mnt_table[mnt_count].prefix[i] = p[i]
|
|
i += 1
|
|
mnt_table[mnt_count].prefix[i] = '\0'
|
|
mnt_table[mnt_count].mode = mode
|
|
mnt_count += 1
|
|
|
|
proc vfs_mount_init*() =
|
|
# Restore the SPEC-130 baseline
|
|
vfs_add_mount("/nexus", MODE_SFS)
|
|
vfs_add_mount("/sysro", MODE_TAR)
|
|
vfs_add_mount("/state", MODE_RAM)
|
|
vfs_add_mount("/dev/tty", MODE_TTY)
|
|
vfs_add_mount("/Bus/Console/tty0", MODE_TTY)
|
|
|
|
proc resolve_path(path: cstring): (VFSMode, int) =
|
|
for i in 0..<mnt_count:
|
|
let prefix = cast[cstring](addr mnt_table[i].prefix[0])
|
|
if vfs_starts_with(path, prefix):
|
|
var len = 0
|
|
while mnt_table[i].prefix[len] != '\0': len += 1
|
|
return (mnt_table[i].mode, len)
|
|
return (MODE_TAR, 0)
|
|
|
|
proc ion_vfs_open*(path: cstring, flags: int32): int32 {.exportc, cdecl.} =
|
|
let (mode, prefix_len) = resolve_path(path)
|
|
|
|
# Delegate internal open
|
|
let sub_path = cast[cstring](cast[uint64](path) + uint64(prefix_len))
|
|
var internal_fd: int32 = -1
|
|
|
|
case mode:
|
|
of MODE_TAR, MODE_RAM: internal_fd = tar.vfs_open(sub_path, flags)
|
|
of MODE_SFS: internal_fd = 0 # Shim
|
|
of MODE_TTY: internal_fd = 1 # Shim
|
|
|
|
if internal_fd >= 0:
|
|
for i in 0..<MAX_FDS:
|
|
if not fd_table[i].active:
|
|
fd_table[i].active = true
|
|
fd_table[i].mode = mode
|
|
fd_table[i].offset = 0
|
|
let p = cast[ptr UncheckedArray[char]](sub_path)
|
|
var j = 0
|
|
while p[j] != '\0' and j < 63:
|
|
fd_table[i].path[j] = p[j]
|
|
j += 1
|
|
fd_table[i].path[j] = '\0'
|
|
return int32(i + 3) # FDs start at 3
|
|
return -1
|
|
|
|
proc ion_vfs_read*(fd: int32, buf: pointer, count: uint64): int64 {.exportc, cdecl.} =
|
|
let idx = int(fd - 3)
|
|
if idx < 0 or idx >= MAX_FDS or not fd_table[idx].active: return -1
|
|
let fh = addr fd_table[idx]
|
|
|
|
case fh.mode:
|
|
of MODE_TTY: return -2
|
|
of MODE_TAR, MODE_RAM:
|
|
let path = cast[cstring](addr fh.path[0])
|
|
let n = tar.vfs_read_at(path, buf, count, fh.offset)
|
|
if n > 0: fh.offset += uint64(n)
|
|
return n
|
|
of MODE_SFS:
|
|
let path = cast[cstring](addr fh.path[0])
|
|
var temp: array[256, byte] # Small shim
|
|
let n = sfs.sfs_read_file(path, addr temp[0], 256)
|
|
if n <= 0: return -1
|
|
let avail = uint64(n) - fh.offset
|
|
let actual = if count < avail: count else: avail
|
|
if actual > 0:
|
|
copyMem(buf, addr temp[int(fh.offset)], int(actual))
|
|
fh.offset += actual
|
|
return int64(actual)
|
|
return 0
|
|
|
|
proc ion_vfs_write*(fd: int32, buf: pointer, count: uint64): int64 {.exportc, cdecl.} =
|
|
let idx = int(fd - 3)
|
|
if idx < 0 or idx >= MAX_FDS or not fd_table[idx].active: return -1
|
|
let fh = addr fd_table[idx]
|
|
|
|
case fh.mode:
|
|
of MODE_TTY: return -2
|
|
of MODE_TAR, MODE_RAM:
|
|
let path = cast[cstring](addr fh.path[0])
|
|
let n = tar.vfs_write_at(path, buf, count, fh.offset)
|
|
if n > 0: fh.offset += uint64(n)
|
|
return n
|
|
of MODE_SFS:
|
|
let path = cast[cstring](addr fh.path[0])
|
|
sfs.sfs_write_file(path, buf, int(count))
|
|
return int64(count)
|
|
|
|
proc ion_vfs_close*(fd: int32): int32 {.exportc, cdecl.} =
|
|
let idx = int(fd - 3)
|
|
if idx >= 0 and idx < MAX_FDS:
|
|
fd_table[idx].active = false
|
|
return 0
|
|
return -1
|
|
|
|
proc ion_vfs_list*(buf: pointer, max_len: uint64): int64 {.exportc, cdecl.} =
|
|
# Hardcoded baseline for now to avoid string/os dependency
|
|
let msg = "/nexus\n/sysro\n/state\n"
|
|
let n = if uint64(msg.len) < max_len: uint64(msg.len) else: max_len
|
|
if n > 0: copyMem(buf, unsafeAddr msg[0], int(n))
|
|
return int64(n)
|