# 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: LittleFS Bridge ## ## Nim FFI wrapper for the Zig-side LittleFS HAL (littlefs_hal.zig). ## Provides the API that VFS delegates to for /nexus mount point. ## ## All calls cross the Nim→Zig→C boundary: ## Nim (this file) → Zig (littlefs_hal.zig) → C (lfs.c) → VirtIO-Block # --- FFI imports from littlefs_hal.zig (exported as C ABI) --- proc nexus_lfs_format(): int32 {.importc, cdecl.} proc nexus_lfs_mount(): int32 {.importc, cdecl.} proc nexus_lfs_unmount(): int32 {.importc, cdecl.} proc nexus_lfs_open(path: cstring, flags: int32): int32 {.importc, cdecl.} proc nexus_lfs_read(handle: int32, buf: pointer, size: uint32): int32 {.importc, cdecl.} proc nexus_lfs_write(handle: int32, buf: pointer, size: uint32): int32 {.importc, cdecl.} proc nexus_lfs_close(handle: int32): int32 {.importc, cdecl.} proc nexus_lfs_seek(handle: int32, off: int32, whence: int32): int32 {.importc, cdecl.} proc nexus_lfs_size(handle: int32): int32 {.importc, cdecl.} proc nexus_lfs_remove(path: cstring): int32 {.importc, cdecl.} proc nexus_lfs_mkdir(path: cstring): int32 {.importc, cdecl.} proc nexus_lfs_is_mounted(): int32 {.importc, cdecl.} # --- LFS open flags (match lfs.h) --- const LFS_O_RDONLY* = 1'i32 LFS_O_WRONLY* = 2'i32 LFS_O_RDWR* = 3'i32 LFS_O_CREAT* = 0x0100'i32 LFS_O_EXCL* = 0x0200'i32 LFS_O_TRUNC* = 0x0400'i32 LFS_O_APPEND* = 0x0800'i32 # --- LFS seek flags --- const LFS_SEEK_SET* = 0'i32 LFS_SEEK_CUR* = 1'i32 LFS_SEEK_END* = 2'i32 # --- Public API for VFS --- proc lfs_mount_fs*(): bool = ## Mount the LittleFS filesystem. Auto-formats on first boot. return nexus_lfs_mount() == 0 proc lfs_unmount_fs*(): bool = return nexus_lfs_unmount() == 0 proc lfs_format_fs*(): bool = return nexus_lfs_format() == 0 proc lfs_is_mounted*(): bool = return nexus_lfs_is_mounted() != 0 proc lfs_open_file*(path: cstring, flags: int32): int32 = ## Open a file. Returns handle >= 0 on success, < 0 on error. return nexus_lfs_open(path, flags) proc lfs_read_file*(handle: int32, buf: pointer, size: uint32): int32 = ## Read from file. Returns bytes read or negative error. return nexus_lfs_read(handle, buf, size) proc lfs_write_file*(handle: int32, buf: pointer, size: uint32): int32 = ## Write to file. Returns bytes written or negative error. return nexus_lfs_write(handle, buf, size) proc lfs_close_file*(handle: int32): int32 = return nexus_lfs_close(handle) proc lfs_seek_file*(handle: int32, off: int32, whence: int32): int32 = return nexus_lfs_seek(handle, off, whence) proc lfs_file_size*(handle: int32): int32 = return nexus_lfs_size(handle) proc lfs_remove_path*(path: cstring): int32 = return nexus_lfs_remove(path) proc lfs_mkdir_path*(path: cstring): int32 = return nexus_lfs_mkdir(path) # --- Convenience: VFS-compatible read/write (path-based, like SFS) --- proc lfs_vfs_read*(path: cstring, buf: pointer, max_len: int): int = ## Read entire file into buffer. Returns bytes read or -1. let h = nexus_lfs_open(path, LFS_O_RDONLY) if h < 0: return -1 let n = nexus_lfs_read(h, buf, uint32(max_len)) discard nexus_lfs_close(h) if n < 0: return -1 return int(n) proc lfs_vfs_write*(path: cstring, buf: pointer, len: int) = ## Write buffer to file (create/truncate). let h = nexus_lfs_open(path, LFS_O_WRONLY or LFS_O_CREAT or LFS_O_TRUNC) if h < 0: return discard nexus_lfs_write(h, buf, uint32(len)) discard nexus_lfs_close(h) proc lfs_vfs_read_at*(path: cstring, buf: pointer, count: uint64, offset: uint64): int64 = ## Read `count` bytes starting at `offset`. Returns bytes read. let h = nexus_lfs_open(path, LFS_O_RDONLY) if h < 0: return -1 if offset > 0: discard nexus_lfs_seek(h, int32(offset), LFS_SEEK_SET) let n = nexus_lfs_read(h, buf, uint32(count)) discard nexus_lfs_close(h) if n < 0: return -1 return int64(n) proc lfs_vfs_write_at*(path: cstring, buf: pointer, count: uint64, offset: uint64): int64 = ## Write `count` bytes at `offset`. Returns bytes written. let flags = LFS_O_WRONLY or LFS_O_CREAT let h = nexus_lfs_open(path, flags) if h < 0: return -1 if offset > 0: discard nexus_lfs_seek(h, int32(offset), LFS_SEEK_SET) let n = nexus_lfs_write(h, buf, uint32(count)) discard nexus_lfs_close(h) if n < 0: return -1 return int64(n)