# 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, lfs_bridge type VFSMode = enum MODE_TAR, MODE_SFS, MODE_RAM, MODE_TTY, MODE_LFS MountPoint = object prefix: array[32, char] mode: VFSMode FileHandle = object path: array[64, char] offset: uint64 mode: VFSMode active: bool lfs_handle: int32 ## LFS file handle (-1 = not open) 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 kprintln(s: cstring) {.importc, cdecl.} proc vfs_mount_init*() = # Mount LittleFS for /nexus (persistent sovereign storage) if lfs_bridge.lfs_mount_fs(): vfs_add_mount("/nexus", MODE_LFS) else: # Fallback to SFS if LittleFS mount fails (no block device?) kprintln("[VFS] LFS mount failed, falling back to SFS for /nexus") 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..= 0: internal_fd = 0 of MODE_TTY: internal_fd = 1 # Shim if internal_fd >= 0: for i in 0..= 0: discard lfs_bridge.lfs_close_file(lfs_h) 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 of MODE_LFS: if fh.lfs_handle < 0: return -1 let n = lfs_bridge.lfs_read_file(fh.lfs_handle, buf, uint32(count)) if n > 0: fh.offset += uint64(n) return int64(n) 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) of MODE_LFS: if fh.lfs_handle < 0: return -1 let n = lfs_bridge.lfs_write_file(fh.lfs_handle, buf, uint32(count)) if n > 0: fh.offset += uint64(n) return int64(n) proc ion_vfs_close*(fd: int32): int32 {.exportc, cdecl.} = let idx = int(fd - 3) if idx >= 0 and idx < MAX_FDS: if fd_table[idx].mode == MODE_LFS and fd_table[idx].lfs_handle >= 0: discard lfs_bridge.lfs_close_file(fd_table[idx].lfs_handle) fd_table[idx].lfs_handle = -1 fd_table[idx].active = false return 0 return -1 proc ion_vfs_dup*(fd: int32, min_fd: int32 = 0): int32 {.exportc, cdecl.} = let idx = int(fd - 3) if idx < 0 or idx >= MAX_FDS or not fd_table[idx].active: return -1 # F_DUPFD needs to find first fd >= min_fd let start_idx = if min_fd > 3: int(min_fd - 3) else: 0 for i in start_idx..= MAX_FDS or not fd_table[old_idx].active: return -1 if new_idx < 0 or new_idx >= MAX_FDS: return -1 if old_idx == new_idx: return new_fd fd_table[new_idx] = fd_table[old_idx] fd_table[new_idx].active = true return new_fd 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)