User Space Interface Progress
Status: In Progress (unmodified static Linux binaries verified from ring 3) Last review: 2026-08-28
Implemented
- User API syscall bridge in
user/lib/user_api.c. - Service-facing interface contracts in
include/vibeos/user_api.h. - Compatibility runtime scaffolding under
user/compat/*. - Baseline integration with process/security/syscall surfaces.
- Versioned user API contract and capability matrix exposure (
vibeos_user_api_contract,vibeos_user_api_capabilities). - Real ELF programs now run in ring 3 through the native syscall entry path. The runtime loads programs from the FAT boot volume and supports fork,
execve,waitpidand exit. - Programs start on a real System V startup stack, not a bare one:
vibeos_elf_build_stack(kernel/core/elf.c) lays outargc,argv,envpand the auxiliary vector, anduser/prog/crt0.Sis a genuine assembly_startthat converts that state into a C call.AT_PHDR,AT_PHNUM,AT_PHENT,AT_ENTRY,AT_PAGESZandAT_RANDOMare all populated, and the user linker script now maps the ELF headers inside the firstPT_LOADsoAT_PHDRpoints at a program header table that really exists in the address space. A ring-3 program verifies this on every boot (auxv okin the serial log). - Every user program now enters through a real assembly
_start(user/prog/crt0.S) and is written as an ordinaryvibeos_main(argc, argv, envp). This is not cosmetic: at entryrspis aligned like a call site rather than a function frame, and the arguments are on the stack rather than in registers, so a C function as the entry point either misreads them or faults on the first aligned SSE store. /BIN/SHsupplies the current interactive shell baseline with keyboard/serial input, line editing and file commands; framebuffer output is available in the runtime console path.- Unmodified static Linux binaries run end to end. A static musl program and a static BusyBox - neither built by this project - load, reach
main, and do real work. BusyBox dispatches onargv[0](which is not the path: the shell supplies the name, the path only opens the file), runsecho,catandls, and its shell parses scripts, searchesPATH, forks and execs. Gated:busybox_did_not_run,busybox_applet_dispatch_failed,busybox_file_operations_failed,interactive_shell_did_not_run,shell_script_did_not_run,unmodified_linux_binary_did_not_runandlinux_binary_got_wrong_argvall fail the boot. - Pipelines run in that shell.
pipe2,dup,dup2and descriptor inheritance acrossforkare enough forls /EFI/BOOT | wc -l; the boot self-test runs exactly that and the gate fails onpipeline_did_not_complete. Writing into a pipe with no reader raisesSIGPIPE, which is what stops a pipeline filling memory after its reader has gone. - A signal reaches a real handler. A program built against a real libc installs handlers, blocks and unblocks signals, ignores one and lets another take its default action; the return path goes through the libc's own trampoline and
rt_sigreturn. Gated onsignal_delivery_broken. Ctrl-Con the console raisesSIGINTagainst the newest live user task. The signal itself is delivered like any other; picking the recipient by newest pid is the stand-in for process groups, which do not exist yet. Not covered by a gate.- Native userland ABI v1 is now defined in
include/vibeos/userland.h, with fixed-width process start metadata, service manifests, runtime snapshots, and deterministic validation of versions, sizes, bounded strings, dependency masks and lifecycle enums. - A bounded native service supervisor is implemented in
user/servicemgr/supervisor.c: it loads validated manifests, starts dependency-ready services, records runtime snapshots, applies restart limits/backoff and isolates terminal service failures. Host regression coverage exercises dependency ordering, restart and failure state transitions. - The portable process model now exposes validated process-group and session membership. This is a host-verified contract only; x86_64 task wiring and controlling-terminal job control remain open.
- A freestanding native init candidate is built and staged separately from the legacy bring-up workload. Runtime selection and process-backed service startup remain pending.
- External commands launched by the native shell now receive a distinct process group; the shell transfers and restores foreground terminal ownership around
wait4. Job-control behavior remains unverified in QEMU.
Pending
- Process groups and a controlling terminal, so
Ctrl-Ctargets a job rather than the newest pid, and soioctl(TCGETS)can become something other thanENOTTY. - A test that exercises the
Ctrl-CtoSIGINTpath, which is currently demonstrated rather than gated. - Libraries with dependencies of their own. Dynamic executables load - the kernel places an
ET_DYNimage at a bias it chooses, maps thePT_INTERPinterpreter alongside it and enters the interpreter - but one program and one interpreter is what has been shown, not a shared object that pulls in another. - Stable libc/runtime contract for richer userland.
- Runtime wiring of the native ABI/supervisor to a filesystem-loaded
/sbin/initprocess. - Expanded compatibility ABI translation depth (Linux/Windows/macOS targets).
- Tooling and diagnostics for userland API evolution.
- A stable libc/runtime boundary, executable format policy and user-space memory/error isolation.
Next checkpoint
- Replace the fixed boot program selection with a supervised ring-3 init process and a stable userland runtime contract.