Syscall Interface
The syscall layer is the boundary between user code and the kernel. All resource access goes through syscalls.
Design Principles
- Isolation: Processes can only access what they have handles to
- Auditing: All operations go through a single point
- Safety: The kernel validates all operations
- Simplicity: Familiar POSIX-like interface
File Operations
open
Open a file or device.
OpenFlags is a struct with boolean fields:
pub struct OpenFlags {
pub read: bool,
pub write: bool,
pub create: bool,
pub truncate: bool,
pub append: bool,
}
Predefined constants:
- OpenFlags::READ - Open for reading only
- OpenFlags::WRITE - Open for writing (creates and truncates)
- OpenFlags::RDWR - Open for reading and writing
- OpenFlags::APPEND - Open for appending (creates but doesn't truncate)
Special paths:
- /dev/console - System console
- /dev/null - Discard writes, EOF on read
- /dev/zero - Returns zeros on read
Example:
read
Read from a file descriptor.
Returns the number of bytes read, or 0 at EOF.
write
Write to a file descriptor.
Returns the number of bytes written.
close
Close a file descriptor.
Decrements the reference count on the underlying object. If refcount reaches 0, the object is freed.
dup
Duplicate a file descriptor.
Creates a new fd pointing to the same object. Increments refcount.
Directory Operations
mkdir
Create a directory.
Parent directory must exist.
readdir
List directory contents.
Returns names of files and subdirectories.
exists
Check if a path exists.
getcwd
Get current working directory.
chdir
Change working directory.
Process Operations
getpid
Get current process ID.
exit
Exit the current process.
Sets process state to Zombie with the exit code.
IPC Operations
pipe
Create a pipe for inter-process communication.
Returns (read_fd, write_fd). Data written to write_fd can be read from read_fd.
Memory Operations
mem_alloc
Allocate a memory region.
Protection flags:
- Protection::READ - Read-only
- Protection::READ_WRITE - Read and write
- Protection::READ_EXEC - Read and execute
mem_free
Free a memory region.
mem_read
Read from a memory region.
mem_write
Write to a memory region.
Shared Memory
shmget
Create a shared memory segment.
shmat
Attach to a shared memory segment.
Returns a region ID that can be used with mem_read/mem_write.
shmdt
Detach from a shared memory segment.
If refcount reaches 0, the segment is freed.
shm_sync
Sync local changes to shared memory.
shm_refresh
Refresh local region from shared memory.
Memory Stats
memstats
Get memory stats for current process.
pub fn memstats() -> SyscallResult<MemoryStats>
pub struct MemoryStats {
pub allocated: usize, // Current allocation
pub limit: usize, // Memory limit (0 = unlimited)
pub peak: usize, // Peak usage
pub region_count: usize, // Number of regions
pub shm_count: usize, // Attached shared memory count
}
set_memlimit
Set memory limit for current process.
system_memstats
Get system-wide memory stats.
pub fn system_memstats() -> SyscallResult<SystemMemoryStats>
pub struct SystemMemoryStats {
pub total_allocated: usize,
pub system_limit: usize,
pub shm_count: usize,
pub shm_total_size: usize,
}
Window Operations
window_create
Create a GUI window.
Returns a file descriptor for the window.
Console Operations
console_push_input
Push input to the console (for keyboard input).
console_take_output
Take output from the console.
Timer Operations
timer_set
Set a one-shot timer.
Timer fires after delay_ms milliseconds. If wake_task is provided, that task is woken when the timer fires.
timer_interval
Set a repeating interval timer.
Timer fires every interval_ms milliseconds until cancelled.
timer_cancel
Cancel a pending timer.
Returns true if the timer was pending and cancelled.
Signal Operations
kill
Send a signal to a process.
Available signals:
- SIGTERM - Graceful termination
- SIGKILL - Immediate termination (cannot be caught)
- SIGSTOP - Stop process (cannot be caught)
- SIGCONT - Continue stopped process
- SIGINT, SIGQUIT, SIGHUP - Termination signals
- SIGUSR1, SIGUSR2 - User-defined signals
- SIGCHLD - Child status changed
- SIGALRM - Timer alarm
- SIGPIPE - Broken pipe
signal
Set signal disposition for current process.
Actions:
- SignalAction::Default - Use default behavior
- SignalAction::Ignore - Ignore the signal
- SignalAction::Terminate - Terminate the process
- SignalAction::Handle - Custom handler (future)
Note: SIGKILL and SIGSTOP cannot have their disposition changed.
sigblock
Block a signal (queue but don't deliver).
sigunblock
Unblock a signal.
sigpending
Check if there are pending signals.
Tracing Operations
trace_enable
Enable kernel tracing.
trace_disable
Disable kernel tracing.
trace_enabled
Check if tracing is enabled.
trace_summary
Get a summary of kernel statistics.
Returns uptime, syscall counts, scheduler stats, process counts, and I/O bytes.
trace_reset
Reset all trace data and statistics.
trace_event
Record a custom trace event.
Error Handling
All syscalls return SyscallResult<T>, which is Result<T, SyscallError>:
pub enum SyscallError {
BadFd, // Invalid file descriptor
NotFound, // File or path not found
PermissionDenied, // Permission denied
InvalidArgument, // Invalid argument
WouldBlock, // Would block (non-blocking I/O)
BrokenPipe, // Pipe/connection closed
Busy, // Resource busy
NoProcess, // No current process
Io(String), // Generic I/O error
Memory(MemoryError), // Memory error
Signal(SignalError), // Signal error
Interrupted, // Interrupted by signal
}
Standard File Descriptors
Every process starts with:
- Fd::STDIN (0) - Standard input
- Fd::STDOUT (1) - Standard output
- Fd::STDERR (2) - Standard error
All three point to the console by default.
Usage Example
use axeberg::kernel::syscall;
// Read a file
let fd = syscall::open("/home/user/data.txt", syscall::OpenFlags::READ)?;
let mut buf = [0u8; 1024];
let n = syscall::read(fd, &mut buf)?;
syscall::close(fd)?;
// Create and write to a file
let fd = syscall::open("/tmp/output.txt", syscall::OpenFlags::WRITE)?;
syscall::write(fd, b"Hello, axeberg!")?;
syscall::close(fd)?;
// Allocate memory
let region = syscall::mem_alloc(4096, Protection::READ_WRITE)?;
syscall::mem_write(region, 0, b"data")?;
syscall::mem_free(region)?;