# 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 File System (SFS) ## ## Freestanding implementation (No OS module dependencies). ## Uses fixed-size buffers and raw blocks for persistence. import ring, fiber # For yield proc kprintln(s: cstring) {.importc, cdecl.} proc kprint(s: cstring) {.importc, cdecl.} proc kprint_hex(n: uint64) {.importc, cdecl.} const SFS_MAGIC* = 0x31534653'u32 const SEC_SB = 0 SEC_BAM = 1 SEC_DIR = 2 CHUNK_SIZE = 508 EOF_MARKER = 0xFFFFFFFF'u32 var sfs_mounted: bool = false var io_buffer: array[512, byte] proc virtio_blk_read(sector: uint64, buf: pointer) {.importc, cdecl.} proc virtio_blk_write(sector: uint64, buf: pointer) {.importc, cdecl.} proc sfs_alloc_sector(): uint32 = virtio_blk_read(SEC_BAM, addr io_buffer[0]) for i in 0..<512: if io_buffer[i] != 0xFF: for b in 0..7: if (io_buffer[i] and byte(1 shl b)) == 0: let sec = uint32(i * 8 + b) io_buffer[i] = io_buffer[i] or byte(1 shl b) virtio_blk_write(SEC_BAM, addr io_buffer[0]) return sec return 0 proc sfs_mount*() = virtio_blk_read(SEC_SB, addr io_buffer[0]) if io_buffer[0] == byte('S') and io_buffer[1] == byte('F') and io_buffer[2] == byte('S') and io_buffer[3] == byte('2'): sfs_mounted = true else: sfs_mounted = false proc sfs_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 sfs_write_file*(name: cstring, data: pointer, data_len: int) {.exportc, cdecl.} = if not sfs_mounted: return virtio_blk_read(SEC_DIR, addr io_buffer[0]) var dir_offset = -1 for offset in countup(0, 511, 64): if io_buffer[offset] != 0: if sfs_streq(name, cast[cstring](addr io_buffer[offset])): dir_offset = offset break elif dir_offset == -1: dir_offset = offset if dir_offset == -1: return var remaining = data_len var data_addr = cast[uint64](data) var current_sector = sfs_alloc_sector() if current_sector == 0: return let first_sector = current_sector while remaining > 0: var sector_buf: array[512, byte] let chunk = if remaining > CHUNK_SIZE: CHUNK_SIZE else: remaining copyMem(addr sector_buf[0], cast[pointer](data_addr), chunk) remaining -= chunk data_addr += uint64(chunk) var next_sector = EOF_MARKER if remaining > 0: next_sector = sfs_alloc_sector() if next_sector == 0: next_sector = EOF_MARKER # Write next pointer at end of block cast[ptr uint32](addr sector_buf[508])[] = next_sector virtio_blk_write(uint64(current_sector), addr sector_buf[0]) current_sector = next_sector if current_sector == EOF_MARKER: break # Update Directory virtio_blk_read(SEC_DIR, addr io_buffer[0]) let nm = cast[ptr UncheckedArray[char]](name) var i = 0 while nm[i] != '\0' and i < 31: io_buffer[dir_offset + i] = byte(nm[i]) i += 1 io_buffer[dir_offset + i] = 0 cast[ptr uint32](addr io_buffer[dir_offset + 32])[] = first_sector cast[ptr uint32](addr io_buffer[dir_offset + 36])[] = uint32(data_len) virtio_blk_write(SEC_DIR, addr io_buffer[0]) proc sfs_read_file*(name: cstring, dest: pointer, max_len: int): int {.exportc, cdecl.} = if not sfs_mounted: return -1 virtio_blk_read(SEC_DIR, addr io_buffer[0]) var start_sector = 0'u32 var file_size = 0'u32 var found = false for offset in countup(0, 511, 64): if io_buffer[offset] != 0: if sfs_streq(name, cast[cstring](addr io_buffer[offset])): start_sector = cast[ptr uint32](addr io_buffer[offset + 32])[] file_size = cast[ptr uint32](addr io_buffer[offset + 36])[] found = true break if not found: return -1 var current_sector = start_sector var dest_addr = cast[uint64](dest) var remaining = if int(file_size) < max_len: int(file_size) else: max_len var total = 0 while remaining > 0 and current_sector != EOF_MARKER: var sector_buf: array[512, byte] virtio_blk_read(uint64(current_sector), addr sector_buf[0]) let chunk = if remaining < CHUNK_SIZE: remaining else: CHUNK_SIZE copyMem(cast[pointer](dest_addr), addr sector_buf[0], chunk) dest_addr += uint64(chunk) remaining -= chunk total += chunk current_sector = cast[ptr uint32](addr sector_buf[508])[] return total proc sfs_get_files*(): cstring = return "boot.kdl\n" # Dummy