Skip to Content
Viewing feat/v0.5-runtime docs — not the stable branch. Changes vs main · Go to main

Core Libraries

Relevant source files

minilib

minilib is the userspace runtime: a no_std crate that wraps the kernel syscall ABI. It depends only on kernel_abi (the shared ABI crate that defines syscall numbers, Errno, BpfAttr, and BPF constants).

Syscall instruction

ArchInstructionNumberArgs
x86_64int 0x80raxvia inline assembly (syscall0 to syscall4 helpers)
AArch64svc #0x8x0 to x5

syscall0 through syscall4 are the raw helpers. syscall_debug and debug_syscall(op, value) reach SYS_DEBUG; the init probes use private audit-diagnostics operations that production kernels reject with EINVAL.

Wrapper functions

AreaFunctions
Processexit, abort, fork, execve, waitpid (with WNOHANG), spawn, spawn_restricted, restrict_bpf_capabilities
I/Oread, write, writev (with iovec), open (flags O_RDONLY, O_WRONLY, O_RDWR, O_CREAT), close, lseek (SEEK_SET/CUR/END), fstat (with stat), getcwd, dup, dup2, pipe
Timeclock_gettime, nanosleep, sleep, msleep, pause, interrupt_sleep
Memorymalloc, free (syscalls SYS_MALLOC and SYS_FREE, not a userspace allocator)
BPFbpf(cmd, attr, size), which is SYS_BPF
Safetyestop_trigger (SYS_ESTOP)
Managed runtimemanaged_bpf_bytes, managed_slot_query, managed_slot_artifact, managed_upload_begin, managed_upload_chunk, managed_upload_finalize, managed_operation_query, managed_operation_cancel, managed_rearm, managed_activate, managed_rollback, managed_deactivate, managed_retire, managed_installation_cancel, managed_recorder_status, managed_recorder_timing_status, managed_recorder_read

Managed ABI wrappers

The managed wrappers all go through SYS_BPF with kernel_abi plain-data request types (ManagedSlotV1, ManagedAuditStatusV1, ManagedAuditStatusV2 and so on). They use a separate internal helper because managed operation IDs need the full syscall word, while the legacy bpf wrapper keeps its c_int signature. Each returns Result<_, Errno>. managed_bpf_bytes is the raw byte-buffer form used by the installer dispatcher. A successful managed_rearm returns an operation ID to query or cancel; it does not activate or resume the retained controller. The wire contract is in Installer and Lifecycle.

Syscall numbers

The shipped ABI is catalogued in docs/reference/generated/abi.md, generated by cargo xtask docs.

RangeSyscalls
1 to 44EXIT, OPEN, FSTAT, MALLOC, FREE, ABORT, GETCWD, READ, WRITE, WRITEV, LSEEK, CLOSE, MMAP, DUP, DUP2, PIPE
50SYS_BPF
51 to 53SYS_PWM_CONFIG, SYS_PWM_WRITE, SYS_PWM_ENABLE (Raspberry Pi 5 only)
54 to 64CLOCK_GETTIME, NANOSLEEP, SPAWN, FORK, EXECVE, WAITPID, DEBUG, ESTOP, SPAWN_RESTRICTED, RESTRICT_BPF_CAPABILITIES, INTERRUPT_SLEEP

BPF commands used from userspace include BPF_MAP_CREATE (0), MAP_LOOKUP_ELEM, MAP_UPDATE_ELEM, MAP_DELETE_ELEM, BPF_PROG_LOAD (5), BPF_OBJ_PIN (6), BPF_OBJ_GET (7), BPF_PROG_ATTACH (8), BPF_PROG_DETACH, BPF_PROG_LOAD_ELF (36), BPF_RINGBUF_POLL (37), plus PROG_UNLOAD, MAP_DESTROY, OBJ_UNPIN. Attach types: timer, GPIO and IIO (Pi 5 only for GPIO and IIO), sys_enter, sys_exit, sched_switch.

minilib does not implement main, argument parsing or formatted printing. Each program defines _start, a panic handler, and (as needed) its own print and print_num helpers.

Program skeleton

#![no_std] #![no_main] use minilib::{exit, write}; #[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { write(1, b"hello\n"); exit(0); } #[panic_handler] fn panic(_: &core::panic::PanicInfo) -> ! { exit(1) }

init

init (userspace/core/init) is PID-1-equivalent and is also the main in-guest integration test. Its feature bpf-unsigned-development mirrors the kernel and root feature of the same name; on x86_64 it also depends on the x86_64 crate.

Probes

Each probe writes an ..._OK or ..._FAIL line to fd 1. The audit gate greps these markers (see Tests and CI).

Marker prefixWhat is exercised
USERCOPY_EFAULTA bad user pointer returns EFAULT
UNKNOWN_SYSCALL_ENOSYSAn unknown syscall number returns ENOSYS
NANOSLEEP_WAITQ, NANOSLEEP_INTERRUPTWait-queue sleep and interrupted sleep
PIPE_WAIT_READER_DATA, PIPE_WAIT_READER_EOF, PIPE_WAITQBlocking pipe readers woken by data and EOF
CHILD_WAIT_BEFORE_EXIT, CHILD_EXIT_BEFORE_WAIT, LIFECYCLE_*waitpid ordering, faulting child, execve rejection (/bin/does-not-exist) and successful execve of /bin/fork_test
BPF_FOREIGN_OWNER_DENYA process cannot act on another owner’s BPF object
BPF_PINNED_WRITE_ONLY, BPF_HOOK_SNAPSHOT_SMP, SMP4_SCHEDULER, BPF_HANDLE_REUSE, BPF_OWNER_EXIT, BPF_CAPABILITY_PROBE_STARTEDOnly with bpf-unsigned-development

The *_BLOCKED_OK markers rely on audit-diagnostic counters read through SYS_DEBUG.

Capabilities

spawn_restricted(path, caps) launches a child with a capability bitmask from kernel_abi (BPF_CAP_PROGRAM_LOAD, BPF_CAP_MAP_CREATE, BPF_CAP_MAP_READ, BPF_CAP_MAP_WRITE, BPF_CAP_ATTACH_SCHEDULER, BPF_CAP_OBJECT_PIN). The signed loader gets only load and map-read; the development export demo gets create, read, write, attach-scheduler and pin; the bridge demo gets map-read and pin.

Managed bootstrap

With the managed-runtime feature (a new init feature), init skips every diagnostic probe above and runs only the installer. It calls spawn_restricted("/bin/signed_bpf_loader", BPF_CAP_BEHAVIOR_ADMIN), then restrict_bpf_capabilities(0) to drop its own capabilities. If the spawn or the drop fails it calls estop_trigger and exits 1. Otherwise it sleeps in a one-second loop. There is no automatic respawn and no stop when the loader exits, so accepted operations and installations keep their kernel-owned lifetime. The source comment states that the administration authority grants no direct actuation. See Installer.

file_structure

userspace/core/file_structure is a no_std crate that models the rootfs. It exposes STRUCTURE, Dir, File, Kind and ValidationError, and is also a build dependency of the root package so build.rs can walk it. It has host unit tests (host lint and tests gate). See Userspace Overview for the tree.

Last updated on