107 lines
3.0 KiB
Nim
107 lines
3.0 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: ROMFS (Static Tar Loader)
|
|
##
|
|
## Freestanding implementation (No OS module dependencies).
|
|
## Uses a simple flat array for the file index.
|
|
|
|
{.push stackTrace: off, lineTrace: off.}
|
|
|
|
type
|
|
TarHeader* = array[512, byte]
|
|
|
|
FileEntry = object
|
|
name: array[64, char]
|
|
offset: uint64
|
|
size: uint64
|
|
active: bool
|
|
|
|
const MAX_INDEX = 64
|
|
var index_table: array[MAX_INDEX, FileEntry]
|
|
var index_count: int = 0
|
|
|
|
proc vfs_init*(s: pointer, e: pointer) =
|
|
let start_addr = cast[uint64](s)
|
|
let end_addr = cast[uint64](e)
|
|
index_count = 0
|
|
|
|
var p = start_addr
|
|
while p < end_addr:
|
|
let h = cast[ptr TarHeader](p)
|
|
if h[][0] == byte(0): break
|
|
|
|
# Extract name
|
|
var name_len = 0
|
|
while name_len < 100 and h[][name_len] != 0: inc name_len
|
|
|
|
var start_idx = 0
|
|
if name_len >= 2 and h[][0] == byte('.') and h[][1] == byte('/'): start_idx = 2
|
|
elif name_len >= 1 and h[][0] == byte('/'): start_idx = 1
|
|
|
|
let clean_len = name_len - start_idx
|
|
if clean_len > 0 and index_count < MAX_INDEX:
|
|
var entry = addr index_table[index_count]
|
|
entry.active = true
|
|
let to_copy = if clean_len < 63: clean_len else: 63
|
|
for i in 0..<to_copy:
|
|
entry.name[i] = char(h[][start_idx + i])
|
|
entry.name[to_copy] = '\0'
|
|
|
|
# Extract size (octal string at offset 124)
|
|
var size: uint64 = 0
|
|
for i in 124..134:
|
|
let b = h[][i]
|
|
if b >= byte('0') and b <= byte('7'):
|
|
size = (size shl 3) or uint64(b - byte('0'))
|
|
entry.size = size
|
|
entry.offset = p + 512
|
|
index_count += 1
|
|
|
|
# Move to next header
|
|
let padded_size = (size + 511) and not 511'u64
|
|
p += 512 + padded_size
|
|
else:
|
|
p += 512
|
|
|
|
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_open*(path: cstring, flags: int32 = 0): int32 =
|
|
var p = path
|
|
if path != nil and path[0] == '/':
|
|
p = cast[cstring](cast[uint64](path) + 1)
|
|
|
|
for i in 0..<index_count:
|
|
if vfs_streq(p, cast[cstring](addr index_table[i].name[0])):
|
|
return int32(i)
|
|
return -1
|
|
|
|
proc vfs_read_at*(path: cstring, buf: pointer, count: uint64, offset: uint64): int64 =
|
|
let fd = vfs_open(path)
|
|
if fd < 0: return -1
|
|
let entry = addr index_table[fd]
|
|
|
|
if offset >= entry.size: return 0
|
|
let avail = entry.size - offset
|
|
let actual = if count < avail: count else: avail
|
|
if actual > 0:
|
|
copyMem(buf, cast[pointer](entry.offset + offset), int(actual))
|
|
return int64(actual)
|
|
|
|
proc vfs_write_at*(path: cstring, buf: pointer, count: uint64, offset: uint64): int64 =
|
|
# ROMFS is read-only
|
|
return -1
|
|
|
|
proc vfs_get_names*(): int = index_count # Dummy for listing
|