# System Calls ## Paths and namespaces Many syscalls accept filesystem paths. - `/...` – real filesystem paths on the **currently selected mount** (boot drive by default) - `$/mnt/vDriveN/...` – explicit mount views (e.g. `$/mnt/vDrive0/`, `$/mnt/vDrive1/`) - `$/dev/...` – DevFS device nodes (e.g. `$/dev/input/kbd0`, `$/dev/graphics/video0`) Examples: ``` # open("/ModuOS/System64/users.db", O_RDONLY, 0) # open("$/dev/input/kbd0", O_RDONLY, 0) ``` ## Paths: `/...` vs `$/...` Many syscalls accept filesystem paths. - `/...` paths resolve against the **current filesystem slot** for the calling process (boot drive selected by default). - `$/...` paths resolve through the **virtual namespace router**: - `$/dev/...` device nodes (DevFS) - `$/mnt/...` mount views (implementation-defined) System calls provide the interface between user-space programs and the kernel. ## Overview ``` User Program → INT 0x80 → Syscall Handler → Kernel Function → Return Value → Resume User Program ``` ## Syscall Mechanism ### Calling Convention **x86-64 System V ABI** (modified): ``` RAX: Syscall number RDI: Argument 1 RSI: Argument 2 RDX: Argument 3 RCX: Argument 4 R8: Argument 5 R9: Argument 6 Return value: RAX ``` ### User-Side Example ```c // User-space syscall wrapper int syscall_read(int fd, void *buffer, size_t count) { int result; __asm__ volatile( "mov $1, %%rax\n" // Syscall number (read) "mov %1, %%rdi\n" // fd "mov %2, %%rsi\n" // buffer "mov %3, %%rdx\n" // count "int $0x80\n" // Trigger interrupt "mov %%rax, %0\n" // Get return value : "=r"(result) : "r"(fd), "r"(buffer), "r"(count) : "rax", "rdi", "rsi", "rdx" ); return result; } ``` ## Syscall Numbers **File**: `include/moduos/kernel/syscall/syscall_numbers.h` ```c #define SYS_EXIT 0 #define SYS_READ 1 #define SYS_WRITE 2 #define SYS_OPEN 3 #define SYS_CLOSE 4 #define SYS_GETPID 5 #define SYS_FORK 6 #define SYS_EXEC 7 #define SYS_WAIT 8 #define SYS_KILL 9 #define SYS_SLEEP 10 #define SYS_YIELD 11 #define SYS_MMAP 12 #define SYS_MUNMAP 13 #define SYS_BRK 14 ``` ## Syscall Implementation ### Dispatcher **File**: `src/kernel/syscall/syscall.c` ```c uint64_t syscall_dispatch(uint64_t syscall_num, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6) { switch (syscall_num) { case SYS_EXIT: return sys_exit((int)arg1); case SYS_READ: return sys_read((int)arg1, (void*)arg2, (size_t)arg3); case SYS_WRITE: return sys_write((int)arg1, (const void*)arg2, (size_t)arg3); case SYS_OPEN: return sys_open((const char*)arg1, (int)arg2); case SYS_CLOSE: return sys_close((int)arg1); case SYS_GETPID: return sys_getpid(); // ... more syscalls default: return -1; // Invalid syscall } } ``` ## Available System Calls ### Process Control #### sys_exit ```c int sys_exit(int exit_code); ``` Terminate current process. #### sys_getpid ```c int sys_getpid(void); ``` Get current process ID. #### sys_fork ```c int sys_fork(void); ``` Create child process (not fully implemented). #### sys_exec ```c int sys_exec(const char *path, char **argv); ``` Execute program from file. #### sys_yield ```c void sys_yield(void); ``` Voluntarily yield CPU to other processes. #### sys_sleep ```c int sys_sleep(uint64_t milliseconds); ``` Sleep for specified time. ### File I/O #### sys_open ```c int sys_open(const char *path, int flags); ``` Open file, returns file descriptor. **Flags**: - `O_RDONLY` (0): Read only - `O_WRONLY` (1): Write only - `O_RDWR` (2): Read/Write #### sys_close ```c int sys_close(int fd); ``` Close file descriptor. #### sys_read ```c int sys_read(int fd, void *buffer, size_t count); ``` Read from file descriptor. **Returns**: Number of bytes read, or negative on error. #### sys_write ```c int sys_write(int fd, const void *buffer, size_t count); ``` Write to file descriptor. **Returns**: Number of bytes written, or negative on error. ### Memory Management #### sys_mmap ```c void* sys_mmap(void *addr, size_t length, int prot, int flags); ``` Map memory region (simplified). #### sys_munmap ```c int sys_munmap(void *addr, size_t length); ``` Unmap memory region. #### sys_brk ```c void* sys_brk(void *addr); ``` Change data segment size (for malloc). ## Error Handling ### Error Codes ```c #define ESUCCESS 0 // Success #define EPERM -1 // Operation not permitted #define ENOENT -2 // No such file or directory #define EBADF -3 // Bad file descriptor #define ENOMEM -4 // Out of memory #define EINVAL -5 // Invalid argument #define ENOSYS -6 // Function not implemented ``` ### Checking Errors ```c int result = syscall_open("/file.txt", O_RDONLY); if (result < 0) { // Error occurred switch (result) { case ENOENT: printf("File not found\n"); break; case EPERM: printf("Permission denied\n"); break; } } ``` ## Next Steps - [Process Management](Process-Management.md) - Process syscalls - [File Systems](File-Systems.md) - File I/O implementation - [Syscall Reference](Syscall-Reference.md) - Complete API reference