Syscalls

This is implemented in syscalls

The numbers of the syscalls and some metadata like SyscallResult and SyscallError are defined in kernel user link crate.

Syscalls specs is as follows:

  • Syscalls can have up to 7 arguments, and are passed in RCX, RDX, RSI, RDI, R8, R9, R10 in order.
  • The syscall number is passed in RAX.
  • The syscall return value is passed in RAX, the syscall may write to pointers passed in the other registers, but the result code will still be in RAX.
  • The returned RAX value is an encoded value of SyscallResult. So, its never intended to be read as u64 directly.
  • The arguments are not modified by the syscall, but the syscall may read from them, or write to memory pointed by them.
  • All pointers passed to the syscall are have to be valid, and point to user space memory only, the kernel will check that the memory is mapped and write to it, but it doesn't guarantee the validity of the memory if it was modified by the kernel (i.e. if the memory was pointed to random part in the heap it could corrupt the heap for example).
  • The syscall may block execution depend on the syscall itself, like wait_pid or a read to a blocking file with no data.

Syscalls list

This shows the list of syscalls and their arguments and return values. Some notes on this:

  • a: *const/*mut T, b: usize will be used in the kernel as a slice, for example write(file_index: usize, buf: &[u8]). But I didn't want to remove an argument and confuse the reader, so I split them into two as being sent from userspace.
  • types like &Path, BlockingMode, SpawnFileMapping, etc... are passed as u64 as is everything, but the kernel checks validity and cast/parse these pointers/values to the correct types.
  • All the return types are SyscallResult and will report any error during execution, for simplicity, I didn't just repeat that in the table.
  • When the return type is (), it means the kernel will return SyscallResult::Ok(0), the userspace will check that its 0.
NameArgumentsReturn valueDescription
openpath: &Path, access_mode: u64, mode: u64file_index: usizeOpens a file
writefile_index: usize, buf: *const u8, size: usizebytes_written: usizeWrites to a file
readfile_index: usize, buf: *mut u8, size: usizebytes_read: usizeReads from a file
closefile_index: usize()Closes a file
blocking_modefile_index: usize, blocking_mode: BlockingMode()Sets the blocking mode of a file. This is DEPRECATED, and should be replaced with set_file_meta with FileMeta::BlockingMode
exitexit_code: i32!Exits the current process
spawnpath: &Path, argv: *const *const u8, file_mappings: *const SpawnFileMapping, file_mappings_size: usizepid: u64Spawns a new process
inc_heapincrement: i64old_heap_end: usizeIncrease/decrease the heap of the current process (similar sbrk)
create_piperead_fd: *mut usize, write_fd: *mut usize()Creates a pipe
wait_pidpid: u64, block: boolexit_code: i32Waits for a process to exit
statpath: &Path, stat: *mut FileStat()Gets the file stat of a file
open_dirpath: &Pathdir_index: usizeOpens a directory
read_dirdir_index: usize, buf: *mut DirEntry, len: usizeentries_read: usizeReads from a directory
get_cwdbuf: *mut u8, len: usizeneeded_bytes: usizeGets the current working directory, returns fferTooSmall` if the buffer is too small
chdirpath: &Path()Changes the current working directory
set_file_metafile_index: usize, meta_id: u64, meta_data: u64()Sets the file meta
get_file_metafile_index: usize, meta_id: u64, meta_data: *mut u64()Gets the file meta
sleepseconds: u64, nanos: u64()Sleeps for a duration
get_timeclock_type: ClockType, time: *mut ClockTime()Gets the time based on the clock_type, see Clocks
graphicscommand: GraphicsCommand, extra: *mut ()()Graphics operations, see Graphics:VGA
seekfile_index: usize, whence: SeekWhence, offset: i64new_offset: u64Seeks a file
prioritypid: u64, priority: Option<PriorityLevel>PriorityLevelSets and gets the priority of a process