Syscalls
Userspace enters the kernel through SYSCALL, and the kernel returns through SYSRET.
There is no interrupt gate for system calls and no argument block on the stack: the call
number goes in rax, and up to six arguments go in registers.
| Register | Carries |
|---|---|
rax |
the call number on the way in, the result on the way out |
rdi, rsi, rdx, r10, r8, r9 |
arguments one through six |
rcx, r11 |
clobbered by the instruction itself: return address and RFLAGS |
The fourth argument is in r10 rather than rcx for the reason the last row gives:
SYSCALL puts the return address in rcx before any handler runs, so an argument left
there would be gone.
// The whole of the userspace side, from programs/edos_lib/src/sys.rs.pub unsafe fn syscall2(num: u64, arg1: u64, arg2: u64) -> u64 { let ret: u64; unsafe { asm!( "syscall", in("rax") num, in("rdi") arg1, in("rsi") arg2, lateout("rax") ret, lateout("rcx") _, lateout("r11") _, options(nostack), ); } ret}Reporting failure
Section titled “Reporting failure”There is no errno global and no negative-value convention shared across the table. A call
that returns a u64 signals failure with u64::MAX; one that returns a signed value
signals it with -1. Either way the number itself carries no detail, so the failing
handler stores a code on the calling thread and userspace reads it back with call 0x400.
The code is per thread, and every handler that can fail clears it before doing any work, so a stale value from an earlier call cannot be mistaken for a fresh one. A call that succeeds leaves it cleared.
Paths are NUL-terminated and are rejected past 1024 bytes. Every pointer userspace hands
over is copied through checked helpers rather than dereferenced: a bad address is
EFAULT, not a kernel fault.
The table
Section titled “The table”0readRead from a descriptor into a user buffer, advancing its offset.I/O
Reg Argument Type Meaning rdifdu64File descriptor. rsibuf*mut u8Destination buffer. rdxcountusizeBytes to read. Returnsi64 — bytes read, 0 at end of file, -1 on errorErrorsplus any filesystem failure, mapped fromFsErrorBlocks on a pipe, a pty or a tty with nothing buffered. Files are served from the page cache, so a hit never reaches the disk.
1writeWrite a user buffer to a descriptor.I/O
Reg Argument Type Meaning rdifdu64File descriptor. rsibuf*const u8Source buffer. rdxcountusizeBytes to write. A zero-length write returns 0 without touching the descriptor.
2openOpen a path and install it in the descriptor table.I/O
Reg Argument Type Meaning rdipath*const u8NUL-terminated path, at most 1024 bytes. rsiflagsu64Access mode and creation flags. Returnsi64 — new descriptor, -1 on errorErrorsplus any filesystem failure, mapped fromFsErrorThe low two bits are the access mode: 0 O_RDONLY, 1 O_WRONLY, 2 O_RDWR. 0x40 is O_CREAT, 0x200 O_TRUNC, 0x400 O_APPEND. An append offset is resolved per write rather than at open time.
3closeRelease a descriptor.I/O
Reg Argument Type Meaning rdifdu64File descriptor. 4list_dirPack a directory listing into a user buffer.Filesystem
Reg Argument Type Meaning rdipath*const u8Directory to list. rsibuf*mut u8Destination buffer. rdxbuf_sizeusizeBuffer capacity in bytes. Returnsi64 — bytes written, -1 on errorErrorsplus any filesystem failure, mapped fromFsErrorEntries are fixed-size headers each followed by a name; the return value is a byte count, not an entry count.
5getcwdCopy the working directory out as a NUL-terminated path.Filesystem
Reg Argument Type Meaning rdibuf*mut u8Destination buffer. rsisizeusizeBuffer capacity in bytes. 6chdirChange the working directory of the calling process.Filesystem
Reg Argument Type Meaning rdipath*const u8Directory to move to. 7pollWait until one of a set of descriptors is ready.I/O
Reg Argument Type Meaning rdifds*mut SelectFdArray of descriptors and interests; results are written back in place. rsicountusizeNumber of entries. rdxtimeout_msu64Timeout in milliseconds. SelectFd is { fd: u64, interests: PollState, result: PollState }, and PollState is five bools: readable, writable, error, hangup, invalid.
8fstatMetadata for an open descriptor.Filesystem
Reg Argument Type Meaning rdifdu64File descriptor. rsistatbuf*mut FstatEntryDestination struct. Returnsi64 — 0 on success, -1 on errorErrorsplus any filesystem failure, mapped fromFsError9mmapMap anonymous, file-backed or physical memory into the address space.Memory
Reg Argument Type Meaning rdiaddru64Requested address, or 0 to let the kernel choose. rsilengthu64Length in bytes. rdxprotu32PROT_READ 0x1, PROT_WRITE 0x2, PROT_EXEC 0x4. r10flagsu32MAP_SHARED 0x01, MAP_PRIVATE 0x02, MAP_FIXED 0x10, MAP_ANONYMOUS 0x20, MAP_PHYSICAL 0x40, MAP_WRITE_COMBINING 0x80. r8phys_or_fdu64Physical address for MAP_PHYSICAL, descriptor for a file-backed mapping. r9file_offsetu64Offset into the file; file-backed mappings only. Pages are faulted in on demand. MAP_PHYSICAL is how a driver in userspace reaches device memory, and it is the reason this call can return EPERM.
10statMetadata for a path.Filesystem
Reg Argument Type Meaning rdipath*const u8Path to inspect. rsipath_lenusizeLength of the path in bytes. rdxstatbuf*mut FstatEntryDestination struct. Returnsi64 — 0 on success, -1 on errorErrorsplus any filesystem failure, mapped fromFsError11munmapRemove a mapping and shoot down the stale TLB entries.Memory
Reg Argument Type Meaning rdiaddru64Start of the mapping. rsilengthu64Length in bytes. 12lseekMove the offset of a file descriptor.I/O
Reg Argument Type Meaning rdifdu64File descriptor. rsioffseti64Signed displacement. rdxwhenceu320 SEEK_SET, 1 SEEK_CUR, 2 SEEK_END. Only regular files carry an offset; anything else is rejected.
13ftruncateSet the length of an open file.Filesystem
Reg Argument Type Meaning rdifdu64File descriptor. rsisizeu64New length in bytes. 14fsyncFlush one file, data and metadata, to stable storage.Filesystem
Reg Argument Type Meaning rdifdu64File descriptor. Returnsi32 — 0 on success, -1 on errorErrorsplus any filesystem failure, mapped fromFsError15isattyReport whether a descriptor is a terminal.I/O
Reg Argument Type Meaning rdifdu64File descriptor. 16ioctlDevice-specific control, for ptys and for devfs nodes.I/O
Reg Argument Type Meaning rdifdu64File descriptor. rsirequestu64Device-defined request code. rdxargu64Inline value, or a pointer when arg_len is non-zero. r10arg_lenusizeSize of the buffer arg points at. r8flagsu64IOCTL_FLAG_READ 1 copies the buffer in, IOCTL_FLAG_WRITE 2 copies it back out. Returnsi64 — the device’s own value, -1 on errorErrorsplus any filesystem failure, mapped fromFsErrorThe buffer is bounced through the kernel rather than handed to the driver, so a device never touches a user pointer. devfs nodes are dispatched directly instead of through the filesystem mailbox.
17preadRead at an explicit offset, leaving the descriptor offset alone.I/O
Reg Argument Type Meaning rdifdu64File descriptor. rsibuf*mut u8Destination buffer. rdxcountusizeBytes to read. r10offsetu64Absolute file offset. Returnsi64 — bytes read, 0 at end of file, -1 on errorErrorsplus any filesystem failure, mapped fromFsErrorThreads of one process share a descriptor table, so they share one offset per descriptor: lseek followed by read races by construction. This call is the fix, and it is ESPIPE on anything without an offset.
18pwriteWrite at an explicit offset, leaving the descriptor offset alone.I/O
Reg Argument Type Meaning rdifdu64File descriptor. rsibuf*const u8Source buffer. rdxcountusizeBytes to write. r10offsetu64Absolute file offset. O_APPEND is deliberately not consulted: a positional write that silently lands somewhere else is worse than no call at all.
19readvRead into a list of buffers, filling each before moving to the next.I/O
Reg Argument Type Meaning rdifdu64File descriptor. rsiiov*const IoVecArray of { base, len } pairs. rdxiovcntusizeNumber of entries, at most IOV_MAX (1024). Returnsi64 — total bytes read, 0 at end of file, -1 on errorErrorsplus any filesystem failure, mapped fromFsErrorEach buffer is a separate underlying read, so the buffers fill in order but the sequence is not atomic against a concurrent reader. A short read ends the sequence, and an error after a partial transfer returns the partial count with errno cleared, as POSIX requires.
20writevWrite a list of buffers in order.I/O
Reg Argument Type Meaning rdifdu64File descriptor. rsiiov*const IoVecArray of { base, len } pairs. rdxiovcntusizeNumber of entries, at most IOV_MAX (1024). Returnsi64 — total bytes written, -1 on errorErrorsplus any filesystem failure, mapped fromFsErrorA zero-length entry is skipped rather than ending the run. A total length past i64::MAX is rejected before anything is written.
21accessTest a path for existence and readability.Filesystem
Reg Argument Type Meaning rdipath*const u8Path, not NUL-terminated. rsipath_lenusizeLength in bytes. rdxmodeu32F_OK 0, X_OK 1, W_OK 2, R_OK 4. Returnsi32 — 0 if the access would be permitted, -1 otherwiseErrorsplus any filesystem failure, mapped fromFsErrorDelegates to faccessat with AT_FDCWD. There is one user id, so only the read-only attribute can actually deny anything; undefined mode bits are EINVAL rather than ignored.
22pipeCreate a pipe and return both ends.I/O
Reg Argument Type Meaning rdipipefd*mut [u64; 2]Receives [read_fd, write_fd]. If the copy back to userspace faults, both descriptors are closed rather than leaked.
32dupDuplicate a descriptor onto the lowest free number.I/O
Reg Argument Type Meaning rdioldfdu64Descriptor to duplicate. 33dup2Duplicate a descriptor onto a chosen number, closing whatever was there.I/O
Reg Argument Type Meaning rdioldfdu64Descriptor to duplicate. rsinewfdu64Target number. 34msyncFlush the dirty pages of a MAP_SHARED range to storage.Memory
Reg Argument Type Meaning rdiaddru64Start of the range. rsilenu64Length in bytes. rdxflagsu32MS_ASYNC 0x1, MS_SYNC 0x2, MS_INVALIDATE 0x4. The VMA lock collects the work and is dropped before any disk I/O runs.
35nanosleepSleep for a duration given in nanoseconds.Time
Reg Argument Type Meaning rdireq*const TimespecRequested duration; tv_nsec must be under 1e9. rsirem*mut TimespecAccepted and validated, never written. A sleep ends on any wake, so the kernel loops until the deadline passes. `rem` stays unwritten because there are no userspace signal handlers yet, which makes an early return unobservable.
39getpidProcess ID of the caller.Process
Takes no arguments.
40waitpidWait for a child to exit and collect its status.Process
Reg Argument Type Meaning rdipidu64Child to wait for. rsiblocku641 parks until the child exits, anything else polls. rdxstatus*mut i32Receives the exit code; may be null. Returnsu64 — the pid, 0 if it has not exited and block was 0, u64::MAX on errorErrors57spawnLoad a program as a new process with three inherited descriptors.Process
Reg Argument Type Meaning rdipath*const u8Program to load. rsiargv*const *const u8NULL-terminated argument vector. rdxstdin_fdu64Descriptor to install as stdin. r10stdout_fdu64Descriptor to install as stdout. r8stderr_fdu64Descriptor to install as stderr. Registers are scarce, so anything richer than three descriptors goes through spawn2.
59execveReplace this process’s image, keeping its pid.Process
Reg Argument Type Meaning rdipath*const u8Program to load. rsiargv*const *const u8NULL-terminated argument vector. rdxenvp*const *const u8NULL-terminated environment. One rule dictates the order of the whole implementation: nothing observable changes until the point of no return, and nothing after that point may fail.
60exitTerminate the calling thread.Process
Reg Argument Type Meaning rdicodei32Exit status. 72fcntlDescriptor flags and duplication.I/O
Reg Argument Type Meaning rdifdu64File descriptor. rsicmdu64F_DUPFD 0, F_GETFD 1, F_SETFD 2, F_DUPFD_CLOEXEC 1030. rdxargu64Command-specific argument. F_GETFL and F_SETFL return EINVAL rather than a plausible-looking zero: there is no O_NONBLOCK here, and a caller told it succeeded would then rely on it.
76truncateSet a file length by path.Filesystem
Reg Argument Type Meaning rdipath*const u8Path, not NUL-terminated. rsipath_lenusizeLength in bytes. rdxsizeu64New length in bytes. Returnsi32 — 0 on success, -1 on errorErrorsplus any filesystem failure, mapped fromFsErrorGrowing a file creates a hole: the blocks it names are never allocated and read back as zeros. Shrinking zeroes the surviving tail of the last cached page, so a later grow cannot resurrect the old bytes.
78getdentsStream a directory listing from an entry index.Filesystem
Reg Argument Type Meaning rdipath*const u8Directory to list. rsipath_lenusizeLength in bytes. rdxbuf*mut u8Destination buffer. r10buf_sizeusizeBuffer capacity in bytes. r8startusizeIndex of the first entry to pack. Returnsi64 — bytes written, 0 once `start` is past the last entry, -1 on errorErrorsplus any filesystem failure, mapped fromFsErrorThe caller advances `start` by the number of entries it decoded, so there is no in/out cursor to keep. An entry that cannot fit on its own is EINVAL, not 0, because 0 means end of directory and would silently drop the tail.
82renameRename or move an entry.Filesystem
Reg Argument Type Meaning rdiold_path*const u8Existing path. rsinew_path*const u8Destination path. 88symlinkCreate a symbolic link.Filesystem
Reg Argument Type Meaning rditarget*const u8What the link points at, stored verbatim. rsitarget_lenusizeLength in bytes. rdxpath*const u8Where the link is created. r10path_lenusizeLength in bytes. Returnsi32 — 0 on success, -1 on errorErrorsplus any filesystem failure, mapped fromFsErrorDelegates to symlinkat with AT_FDCWD. Targets are stored inline in the inode on EFS. Path resolution follows links up to eight hops before returning ELOOP; unlinking a link frees its inode in the same transaction as the detach, since nothing can hold a reference to one.
89readlinkRead a symbolic link target without following it.Filesystem
Reg Argument Type Meaning rdipath*const u8The link itself. rsipath_lenusizeLength in bytes. rdxbuf*mut u8Destination buffer. r10buf_lenusizeBuffer capacity in bytes. Returnsi64 — bytes written, -1 on errorErrorsplus any filesystem failure, mapped fromFsErrorTruncates rather than failing when the buffer is short, and no terminator is written. A path that is not a link is an error, not an empty read.
102getuidReal user id of the calling process.System
Takes no arguments.
104getgidReal group id of the calling process.System
Takes no arguments.
162syncFlush every dirty block cache page to disk.Filesystem
Takes no arguments.
Errors are the writeback thread’s to log; the caller is told nothing because it can do nothing.
169rebootSync every filesystem, then stop or restart the machine.System
Reg Argument Type Meaning rdicmdu640 power off, 1 reset, 2 halt. Soft-off with no AML interpreter: PM1a/PM1b_CNT come from the FADT and SLP_TYPa is decoded structurally out of the DSDT’s \_S5_ package, with emulator ports as a fallback. Reset drives RST_CNT then pulses the 8042. Progress prints to the serial port rather than the log ring, because the kthread that drains the ring will not run again.
202mountMount a partition at a path.Filesystem
Reg Argument Type Meaning rdidevice_idu64Block device index. rsipartition_idxu64Partition within that device. rdxpath*const u8Mount point. r10fs_type*const u8Filesystem name, e.g. efs or fat32. Returnsi64 — 0 on success, -1 on errorErrorsplus any filesystem failure, mapped fromFsError203list_partitionsDescribe every partition the kernel enumerated, as text.Filesystem
Reg Argument Type Meaning rdibuf*mut u8Destination buffer. rsisizeu64Buffer capacity in bytes. 204mkdirCreate a directory.Filesystem
Reg Argument Type Meaning rdipath*const u8Directory to create. Returnsi64 — 0 on success, -1 on errorErrorsplus any filesystem failure, mapped fromFsError205rmdirRemove an empty directory.Filesystem
Reg Argument Type Meaning rdipath*const u8Directory to remove. Returnsi64 — 0 on success, -1 on errorErrorsplus any filesystem failure, mapped fromFsError206rmdir_allRemove a directory and everything under it.Filesystem
Reg Argument Type Meaning rdipath*const u8Root of the subtree to remove. Returnsi64 — 0 on success, -1 on errorErrorsplus any filesystem failure, mapped fromFsErrorThe recursion lives in the kernel because a userspace walk would race with anyone else writing into the tree.
207unlinkRemove a file.Filesystem
Reg Argument Type Meaning rdipath*const u8File to remove. Returnsi64 — 0 on success, -1 on errorErrorsplus any filesystem failure, mapped fromFsError208list_mountsDescribe the mount table as text.Filesystem
Reg Argument Type Meaning rdibuf*mut u8Destination buffer. rsisizeusizeBuffer capacity in bytes. 209sleep_msPark the calling thread for a duration.Time
Reg Argument Type Meaning rdimillisecondsu64How long to sleep. 210monotonic_timeNanoseconds since boot, from the HPET.Time
Takes no arguments.
Monotonic with microsecond resolution, scaled to nanoseconds. It never goes backwards and never jumps with the wall clock.
211cloneStart a thread in the calling process’s address space.Process
Reg Argument Type Meaning rdifuncu64Entry point. rsiargu64Value passed to the entry point. rdxflagsu64Clone flags. r10child_stacku64Top of the stack the child runs on. The child shares the address space, the descriptor table and the heap break, and gets its own TLS block and stack.
212futex_waitSleep while a word in memory still holds an expected value.Sync
Reg Argument Type Meaning rdiaddr*const u32Word to watch. rsiexpectedu32Value to sleep on. rdxtimeout_nsu64Timeout in nanoseconds; u64::MAX waits forever. Returnsu64 — 0 woken with the value changed, 1 value did not match or a spurious wake, 2 timed out, u64::MAX on errorErrorsKeyed by the address space plus the address, so two processes sharing a mapping share a queue. The wait queue is dropped when its last waiter leaves.
213futex_wakeWake waiters parked on a word.Sync
Reg Argument Type Meaning rdiaddr*const u32Word waiters are parked on. rsicountu32How many to wake. 214getrandomFill a buffer with random bytes.System
Reg Argument Type Meaning rdibuf*mut u8Destination buffer. rsilenusizeBytes to generate, at most 1 MiB. rdxflagsu64Must be 0. 215shm_createCreate a shared memory region.Shared memory
Reg Argument Type Meaning rdisizeu64Size in bytes. 216shm_mapMap a shared region into the calling process.Shared memory
Reg Argument Type Meaning rdishm_idu64Region id. rsiaddr_hintu64Suggested address, or 0 to let the kernel choose. rdxprotu64PROT_READ 0x1, PROT_WRITE 0x2, PROT_EXEC 0x4. This is what a window buffer is: the client draws into the region and the compositor reads the same frames.
217shm_unmapUnmap a shared region from the calling process.Shared memory
Reg Argument Type Meaning rdiaddru64Address the region was mapped at. 218shm_destroyDestroy a shared region.Shared memory
Reg Argument Type Meaning rdishm_idu64Region id. Refused while any mapping is still live.
219window_createRegister a window with the kernel.Window
Reg Argument Type Meaning rdixi64Position, x. rsiyi64Position, y. rdxwidthu64Width in pixels. r10heightu64Height in pixels. The kernel owns the registry and routes input to it. Decoration, stacking and everything else people call a window manager is userspace.
220window_destroyRemove a window from the registry.Window
Reg Argument Type Meaning rdiwindow_idu64Window id. 221window_setSet a window property.Window
Reg Argument Type Meaning rdiwindow_idu64Window id. rsipropu64VISIBLE 1, X 2, Y 3, WIDTH 4, HEIGHT 5, TITLE_PTR 6, BUFFER_SHM 7, FLAGS 8. rdxvalueu64The value, or a pointer for TITLE_PTR. FLAGS carries FLAG_DOCK 1, the undecorated, undraggable window the taskbar uses.
222window_getRead a window property.Window
Reg Argument Type Meaning rdiwindow_idu64Window id. rsipropu64Property id, as for window_set. 223window_pollDrain pending events for a window.Window
Reg Argument Type Meaning rdiwindow_idu64Window id. rsievents*mut WindowEventDestination array. rdxmaxu64Capacity of that array. 224window_listList every window, for the compositor.Window
Reg Argument Type Meaning rdibuf*mut WindowListEntryDestination array. rsimaxu64Capacity of that array. 225window_send_eventPost an event to a window the caller does not own.Window
Reg Argument Type Meaning rdiwindow_idu64Target window. rsievent*const WindowEventEvent to deliver. How the window manager asks a client to close itself.
226clock_gettimeNanoseconds since the Unix epoch.Time
Reg Argument Type Meaning rdibuf*mut u8Eight-byte buffer receiving a little-endian u64. Answered from the monotonic counter plus a wall-clock offset sampled at boot, so it costs a counter read rather than several RTC port round-trips.
227openptyOpen a pty master and slave pair.I/O
Reg Argument Type Meaning rdifds*mut [u64; 2]Receives [master_fd, slave_fd]. What the terminal emulator opens before it spawns a shell.
228spawn2Spawn with arguments, an environment and three descriptors.Process
Reg Argument Type Meaning rdiargs*const SpawnArgsStruct of { path, argv, envp, stdin_fd, stdout_fd, stderr_fd }. 229killSend a signal to a process.Process
Reg Argument Type Meaning rdipidu64Target process. rsisignumu32Signal number, 1 to 31. 230sigactionInstall a signal disposition.Process
Reg Argument Type Meaning rdisignumu32Signal number, 1 to 31; SIGKILL is rejected. rsihandleru320 SIG_DFL, 1 SIG_IGN, otherwise a handler address. 231shm_sizeSize of a shared region.Shared memory
Reg Argument Type Meaning rdishm_idu64Region id. 232window_damageTell the compositor a window has repainted its buffer.Window
Reg Argument Type Meaning rdiwindow_idu64Window id. 233sigprocmaskRead and change the calling thread’s blocked signal mask.Process
Reg Argument Type Meaning rdihowu32SIG_BLOCK 0, SIG_UNBLOCK 1, SIG_SETMASK 2. rsimasku32The set to apply. Sets are 32 bits, so the mask goes in and the old one comes back by value rather than through pointers, matching sigaction. A signal sent while blocked is recorded pending without killing or waking the target; widening the mask delivers it immediately, and SIGKILL is dropped from the mask rather than making the call fail.
234window_grant_shellAppoint another process as part of the shell.Window
Reg Argument Type Meaning rdipidu64Process to appoint. Moving, resizing, framing, minimizing and posting events to a window belong to a shell, not to the window’s owner, so they cannot be gated on ownership. They are gated on this instead. Only a process that already holds the privilege may grant it, and the kernel seeds exactly one: `bin/edos-init`, the only process it starts, which appoints the compositor and the panel. The grant is per pid, follows a process’s threads, and is dropped when the process exits.
240socketCreate a socket and install it in the descriptor table.Network
Reg Argument Type Meaning rdidomainu64AF_INET 2. rsitypeu64SOCK_STREAM 1, SOCK_DGRAM 2. rdxprotocolu64Ignored; implied by the type. 241bindBind a socket to a local address.Network
Reg Argument Type Meaning rdifdu64File descriptor. rsiaddr*const SockAddrInLocal address. rdxaddr_lenu64Size of that struct. 242connectOpen a connection to a remote address.Network
Reg Argument Type Meaning rdifdu64File descriptor. rsiaddr*const SockAddrInRemote address. rdxaddr_lenu64Size of that struct. Blocks through the TCP handshake.
243listenMark a bound socket as accepting connections.Network
Reg Argument Type Meaning rdifdu64File descriptor. rsibacklogu32Pending connection queue depth. 244acceptTake the next established connection off a listening socket.Network
Reg Argument Type Meaning rdifdu64File descriptor. rsiaddr*mut SockAddrInReceives the peer address; may be null. rdxaddr_len*mut u32In and out length for that struct. Returnsu64 — descriptor for the new connection, u64::MAX on errorErrors245sendtoSend on a socket, with an explicit destination for datagrams.Network
Reg Argument Type Meaning rdifdu64File descriptor. rsibuf*const u8Payload. rdxlenu64Payload length. r10flagsu64Unused. r8addr*const SockAddrInDestination; null on a connected socket. r9addr_lenu64Size of that struct. 246recvfromReceive on a socket, optionally reporting the sender.Network
Reg Argument Type Meaning rdifdu64File descriptor. rsibuf*mut u8Destination buffer. rdxlenu64Buffer capacity. r10flagsu64Unused. r8addr*mut SockAddrInReceives the sender address; may be null. r9addr_len*mut u32In and out length for that struct. 247shutdownClose one or both directions of a connection.Network
Reg Argument Type Meaning rdifdu64File descriptor. rsihowu640 read, 1 write, 2 both. 248setsockoptSet a socket option.Network
Reg Argument Type Meaning rdifdu64File descriptor. rsileveli32Option level. rdxoptnamei32Option name. r10val*const u8Option value. r8val_lenu32Length of that value. 249pingSend an ICMP echo request and wait for the reply.Network
Reg Argument Type Meaning rdidst_ip*const [u8; 4]Destination address. rsiidu16ICMP identifier. rdxsequ16ICMP sequence number. r10timeout_msu64Timeout in milliseconds; 0 means 5000. Returnsu64 — round-trip time in microseconds, u64::MAX on timeout or errorErrorsA raw socket API would be the general answer; this is the one ICMP case userspace actually needs.
250netinfoDescribe the network interfaces as text.Network
Reg Argument Type Meaning rdibuf*mut u8Destination buffer. rsilenusizeBuffer capacity in bytes. 251getsockoptRead a socket option.Network
Reg Argument Type Meaning rdifdu64File descriptor. rsileveli32Option level. rdxoptnamei32Option name. r10val*mut u8Receives the value. r8val_len*mut u32In and out length for that buffer. 252getpeernameAddress of the remote end of a connection.Network
Reg Argument Type Meaning rdifdu64File descriptor. rsiaddr*mut SockAddrInReceives the peer address. rdxaddr_len*mut u32In and out length for that struct. 253getsocknameLocal address a socket is bound to.Network
Reg Argument Type Meaning rdifdu64File descriptor. rsiaddr*mut SockAddrInReceives the local address. rdxaddr_len*mut u32In and out length for that struct. 254statfsFilesystem statistics for the mount that holds a path.Filesystem
Reg Argument Type Meaning rdipath*const u8Any path on the filesystem. rsibuf*mut RawStatFsDestination struct. rdxbuf_lenusizeSize of that struct. 255forkDuplicate the calling process, copy-on-write.Process
Takes no arguments.
Returnsi64 — the child pid in the parent, 0 in the child, -1 on errorErrorsPrivate mappings are marked read-only in both processes and split on the first write fault.
256getdnsThe resolver address the stack learned from DHCP.Network
Reg Argument Type Meaning rdiaddr*mut [u8; 4]Receives the resolver address. A resolver is configuration, and there is no /etc/resolv.conf convention here, so userspace asks the stack that learned it.
257openatOpen a path resolved against a directory descriptor.I/O
Reg Argument Type Meaning rdidirfdi64Directory the path is resolved against, or AT_FDCWD (-100) for the cwd. Ignored when the path is absolute. rsipath*const u8Path, not NUL-terminated. rdxpath_lenusizeLength in bytes. r10flagsu64Same flag set as open. Returnsi64 — new descriptor, -1 on errorErrorsplus any filesystem failure, mapped fromFsErrorShares its body with open, which is openat against the cwd. Taking pointer and length rather than a NUL-terminated string means userspace does not have to allocate a CString per open.
258mkdiratCreate a directory relative to a directory descriptor.Filesystem
Reg Argument Type Meaning rdidirfdi64Directory the path is resolved against, or AT_FDCWD (-100) for the cwd. Ignored when the path is absolute. rsipath*const u8Path, not NUL-terminated. rdxpath_lenusizeLength in bytes. Returnsi32 — 0 on success, -1 on errorErrorsplus any filesystem failure, mapped fromFsErrorNo mode argument: there are no permission bits to observe yet.
262fstatatStat a path resolved against a directory descriptor.Filesystem
Reg Argument Type Meaning rdidirfdi64Directory the path is resolved against, or AT_FDCWD (-100) for the cwd. Ignored when the path is absolute. rsipath*const u8Path, not NUL-terminated. rdxpath_lenusizeLength in bytes. r10statbuf*mut FstatEntryReceives the metadata. r8flagsu64Must be zero. Returnsi32 — 0 on success, -1 on errorErrorsplus any filesystem failure, mapped fromFsErrorstat is this call against the cwd. A nonzero flags word is rejected rather than ignored: AT_SYMLINK_NOFOLLOW cannot be honoured while the lookup follows links.
263unlinkatRemove a file or directory relative to a directory descriptor.Filesystem
Reg Argument Type Meaning rdidirfdi64Directory the path is resolved against, or AT_FDCWD (-100) for the cwd. Ignored when the path is absolute. rsipath*const u8Path, not NUL-terminated. rdxpath_lenusizeLength in bytes. r10flagsu640, or AT_REMOVEDIR (0x200) to remove a directory. Returnsi32 — 0 on success, -1 on errorErrorsplus any filesystem failure, mapped fromFsErrorAT_REMOVEDIR is the only accepted flag; anything else is EINVAL.
264renameatRename, resolving each side against its own directory descriptor.Filesystem
Reg Argument Type Meaning rdiolddirfdi64Base for the old path, or AT_FDCWD (-100). rsioldpath*const u8Existing name. rdxoldpath_lenusizeLength in bytes. r10newdirfdi64Base for the new path, or AT_FDCWD (-100). r8newpath*const u8New name. r9newpath_lenusizeLength in bytes. Returnsi32 — 0 on success, -1 on errorErrorsplus any filesystem failure, mapped fromFsErrorrename routes through the same body, which is what gives it real filesystem error codes instead of a flat EINVAL.
266symlinkatCreate a symbolic link relative to a directory descriptor.Filesystem
Reg Argument Type Meaning rditarget*const u8What the link points at, stored verbatim. rsitarget_lenusizeLength in bytes. rdxnewdirfdi64Base for the link path, or AT_FDCWD (-100). r10linkpath*const u8Where the link is created. r8linkpath_lenusizeLength in bytes. Returnsi32 — 0 on success, -1 on errorErrorsplus any filesystem failure, mapped fromFsErrorThe descriptor places the link only. The target is never resolved at creation time, so it may dangle, and a dangling link still takes the name.
267readlinkatRead a link target relative to a directory descriptor.Filesystem
Reg Argument Type Meaning rdidirfdi64Directory the path is resolved against, or AT_FDCWD (-100) for the cwd. Ignored when the path is absolute. rsipath*const u8The link itself. rdxpath_lenusizeLength in bytes. r10buf*mut u8Destination buffer. r8buf_lenusizeBuffer capacity in bytes. Returnsi64 — bytes written, -1 on errorErrorsplus any filesystem failure, mapped fromFsErrorreadlink is this call against the cwd.
269faccessatTest access to a path relative to a directory descriptor.Filesystem
Reg Argument Type Meaning rdidirfdi64Directory the path is resolved against, or AT_FDCWD (-100) for the cwd. Ignored when the path is absolute. rsipath*const u8Path, not NUL-terminated. rdxpath_lenusizeLength in bytes. r10modeu32F_OK 0, X_OK 1, W_OK 2, R_OK 4. r8flagsu64Must be zero. Returnsi32 — 0 if the access would be permitted, -1 otherwiseErrorsplus any filesystem failure, mapped fromFsErrorFlags are rejected rather than ignored. AT_EACCESS names the only set of ids there is, and AT_SYMLINK_NOFOLLOW cannot be honoured while the lookup follows links.
280utimensatSet a file’s access and modification times.Filesystem
Reg Argument Type Meaning rdidirfdi64Directory the path is resolved against, or AT_FDCWD (-100) for the cwd. Ignored when the path is absolute. rsipath*const u8Path, not NUL-terminated. rdxpath_lenusizeLength in bytes. r10times*const [Timespec; 2]Access time then modification time; null means both now. r8flagsu64Must be zero. Returnsi32 — 0 on success, -1 on errorErrorsplus any filesystem failure, mapped fromFsErrorUTIME_NOW stamps the current time and UTIME_OMIT leaves that field alone. EFS applies both in one journal transaction. AT_SYMLINK_NOFOLLOW is rejected, since the underlying set_times follows links.
1024errnoThe error code the caller’s last failing syscall stored.System
Takes no arguments.
Per thread, and cleared at the start of every handler that can fail. The value is the discriminant below, not a POSIX number.
Nothing matches that.
Error codes
Section titled “Error codes”Errno is a plain Rust enum, and what userspace reads is its discriminant. These are
not the POSIX numbers; a program that hardcodes 2 for ENOENT is reading ENOMEM.
| Value | Name | Meaning |
|---|---|---|
| 0 | Clear | No error. Every handler stores this before it does any work. |
| 1 | EINVAL | Invalid argument passed to a syscall. |
| 2 | ENOMEM | Memory allocation failed or memory exhausted. |
| 3 | EFAULT | Bad memory address provided by userspace. |
| 4 | EBADF | Invalid or closed file descriptor. |
| 5 | EACCES | Operation requires permissions the caller lacks. |
| 6 | EPERM | Operation not permitted for the current caller. |
| 7 | ENOENT | Requested file or directory does not exist. |
| 8 | EEXIST | Attempted to create an entry that already exists. |
| 9 | ENOTDIR | Expected a directory but encountered a non-directory entry. |
| 10 | EISDIR | Operation required a regular file but encountered a directory. |
| 11 | ENOSPC | Device or filesystem has no space left for the operation. |
| 12 | EROFS | Write attempted on a read-only filesystem or device. |
| 13 | EIO | Generic I/O failure from the filesystem or storage layer. |
| 14 | EINTR | System call interrupted, e.g. by a signal or a kill. |
| 15 | ENOEXEC | File format is not recognized as an executable. |
| 16 | EAGAIN | Resource temporarily unavailable; the operation would block. |
| 17 | ENOTCONN | Socket is not connected. |
| 18 | ECONNREFUSED | Connection was refused by the remote host. |
| 19 | EADDRINUSE | Address already in use. |
| 20 | EPIPE | Broken pipe: a write to a closed connection. |
| 21 | EAFNOSUPPORT | Address family not supported. |
| 22 | ESPIPE | Seek on a descriptor with no file offset: pipe, socket, tty. |
| 23 | EBUSY | Device or resource in use, e.g. a disk backing a live mount. |
| 24 | UNKNOWN | Placeholder for unmapped kernel error codes. |
Filesystem failures reach userspace through a mapping rather than as their own codes:
FileNotFound becomes ENOENT, NotAFile becomes EISDIR, NotADir becomes
ENOTDIR, Busy becomes EBUSY, InvalidFs and InvalidArgument become EINVAL, and
everything else, including a corrupt filesystem and an AHCI error, becomes EIO.
Adding one
Section titled “Adding one”Four edits, in this order:
- A number constant and a dispatch arm in
kernel/src/syscalls/mod.rs. The arm unpacks registers and calls the implementation; it does not contain logic. - The implementation in the matching
syscalls/*.rs, taking real types rather than registers, clearing the caller’s error code first and copying user memory through the checked helpers. - A wrapper in
programs/edos_lib/, or in theedos_rtcrate and the std fork if it has to be reachable throughstd. - A row here, since this page is transcribed from that table.