System Calls


GuardBSD exposes a minimal and capability-secured syscall surface provided by the three microkernels:

  • µK-Space,

  • µK-Time,

  • µK-IPC.

System calls form the lowest-level interface between userland and the kernel, with userland libraries (libgbsd) acting as safe Rust wrappers.

This API is based on GuardBSD 1.0.0 (Winter Saga).


Overview

GuardBSD follows a strict capability model:

  • No ambient authority - every operation requires a valid capability.
  • Type-safe interface - syscalls operate on strongly typed values.
  • Architecture-agnostic design - syscall numbers and registers differ per architecture, but semantics remain identical.

System calls are grouped by microkernel:

  • µK-Space → memory management
  • µK-Time → threads, scheduling, timers
  • µK-IPC → message passing & ports
  • Capability operations → delegation, revocation
  • Process operations → process creation, termination

Calling Conventions

x86_64 (int 0x80)

  • rax - syscall number
  • rdi, rsi, rdx, r10, r8, r9 - arguments
  • return value in rax (negative = -errno)

AArch64 (svc #0)

  • x8 - syscall number
  • x0x5 - arguments
  • return value in x0 (negative = -errno)

More details in the ABI section.


µK-Space - Memory Management

space_create(size, rights)

Creates a new memory region; returns a capability handle.
Reference: oaicite 4.

Rights: none (creates new capability)

let cap = sys_space_create(4096, Rights::READ | Rights::WRITE)?;

space_map(cap, vaddr)

Maps memory into the current address space. Requires READ rights.

space_unmap(cap)

Unmaps a previously mapped region.

space_info(cap)

Returns SpaceInfo: size, permissions, physical address.


µK-Time - Threads & Scheduling

thread_create(entry, arg, stack_cap)

Creates a new thread.

let tid = sys_thread_create(thread_fn as usize, 42, stack_cap)?;

thread_yield()

Voluntarily yields the CPU.

thread_join(tid)

Waits for thread to exit; returns its return code.

time_sleep(duration)

Puts the current thread to sleep.

time_get()

Returns system time in nanoseconds.


µK-IPC - Message Passing

IPC is based on message ports and capabilities.

port_create(rights)

Creates an IPC port.

port_send(port, message)

Asynchronous send. Returns immediately unless queue is full.

port_receive(port, timeout)

Waits for a message.

port_call(port, request, timeout)

Performs a synchronous request→reply exchange.


let reply_port = sys_port_call(server_port, &request, None)?;
let response = sys_port_receive(reply_port, None)?;

port_poll(ports, timeout)

Polls multiple ports; returns first ready one.


Capability Operations

Capabilities control all access in GuardBSD.

cap_grant(cap, pid, rights)

Grants a capability to another process with reduced rights.

cap_revoke(cap)

Revokes a capability immediately.

cap_duplicate(cap, rights)

Creates a new capability with reduced rights.


Process Syscalls

process_create(image_cap, args)

Creates a new process and returns:

  • process capability
  • initial IPC port capability (bootstrap port)

process_wait(process_cap)

Waits for process termination.

process_kill(process_cap, signal)

Sends a signal.


Syscall Numbers (Reference)

From the low-level syscall table:


| Number | Name           | Description       |
| ------ | -------------- | ----------------- |
| 1      | `exit`         | terminate process |
| 3      | `read`         | read from FD      |
| 4      | `write`        | write to FD       |
| 5      | `open`         | open file         |
| 6      | `close`        | close FD          |
| 7      | `getpid`       | get process ID    |
| 8      | `stat`         | file metadata     |
| 9      | `rename`       | atomic rename     |
| 10     | `unlink`       | remove file       |
| 11     | `sync`         | flush writes      |
| 20–24  | IPC port ops   | µK-IPC            |
| 25–28  | capability ops | grant/revoke/copy |
| 29–31  | IPC extras     | sync_call/reply   |
| 40–42  | log transport  | kernel logs       |

Full table in the Quick Reference.


Error Handling

Syscalls return negative codes on error (POSIX-like). libgbsd maps these to Error enum:


InvalidArgument
PermissionDenied
NotFound
OutOfMemory
Timeout
InvalidState
CapabilityRevoked


Performance Notes

From kernel benchmarks:

  • port_send ≈ 150–180 cycles
  • port_receive ≈ 120 cycles
  • space_map ≈ 300 cycles
  • thread_yield ≈ 80 cycles
  • time_get ≈ 50 cycles

Related Documentation

  • ABI - binary structure layouts
  • CLI - userland tooling
  • libgbsd - Rust syscall wrappers