Core Libraries
Relevant source files
- userspace/core/minilib/src/lib.rs
- userspace/core/init/src/main.rs
- userspace/core/file_structure/src/lib.rs
- docs/reference/generated/abi.md
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
| Arch | Instruction | Number | Args |
|---|---|---|---|
| x86_64 | int 0x80 | rax | via inline assembly (syscall0 to syscall4 helpers) |
| AArch64 | svc #0 | x8 | x0 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
| Area | Functions |
|---|---|
| Process | exit, abort, fork, execve, waitpid (with WNOHANG), spawn, spawn_restricted, restrict_bpf_capabilities |
| I/O | read, 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 |
| Time | clock_gettime, nanosleep, sleep, msleep, pause, interrupt_sleep |
| Memory | malloc, free (syscalls SYS_MALLOC and SYS_FREE, not a userspace allocator) |
| BPF | bpf(cmd, attr, size), which is SYS_BPF |
| Safety | estop_trigger (SYS_ESTOP) |
Syscall numbers
The shipped ABI is catalogued in docs/reference/generated/abi.md, generated by cargo xtask docs.
| Range | Syscalls |
|---|---|
| 1 to 44 | EXIT, OPEN, FSTAT, MALLOC, FREE, ABORT, GETCWD, READ, WRITE, WRITEV, LSEEK, CLOSE, MMAP, DUP, DUP2, PIPE |
| 50 | SYS_BPF |
| 51 to 53 | SYS_PWM_CONFIG, SYS_PWM_WRITE, SYS_PWM_ENABLE (Raspberry Pi 5 only) |
| 54 to 64 | CLOCK_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 prefix | What is exercised |
|---|---|
USERCOPY_EFAULT | A bad user pointer returns EFAULT |
UNKNOWN_SYSCALL_ENOSYS | An unknown syscall number returns ENOSYS |
NANOSLEEP_WAITQ, NANOSLEEP_INTERRUPT | Wait-queue sleep and interrupted sleep |
PIPE_WAIT_READER_DATA, PIPE_WAIT_READER_EOF, PIPE_WAITQ | Blocking 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_DENY | A 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_STARTED | Only 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.
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.