Kernel Service Calls
June 25, 2026 ยท View on GitHub
The XenevaOS Service Call Interface (SCI) provides a controlled gateway for user-space applications to request services from the kernel. Service calls act as the bridge between user mode and kernel mode, and can be thought of as Kernel IPC. Service calls allow applications to perform privileged operations such as file access, memory management, process control, and network communication. In XenevaOS, all user applications interact with the kernel through a well-defined set of system calls that follow a consistent calling convention and interface layout.
Calling Convention
System calls in XenevaOS are invoked using the syscall instruction (on x86_64) or svc #0 (on ARM64).
The system call number is placed in the R12 register, and arguments are passed through registers R13, R14, R15, RDI, and the stack. Upon completion, the return value is stored in the RAX register.
For ARM64, the system call number is placed in the X16 register, and arguments are passed through registers X0, X1, X2, X3, X4, and X5. Upon completion, the return value is stored in the X6 register.
Example (x86_64):
ExitProcess:
mov r12, 5
mov r13, 0
mov r14, 0
mov r15, 0
mov rdi, 0
syscall
ret
Example (ARM64):
ProcessSleep:
mov x16, 23
svc #0
mov x0, x6
ret
Kernel Service Calls
The kernel maintains a service call dispatch table, which maps each kernel handler function to its respective system call number.
| Service Number | Symbol Name | Description |
|---|---|---|
| 0 | null_call | Does nothing, returns 0 |
| 1 | SeTextOut/UARTDebugOut | Uses Kernel serial console output to print user space messages |
| 2 | PauseThread | Puts the currently running thread into the blocked queue |
| 3 | GetThreadID | Returns currently running thread ID |
| 4 | GetProcessID | Returns current running process ID |
| 5 | ProcessExit | Terminate and deallocate all resources of current running process |
| 6 | ProcessWaitForTermination | Puts the currently running process into the wait queue until the desired process terminates (which is specified by process ID in the arguments) |
| 7 | CreateProcess | Creates a new process slot in the kernel |
| 8 | ProcessLoadExec | Loads an executable into the provided process slot |
| 9 | CreateSharedMem | Creates a shared memory segment in the current process slot |
| 10 | ObtainSharedMem | Maps and returns a pointer to the shared memory address mapped to the physical addresses of the provided shared memory segment |
| 11 | UnmapSharedMem | Unmaps a shared memory segment from the current process (the shared memory segment is not freed until it is detached from all processes) |
| 12 | OpenFile | Opens a file in the kernel and returns its file descriptor allocated in the current process slot |
| 13 | CreateMemMapping | Creates a memory mapping inside a process of memory, file or device |
| 14 | UnmapMemMapping | Unmaps a previously mapped memory within a process. It requires the memory pointer |
| 15 | GetProcessHeapMem | Process on Aurora maintains heap memory separately, i.e it uses separate address range from MemMappings |
| 16 | ReadFile | Reads a file to a given buffer, it requires the file descriptor number previously allocated using OpenFile call |
| 17 | WriteFile | Writes data to a file from given buffer, it requires the file descriptor number previously allocated using OpenFile call |
| 20 | CloseFile | Closes a given file, requires the file descriptor allocated using OpenFile call |
| 21 | FileIoControl | Submit commands to a given file, mostly used in device files |
| 22 | FileStat | Get metadata of a file to a given buffer, metadata holds information such as file size, creation/modificatin date, current position and EndOfFile bit |
| 23 | ProcessSleep | Put a process on sleep for given amount of time, it accepts number of scheuler ticks |
| 24 | AuGetSystemTimerTick | Get the current number of timer ticks passed since the system was booted |