173 lines
5.8 KiB
Nim
173 lines
5.8 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: Application Loader (The Breath of Life)
|
|
|
|
# MARKUS MAIWALD (ARCHITECT) | VOXIS FORGE (AI)
|
|
# Rumpk Phase 8: The Summoning (ELF Loader)
|
|
|
|
import fs/tar, loader/elf
|
|
|
|
proc kprint(s: cstring) {.importc, cdecl.}
|
|
proc kprintln(s: cstring) {.importc, cdecl.}
|
|
proc kprint_hex(v: uint64) {.importc, cdecl.}
|
|
|
|
# Assembly trampoline to jump to userland
|
|
proc rumpk_enter_userland*(entry, argc, argv, sp: uint64) {.importc, cdecl.}
|
|
|
|
proc kload*(path: string): uint64 =
|
|
# 1. Read ELF File from VFS
|
|
let file_content = vfs_read_file(path)
|
|
if file_content.len == 0:
|
|
kprint("[Loader] Error: File not found or empty: '")
|
|
kprint(cstring(path))
|
|
kprintln("'")
|
|
return 0
|
|
|
|
# 2. Verify ELF Header
|
|
let ehdr = cast[ptr Elf64_Ehdr](unsafeAddr file_content[0])
|
|
|
|
if ehdr.e_ident[0] != 0x7F or ehdr.e_ident[1] != 'E'.uint8 or
|
|
ehdr.e_ident[2] != 'L'.uint8 or ehdr.e_ident[3] != 'F'.uint8:
|
|
kprintln("[Loader] Error: Invalid ELF magic.")
|
|
return 0
|
|
|
|
if ehdr.e_machine != 243: # EM_RISCV
|
|
kprintln("[Loader] Error: Binary is not for RISC-V.")
|
|
return 0
|
|
|
|
# 3. Parse Program Headers
|
|
let base_ptr = cast[uint64](unsafeAddr file_content[0])
|
|
|
|
for i in 0 ..< int(ehdr.e_phnum):
|
|
let phdr_offset = ehdr.e_phoff + uint64(i * int(ehdr.e_phentsize))
|
|
let phdr = cast[ptr Elf64_Phdr](base_ptr + phdr_offset)
|
|
|
|
if phdr.p_type == PT_LOAD:
|
|
let dest = cast[ptr UncheckedArray[byte]](phdr.p_vaddr)
|
|
let src = cast[ptr UncheckedArray[byte]](base_ptr + phdr.p_offset)
|
|
|
|
# Clear BSS (memsz > filesz)
|
|
if phdr.p_memsz > 0:
|
|
zeroMem(dest, phdr.p_memsz)
|
|
|
|
# Copy Data
|
|
if phdr.p_filesz > 0:
|
|
copyMem(dest, src, phdr.p_filesz)
|
|
let magic = cast[ptr uint32](dest)[]
|
|
kprint("[Loader] Verified Segment at ")
|
|
kprint_hex(cast[uint64](dest))
|
|
kprint(" Magic: ")
|
|
kprint_hex(uint64(magic))
|
|
kprintln("")
|
|
|
|
return ehdr.e_entry
|
|
|
|
# --- M4.4: BKDL Manifest Extraction ---
|
|
|
|
proc streq_n(a: ptr UncheckedArray[byte], b: cstring, maxlen: int): bool =
|
|
## Compare byte array against C string, bounded by maxlen
|
|
var i = 0
|
|
while i < maxlen:
|
|
if b[i] == '\0':
|
|
return true # b ended, all matched
|
|
if a[i] != byte(b[i]):
|
|
return false
|
|
i += 1
|
|
return false
|
|
|
|
proc kload_manifest*(file_content: openArray[byte]): ManifestResult =
|
|
## Scan ELF section headers for .nexus.manifest containing BKDL data.
|
|
## Returns header=nil if no manifest found.
|
|
result.header = nil
|
|
result.caps = nil
|
|
result.count = 0
|
|
|
|
if file_content.len < int(sizeof(Elf64_Ehdr)):
|
|
return
|
|
|
|
let ehdr = cast[ptr Elf64_Ehdr](unsafeAddr file_content[0])
|
|
let base = cast[uint64](unsafeAddr file_content[0])
|
|
let file_len = uint64(file_content.len)
|
|
|
|
# Validate section header table is within file
|
|
if ehdr.e_shoff == 0 or ehdr.e_shnum == 0:
|
|
return
|
|
if ehdr.e_shoff + uint64(ehdr.e_shnum) * uint64(ehdr.e_shentsize) > file_len:
|
|
return
|
|
|
|
# Get string table section (shstrtab)
|
|
if ehdr.e_shstrndx >= ehdr.e_shnum:
|
|
return
|
|
let strtab_shdr = cast[ptr Elf64_Shdr](base + ehdr.e_shoff + uint64(ehdr.e_shstrndx) * uint64(ehdr.e_shentsize))
|
|
if strtab_shdr.sh_offset + strtab_shdr.sh_size > file_len:
|
|
return
|
|
let strtab = cast[ptr UncheckedArray[byte]](base + strtab_shdr.sh_offset)
|
|
|
|
# Scan sections for .nexus.manifest
|
|
let target = cstring(".nexus.manifest")
|
|
for i in 0 ..< int(ehdr.e_shnum):
|
|
let shdr = cast[ptr Elf64_Shdr](base + ehdr.e_shoff + uint64(i) * uint64(ehdr.e_shentsize))
|
|
if shdr.sh_name < uint32(strtab_shdr.sh_size):
|
|
let name_ptr = cast[ptr UncheckedArray[byte]](cast[uint64](strtab) + uint64(shdr.sh_name))
|
|
let remaining = int(strtab_shdr.sh_size) - int(shdr.sh_name)
|
|
if streq_n(name_ptr, target, remaining):
|
|
# Found .nexus.manifest section
|
|
if shdr.sh_offset + shdr.sh_size > file_len:
|
|
return # Section data out of bounds
|
|
if shdr.sh_size < uint64(sizeof(BkdlHeader)):
|
|
return # Too small
|
|
|
|
let hdr = cast[ptr BkdlHeader](base + shdr.sh_offset)
|
|
if hdr.magic != BKDL_MAGIC or hdr.version != BKDL_VERSION:
|
|
kprintln("[Manifest] Invalid BKDL magic/version")
|
|
return
|
|
|
|
let expected_size = uint64(sizeof(BkdlHeader)) + uint64(hdr.cap_count) * uint64(sizeof(CapDescriptor))
|
|
if expected_size > shdr.sh_size:
|
|
kprintln("[Manifest] BKDL cap_count exceeds section size")
|
|
return
|
|
|
|
result.header = hdr
|
|
result.caps = cast[ptr UncheckedArray[CapDescriptor]](base + shdr.sh_offset + uint64(sizeof(BkdlHeader)))
|
|
result.count = int(hdr.cap_count)
|
|
return
|
|
|
|
proc kexec*(path: string) =
|
|
let entry = kload(path)
|
|
if entry != 0:
|
|
kprintln("[Loader] Transferring Consciousness...")
|
|
rumpk_enter_userland(entry, 0, 0, 0)
|
|
|
|
proc kload_phys*(path: string, phys_offset: uint64): uint64 =
|
|
let file_content = vfs_read_file(path)
|
|
if file_content.len == 0:
|
|
return 0
|
|
|
|
let ehdr = cast[ptr Elf64_Ehdr](unsafeAddr file_content[0])
|
|
if ehdr.e_ident[0] != 0x7F: return 0
|
|
if ehdr.e_machine != 243: return 0
|
|
|
|
let base_ptr = cast[uint64](unsafeAddr file_content[0])
|
|
|
|
for i in 0 ..< int(ehdr.e_phnum):
|
|
let phdr_offset = ehdr.e_phoff + uint64(i * int(ehdr.e_phentsize))
|
|
let phdr = cast[ptr Elf64_Phdr](base_ptr + phdr_offset)
|
|
|
|
if phdr.p_type == PT_LOAD:
|
|
let rel_addr = phdr.p_vaddr - 0x84000000'u64
|
|
let dest_addr = phys_offset + rel_addr
|
|
let dest = cast[ptr UncheckedArray[byte]](dest_addr)
|
|
let src = cast[ptr UncheckedArray[byte]](base_ptr + phdr.p_offset)
|
|
|
|
if phdr.p_memsz > 0:
|
|
zeroMem(dest, phdr.p_memsz)
|
|
if phdr.p_filesz > 0:
|
|
copyMem(dest, src, phdr.p_filesz)
|
|
|
|
return ehdr.e_entry
|