|
PatchworkOS
19e446b
A non-POSIX operating system.
|
System Call Interface. More...
System Call Interface.
System calls provide a controlled interface for user-space applications to request services from the kernel, such as file operations, process management, and inter-process communication.
Historically, system calls were invoked using software interrupts (usually int 0x80), which are relatively slow due to overhead from interrupt handling.
Instead, we use the modern SYSCALL instruction, which allows for a faster transition from user mode to kernel mode, but it is a little more complex to set up.
The syscall calling convention mostly follows the standard System V ABI for x86_64 architecture, with the exception of the argument registers, and the use of the RAX register for the syscall number.
Arguments are passed to syscalls using the RDI, RSI, RDX, R10, R8, and R9 registers, in that order. The syscall number is passed in the RAX register.
After the registers are setup the syscall instruction should be called, with the return value is being placed in the RAX register.
If the return value is ERR for a system call that returns an integer or NULL for a system call that returns a pointer. Then the SYS_ERRNO syscall can be used to retrieve the associated error code.
Data Structures | |
| struct | syscall_ctx_t |
| Per thread syscall context. More... | |
| struct | syscall_descriptor_t |
| A syscall descriptor. More... | |
Macros | |
| #define | SYSCALL_CTX_SYSCALL_RSP_OFFSET 0x0 |
The offset of the syscallRsp member in the syscall_ctx_t structure. | |
| #define | SYSCALL_CTX_USER_RSP_OFFSET 0x8 |
The offset of the userRsp member in the syscall_ctx_t structure. | |
| #define | SYSCALL_DEFINE(num, returnType, ...) |
| Macro to define a syscall. | |
Enumerations | |
| enum | syscall_number_t { SYS_EXITS , SYS_THREAD_EXIT , SYS_SPAWN , SYS_NANOSLEEP , SYS_ERRNO , SYS_GETPID , SYS_GETTID , SYS_UPTIME , SYS_EPOCH , SYS_OPEN , SYS_OPEN2 , SYS_CLOSE , SYS_READ , SYS_WRITE , SYS_SEEK , SYS_IOCTL , SYS_POLL , SYS_STAT , SYS_MMAP , SYS_MUNMAP , SYS_MPROTECT , SYS_GETDENTS , SYS_THREAD_CREATE , SYS_YIELD , SYS_DUP , SYS_DUP2 , SYS_FUTEX , SYS_REMOVE , SYS_LINK , SYS_SHARE , SYS_CLAIM , SYS_BIND , SYS_OPENAT , SYS_NOTIFY , SYS_NOTED , SYS_READLINK , SYS_SYMLINK , SYS_MOUNT , SYS_UNMOUNT , SYS_ARCH_PRCTL , SYS_SETUP , SYS_TEARDOWN , SYS_ENTER , SYS_TOTAL_AMOUNT } |
| System Call Numbers. More... | |
| enum | syscall_flags_t { SYSCALL_NORMAL = 0 << 0 , SYSCALL_FORCE_FAKE_INTERRUPT = 1 << 0 } |
| Syscall flags. More... | |
Functions | |
| void | syscall_ctx_init (syscall_ctx_t *ctx, const stack_pointer_t *syscallStack) |
| Initialize a syscall context. | |
| void | syscall_ctx_load (syscall_ctx_t *ctx) |
Load the syscall context into the MSR_KERNEL_GS_BASE MSR. | |
| void | syscall_table_init (void) |
| Sort the syscall table and verify that all syscalls are present. | |
| void | syscall_handler (interrupt_frame_t *frame) |
| Main C syscall handler. | |
| void | syscall_entry (void) |
| Assembly entry point for syscalls. | |
Variables | |
| syscall_descriptor_t | _syscall_table_start [] |
| Linker defined start of the syscall table. | |
| syscall_descriptor_t | _syscall_table_end [] |
| Linker defined end of the syscall table. | |
| #define SYSCALL_CTX_SYSCALL_RSP_OFFSET 0x0 |
The offset of the syscallRsp member in the syscall_ctx_t structure.
Needed to access the syscall context from assembly code.
| #define SYSCALL_CTX_USER_RSP_OFFSET 0x8 |
The offset of the userRsp member in the syscall_ctx_t structure.
Needed to access the syscall context from assembly code.
| #define SYSCALL_DEFINE | ( | num, | |
| returnType, | |||
| ... | |||
| ) |
Macro to define a syscall.
Uses the ._syscall_table linker section to store the syscall descriptor.
| num | The syscall number, must be unique, check syscall_number_t. |
| returnType | The return type of the syscall handler, must be uint64_t compatible. |
| ... | The arguments of the syscall handler, can be no more than 6 arguments (Such that we only use registers to pass them). |
| enum syscall_number_t |
System Call Numbers.
| enum syscall_flags_t |
Syscall flags.
| void syscall_ctx_init | ( | syscall_ctx_t * | ctx, |
| const stack_pointer_t * | syscallStack | ||
| ) |
| void syscall_ctx_load | ( | syscall_ctx_t * | ctx | ) |
| void syscall_table_init | ( | void | ) |
| void syscall_handler | ( | interrupt_frame_t * | frame | ) |
Main C syscall handler.
This is called from the assembly syscall_entry() function.
Since notes can only be handled when in user space, this function will, if there are notes pending, provide a fake interrupt context to handle the note as if a interrupt had occurred at the exact same time as the system call began.
| frame | The interrupt frame containing the CPU state at the time of the syscall. |
Definition at line 75 of file syscall.c.
|
extern |
Assembly entry point for syscalls.
The logic for saving/restoring registers and switching stacks is done here before calling syscall_handler().
|
extern |
Linker defined start of the syscall table.
|
extern |
Linker defined end of the syscall table.