Skip to content

System Calls

NtinosTheGamer2324 edited this page Dec 28, 2025 · 2 revisions

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

// 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

#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

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

int sys_exit(int exit_code);

Terminate current process.

sys_getpid

int sys_getpid(void);

Get current process ID.

sys_fork

int sys_fork(void);

Create child process (not fully implemented).

sys_exec

int sys_exec(const char *path, char **argv);

Execute program from file.

sys_yield

void sys_yield(void);

Voluntarily yield CPU to other processes.

sys_sleep

int sys_sleep(uint64_t milliseconds);

Sleep for specified time.

File I/O

sys_open

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

int sys_close(int fd);

Close file descriptor.

sys_read

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

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

void* sys_mmap(void *addr, size_t length, int prot, int flags);

Map memory region (simplified).

sys_munmap

int sys_munmap(void *addr, size_t length);

Unmap memory region.

sys_brk

void* sys_brk(void *addr);

Change data segment size (for malloc).

Error Handling

Error Codes

#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

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

Clone this wiki locally