Skip to content

Trap ABI Reference

Implemented

The contract is the protocol

This page documents the Trap ABI — the unavoidable CPU-facing entry layer (ecall / svc #0 / syscall). It is an implementation detail of how a fiber enters the kernel, not the application contract.

The stable contract that applications depend on is the Kernel Protocol: typed ION Ring packets, signed BKDL descriptors, and capability verbs. Read that page first.

Scope of this page

The Trap ABI is what libnexus, language runtimes, and the Membrane POSIX bridge use to perform the four mechanical operations the protocol needs:

  • submit a packet to a TX ring
  • await a reply from an RX ring (yielding if empty)
  • invoke a capability verb against a cap bundle
  • yield the remaining quantum

The table below documents the current implementation surface of those entry points. Several operations carry POSIX-style names (SYS_OPEN, SYS_READ, integer file descriptors) because the current implementation exposes a transitional shim. The long-term path is the Native Interface: typed channels, capability handles, structured objects, no int fd. Applications that target the long-term contract should link against libnexus rather than reach for the raw trap numbers below.

Entry convention

Rumpk traps are invoked via ecall (RISC-V) or svc #0 (ARM64). The syscall number is in a7/x8, arguments in a0-a2/x0-x2, return value in a0/x0.

VFS Operations

NrNameArgsReturnsDescription
0x200SYS_OPENpath, flagsfd or -1Open file in VFS (/sysro, /nexus, /state)
0x201SYS_CLOSEfd0 or -1Close file descriptor
0x202SYS_LISTbuf, maxlencountList directory entries
0x203SYS_READfd, buf, lenbytes readRead from fd (stdin blocks until input)
0x204SYS_WRITEfd, buf, lenbytes writtenWrite to fd (stdout/stderr to PTY or console)
0x205SYS_IOCTLfd, request0I/O control (stub)
0x206SYS_FCNTLfd, cmd, argvariesFile control (F_DUPFD supported)

Process Control

NrNameArgsReturnsDescription
0x01SYS_EXITstatusTerminate current fiber
0x65SYS_NANOSLEEPns0Sleep for ns nanoseconds
0x66SYS_GET_TIMEnsGet current time in nanoseconds
0x100SYS_SPAWNpath, argfiber_idSpawn new fiber from ELF
0x101SYS_PLEDGEmask0 or -1Narrow pledge mask (can only restrict, never widen)
0x102SYS_JOINfiber_id0Wait for fiber to exit
0x500SYS_CHECKPOINTblob_ptr, blob_len0 or -1Save fiber checkpoint (Phase 6.4)

Three time surfaces — pick the right one

SYS_GET_TIME / SYS_NANOSLEEP expose the boot clock (nanoseconds since kernel start) for scheduling and timeout use. They are not the application time contract.

Nexus exposes three time surfaces; the Trap ABI is the lowest:

SurfaceTypeUnitUse case
Trap ABI (this page)u64 boot_nsnanoseconds since bootKernel scheduling, timeouts, fiber quantum accounting
STP / Chronology (SPEC-106)StpTimestamp (i64)TAI nanoseconds since Nexus Epoch (JD 2460000.0)Application time, event timestamps, wire encoding (UTCP TLV 0x0106), package metadata, STL events
STP Duration (SPEC-106)StpDuration (i64)nanosecondsGeneral durations, intervals, latency
STP Precise Duration (SPEC-106 §2.3)StpDuration128 (i128)attosecondsScientific measurements, RF, space, physics — sub-nanosecond precision without overflow
NST SovereignTick (SPEC-105)128-bit {epoch_ns, entropy_hash}nanoseconds + tamper-evidence hashSpace missions, distributed consensus, causal ordering

Why nanoseconds, not attoseconds, as the canonical timestamp unit? A signed 64-bit nanosecond counter covers ±292 years — enough for any terrestrial or near-space mission. An attosecond counter overflows the same 64 bits in ~9.2 seconds, which is unusable as a global timestamp. Sub-nanosecond precision is reserved for durations (where the range requirement is bounded) via StpDuration128, not for timestamps.

The Chronology and NST surfaces are accessed via their respective userland services over Storage Channels, not via Trap ABI. This is consistent with the Kernel Protocol doctrine: the kernel exposes a minimal entry surface; rich semantics live in userland services that speak the protocol.

LWF Operations (Sovereign Networking)

NrNameArgsReturnsDescription
0x700SYS_LWF_RECVbuf, maxlenframe_len or 0Pop LWF frame from chan_lwf_rx (non-blocking)
0x701SYS_LWF_SENDbuf, lenlen or 0Push LWF frame to chan_lwf_tx
0x702SYS_UTCP_RECVbuf, maxlenframe_len or 0Pop UTCP frame from chan_utcp_rx
0x703SYS_UTCP_SENDbuf, lenlen or 0Push UTCP frame to chan_utcp_tx

Capability gating: LWF_RECV requires capability 0x600 (PERM_READ). LWF_SEND requires 0x601 (PERM_WRITE). Capabilities are granted via BKDL manifest embedded in the capsule ELF.

User buffer bounce: For fibers with per-fiber address spaces (Cell 1+), the kernel uses user_copy_in/user_copy_out to translate between per-fiber VA and kernel PA. The bounce temporarily activates the fiber's worker SATP with interrupts disabled, copies the data, then restores the kernel identity map.

Native path

For new applications, network I/O should be expressed as a Flow over a typed channel rather than the explicit LWF_SEND/LWF_RECV trap pair. The traps remain available for the POSIX bridge and low-level diagnostics.

AEAD Cryptography (M5.2 Membrane-Capsule Bridge)

NrNameArgsReturnsDescription
0x800SYS_AEAD_SEALargs_ptr, args_lensealed_len or 0XChaCha20-Poly1305 encrypt
0x801SYS_AEAD_UNSEALargs_ptr, args_lenplaintext_len or 0XChaCha20-Poly1305 decrypt

Backend: Monocypher crypto_aead_lock/crypto_aead_unlock (C reference implementation).

SYS_AEAD_SEAL (0x800)

Encrypts plaintext with XChaCha20-Poly1305. Output format: [24-byte nonce][ciphertext][16-byte Poly1305 tag].

Args struct (56 bytes at a0, a1 = struct size):

OffsetSizeFieldDescription
032key256-bit symmetric key
328plaintext_ptrPointer to plaintext in user memory
408plaintext_lenPlaintext length (max 2000 bytes)
488ad_ptrPointer to additional authenticated data
568ad_lenAD length (max 256 bytes)
648out_ptrPointer to output buffer in user memory
728out_lenOutput buffer max size

Returns: Sealed length (plaintext_len + 40) on success, 0 on error.

SYS_AEAD_UNSEAL (0x801)

Decrypts and authenticates XChaCha20-Poly1305 sealed payload. Rejects tampered data.

Args struct (same layout as SEAL, with sealed data instead of plaintext):

OffsetSizeFieldDescription
032key256-bit symmetric key
328sealed_ptrPointer to sealed data [nonce][ct][tag]
408sealed_lenSealed length (must be >= 40)
488ad_ptrPointer to AD (must match what was used for sealing)
568ad_lenAD length
648out_ptrPointer to plaintext output buffer
728out_lenOutput buffer max size

Returns: Plaintext length (sealed_len - 40) on success, 0 on authentication failure.

Pledge Enforcement

Every syscall is checked against the fiber's pledge mask before dispatch. Pledges can only be narrowed (SYS_PLEDGE with a mask that's a subset of the current mask). Attempting to widen returns -1.

Pledge BitNameSyscalls Gated
0x01PLEDGE_STDIOSYS_READ (fd=0), SYS_WRITE (fd=1,2)
0x02PLEDGE_RPATHSYS_OPEN (read), SYS_READ (fd>=3)
0x04PLEDGE_WPATHSYS_OPEN (write), SYS_WRITE (fd>=3)
0x08PLEDGE_INETSYS_LWF_, SYS_UTCP_, SYS_AEAD_*
0x10PLEDGE_EXECSYS_SPAWN