Kernel

System Calls

The syscall surface is defined in include/uapi/syscalls.h and dispatched by a single switch in src/kernel/core/syscall.cpp.

ABI

Userspace invokes syscalls with the syscall instruction via inline wrappers (src/usr/libc/syscall.h):

  • Number in rax; arguments in rdi, rsi, rdx, r10, r8, r9; return value in rax. rcx and r11 are clobbered.
  • Per-core MSRs: STAR (kernel CS 0x08, user selector base with the AMD SYSRET quirk), LSTAR = syscall_entry, SFMASK clears TF/IF/DF/NT/RF/AC, EFER.SCE enabled.
  • The entry path (src/arch/x86_64/boot/usermode.asm) swaps to the kernel stack via per-CPU GS data, builds a SyscallFrame (registers plus saved rip/cs/rflags/rsp/ss), and enables interrupts — syscalls run with interrupts on.
  • On return, pending signals are checked, volatile registers are zeroed (no kernel state leaks to user), and o64 sysret returns. Non-canonical rcx takes an iretq fallback instead.
  • A legacy int 0x80 gate (DPL 3) reaches the same handler; userspace does not use it.

Error conventions: classic calls return (uint64_t)-1; extended calls (270 and up) return negative errno values (-4 EINTR, -9 EBADF, -11 EAGAIN, -12 ENOMEM, -14 EFAULT, -16 EBUSY, -19 ENODEV, -22 EINVAL, -24 EMFILE, -28 ENOSPC, -32 EPIPE, -110 ETIMEDOUT). User pointers are validated against the process VMA list; string copies are bounded; data copies use SMAP-aware fixup paths.

Files and Descriptors

# Name Purpose
0 SYS_READ Read from fd; stdin polls keyboard + serial
1 SYS_WRITE Write to fd; stdout/stderr go to boot log / serial
2 SYS_OPEN Open with O_CREAT/O_TRUNC/O_APPEND
3 SYS_CLOSE Close fd
4 SYS_STAT Stat a path
22 SYS_PIPE Create a pipe (two fds)
33 SYS_DUP2 Duplicate fd
78 SYS_GETDENTS Stateful readdir: one entry per call
83 SYS_MKDIR Create directory
87 SYS_UNLINK Delete file
224 SYS_RENAME Rename file or directory
225 SYS_RMDIR Remove empty directory
277 SYS_FTRUNCATE Truncate open file (FAT32: to 0 only)
279 SYS_FSIZE Size of an open file (used to validate memfd buffers)
280 SYS_SYNC Flush page cache and filesystem state
281 SYS_LSEEK Reposition fd offset (SEEK_SET/CUR/END from uapi/fs.h)

Processes, Threads, Signals

# Name Purpose
13 SYS_SIGACTION Install or query a signal handler
15 SYS_SIGRETURN Return from a signal handler
24 SYS_YIELD Voluntary reschedule
37 SYS_KILL Send a signal to a pid
39 SYS_GETPID Current pid
57 SYS_FORK Clone the process (CoW)
59 SYS_EXEC Replace the process image
60 SYS_EXIT Exit with status; kills the other live threads in the group
61 SYS_WAIT4 Wait for children (WNOHANG = 1)
62 SYS_GETPROCS Snapshot the process list
102 SYS_GETUID Current uid
105 SYS_SETUID Set uid (root only)
271 SYS_THREAD_CREATE Create a thread sharing the address space and fd table
297 SYS_THREAD_EXIT Terminate only the calling thread (never returns)
298 SYS_THREAD_DETACH Mark a child thread detached (self-reap, no join)

Thread syscalls: SYS_THREAD_CREATE(entry, arg, stack_top, flags, stack_lo, stack_size) builds the entry frame from the caller's live syscall frame (user segments and rflags carry over; arg reaches the entry in rdi) and returns the new thread's pid, or -22 for a null entry/stack_top/frame, -12 when the thread's TLS block cannot be allocated or installed, -14 when the recorded TLS template VAs are not readable (a bad template, not a memory shortage), and -11 while an exec is tearing the caller's thread group down (the group is being replaced; retry after the exec resolves). flags (arg4) honors THREAD_DETACHED (uapi/syscalls_ext.h) — the thread is created detached, never waitable — and ignores unknown bits; stack_lo/stack_size (arg5/arg6) record a range that SYS_THREAD_EXIT unmaps, with 0/0 keeping the caller-managed stack of the original form. SYS_THREAD_EXIT(status) ends only the calling thread after unmapping its recorded range and TLS mapping; SYS_THREAD_DETACH(tid) returns -10 when tid is not a live child thread (forked children lead their own group). Threads are processes with their own pids: SYS_GETPID in a thread returns the thread pid, and a joinable thread is reaped by SYS_WAIT4 from its creator. See Processes — Threads and Processes — Thread-Local Storage.

Memory

# Name Purpose
9 SYS_MMAP Anonymous or memfd-backed mapping
10 SYS_MUNMAP Unmap a range
270 SYS_FUTEX FUTEX_WAIT / FUTEX_WAKE (WAIT takes a relative timeout in arg4; wakes are matched by the physical address of the 32-bit word)
272-274 SYS_EPOLL_CREATE/CTL/WAIT Epoll instances over fds
275 SYS_MPROTECT Change protections on mapped pages
276 SYS_MEMFD_CREATE Anonymous memory-file fd (max 16 MiB)

Futex: FUTEX_WAIT(uaddr, expected, timeout_ms) takes a relative timeout in milliseconds (arg4; 0 = infinite, sub-tick timeouts round up to one timer tick) and returns -11 when the word holds a different value, -110 on expiry, -12 when the timed-wait registration cannot be allocated, and -4 when a fatal signal interrupts the wait (both the timed and untimed waits recheck fatal signals right before parking). FUTEX_WAKE(uaddr, count) wakes up to count waiters parked on that exact word — the count is literal, POSIX-style, so 0 wakes none — and returns how many it woke; the word is keyed by physical address, so the same shared frame mapped at different virtual addresses — cross-process shared memfd pages — still matches.

Display, GUI, Input, Sound

# Name Purpose
205-207 SYS_SOUND_PLAY/WRITE/CONFIG PLAY: file playback via the kernel parser. WRITE: streaming PCM push (fails without an open stream). CONFIG: card format
282 SYS_SOUND_STREAM_OPEN Open streaming playback (rate, channels, 16-bit); stops previous playback
283 SYS_SOUND_STREAM_END No more stream data; drain queued PCM then auto-close (immediately when nothing was queued)
284 SYS_SOUND_STOP Abort the stream and stop the card
285 SYS_SOUND_PAUSE Pause stream playback (idempotent; latches if DMA has not started)
286 SYS_SOUND_RESUME Resume stream playback (idempotent; clears a latched pause)
287 SYS_SOUND_STATUS Fill sound_status (uapi/sound.h): played/queued bytes, format, flags (paused includes the latch, owned marks the caller's own stream)
288 SYS_SOUND_VOLUME Card master volume 0-100
208 SYS_FB_INFO Framebuffer geometry
209 SYS_FB_MMAP Map the framebuffer at 0x200000000 (WC)
210 SYS_GET_EVENT Pop an event from the process queue (blocking flag)
211 SYS_FB_FLUSH Store fence for WC writes
212 SYS_FB_BLIT Full-frame blit from a user buffer
214 SYS_FB_BLIT_RECT Rect blit
244 SYS_POST_EVENT Push an event into another process's queue
245 SYS_GUI_REGISTER_WM Caller becomes the window manager
246 SYS_GUI_SET_FOCUS WM-only: set the focused pid
247-262 SYS_DISPLAY_* KMS-style display API (see below)
289 SYS_INPUT_ENUM_DEVICES Fill InputDeviceInfo[] (uapi/input.h); returns total count
290 SYS_INPUT_SET_POINTER_SPEED Q8 multiplier (256 = 1.0x, clamped 16-1024) applied to mouse deltas
291 SYS_INPUT_SET_REPEAT_RATE USB HID key-repeat delay_ms and rate_ms
292 SYS_INPUT_SET_DEVICE_ENABLED Enable/disable an input source by stable id (PS/2 sentinel or USB slot)
293 SYS_NET_STATUS Fill NetStatus (uapi/syscalls_ext.h): ip/netmask/gateway/dns (host order), link_up, configured, nic
294 SYS_SOCKET_STATE Socket state: NET_TCP_* (mirrors kernel TcpState) for TCP handles, NET_SOCK_UDP_OPEN for UDP; -9 EBADF for unused/invalid handles
295 SYS_PING One blocking ICMP echo probe (ip, timeout_ms, *rtt_ms): 0 + rtt, -110 ETIMEDOUT, -19 ENODEV, -16 EBUSY (probe ring full), -14 EFAULT
296 SYS_NET_RENEW Force a full DHCP exchange: 0 on ACK, -11 EAGAIN before net_init, -19 ENODEV, -16 EBUSY (renew in flight), -100 ENETDOWN

Display syscalls: GET_CAPS 247, PRESENT 248, WAIT 249, GET_STATUS 250, QUERY_CONNECTORS 252, GET_MODES 253, SET_MODE 254, BUFFER_CREATE 255, BUFFER_MAP 256, BUFFER_DESTROY 257, COMPOSE_SUBMIT 258, EVENT_WAIT 259, ATOMIC_COMMIT 260, BUFFER_SET_WM_ACCESS 261, SURFACE_IMPORT 262. Present requests carry up to 128 damage rects; compose requests up to 32 layers and 32 damage rects. See Display.

Input syscalls: ENUM_DEVICES 289 fills an array of InputDeviceInfo (PS/2 mouse/keyboard plus one entry per USB HID mouse/keyboard stream) and returns the total count (entries beyond the caller's buffer are truncated). SET_POINTER_SPEED scales raw mouse deltas before accumulation (orthogonal to the PS/2 acceleration curve); SET_REPEAT_RATE tunes the USB HID software repeat; SET_DEVICE_ENABLED freezes a source at the driver (its state is preserved, not zeroed). See Input.

Shared Memory

# Name Purpose
240 SYS_SHM_GET Allocate a block (max 16 MiB), returns id 0-63
241 SYS_SHM_MAP Map at 0x300000000 + id * 16 MiB
242 SYS_SHM_FREE Unmap and release
243 SYS_SHM_INFO Block size
251 SYS_SHM_UNMAP Unmap only
263 SYS_SHM_GET_OWNER Owner pid
278 SYS_FD_TRANSFER Copy an fd's vnode into another process (pid 0 = the WM)

Network

# Name Purpose
220 SYS_SOCKET AF_INET; SOCK_STREAM = TCP, SOCK_DGRAM = UDP
221 SYS_BIND Bind a port
222/223 SYS_SENDTO/RECVFROM UDP datagrams
229/230/233 SYS_CONNECT/SEND/RECV TCP stream
234 SYS_CLOSESOCKET Close a socket
235 SYS_RESOLVE DNS hostname to IPv4

Socket handles are not file descriptors: handle = kind << 12 | index. See Networking.

System

# Name Purpose
169 SYS_REBOOT Reboot
231 SYS_POWEROFF ACPI poweroff
201 SYS_GETTIME RTC wall clock
202 SYS_GETUPTIME Seconds since boot
203 SYS_GETMEMINFO Total/free/used memory
204 SYS_GETSYSINFO Kernel commit, bootloader, timer Hz, CPU count, debug flag
213 SYS_GET_TSC_FREQ Calibrated TSC frequency in MHz (0 if uncalibrated)
215 SYS_GET_TICKS Raw timer ticks
216 SYS_SLEEP_MS Sleep for at least the given milliseconds (real sleep, signal-interruptible)
226 SYS_GETVOLUMES Volume list (max 16)
227/228 SYS_STORAGE_GET_MODE/SET_MODE Storage guard mode; SET is WM-only
232 SYS_SET_QUIET Toggle boot framebuffer logging
236 SYS_GETRANDOM Up to 64 KiB from a seeded xorshift* PRNG (not cryptographic)