This list is unstable and subject to change between versions of MOROS.
Each syscall is documented with its high-level Rust API wrapper and details of the raw interface when needed.
Any reference to a slice in the arguments (like &str
or &[u8]
) will need to
be converted into a pointer and a length for the raw syscall.
Any negative number returned by a raw syscall indicates that an error has
occurred. In the high-level API, this will be typically converted to an
Option
or a Result
type.
At the lowest level a syscall follows the System V ABI convention with its
number set in the RAX
register, and its arguments in the RDI
, RSI
, RDX
,
and R8
registers. The RAX
register is reused for the return value.
Hello world example in assembly using the WRITE
and EXIT
syscalls:
[bits 64]
section .data
msg: db "Hello, World!", 10
len: equ $-msg
global _start
section .text
_start:
mov rax, 4 ; syscall number for WRITE
mov rdi, 1 ; standard output
mov rsi, msg ; addr of string
mov rdx, len ; size of string
int 0x80
mov rax, 1 ; syscall number for EXIT
mov rdi, 0 ; no error
int 0x80
fn exit(code: ExitCode)
Terminate the calling process.
The code can be one of the following:
pub enum ExitCode {
Success = 0,
Failure = 1,
UsageError = 64,
DataError = 65,
OpenError = 128,
ReadError = 129,
ExecError = 130,
PageFaultError = 200,
ShellExit = 255,
}
The ExitCode
is converted to a usize
for the raw syscall.
fn spawn(path: &str, args: &[&str]) -> ExitCode
Spawn a process with the given list of arguments.
This syscall will block until the child process is terminated. It will return
the ExitCode
passed by the child process to the EXIT
syscall.
fn read(handle: usize, buf: &mut [u8]) -> Option<usize>
Read from a file handle to a buffer.
Return the number of bytes read on success.
fn write(handle: usize, buf: &[u8]) -> Option<usize>
Write from a buffer to a file handle.
Return the number of bytes written on success.
fn open(path: &str, flags: u8) -> Option<usize>
Open a file and return a file handle.
The flags can be one or more of the following:
enum OpenFlag {
Read = 1,
Write = 2,
Append = 4,
Create = 8,
Truncate = 16,
Dir = 32,
Device = 64,
}
The flags OpenFlag::Create | OpenFlag::Dir
can be used to create a directory.
Reading a directory opened with OpenFlag::Read | OpenFlag::Dir
will return a
list of FileInfo
, one for each file in the directory.
fn close(handle: usize)
Close a file handle.
fn info(path: &str) -> Option<FileInfo>
Get information on a file.
A FileInfo
will be returned when successful:
struct FileInfo {
kind: FileType,
size: u32,
time: u64,
name: String,
}
The raw syscall takes the pointer and the length of a mutable reference to a
FileInfo
that will be overwritten on success and returns a isize
to
indicate the result of the operation.
fn dup(old_handle: usize, new_handle: usize) -> Result<(), ()>
Duplicate a file handle.
fn delete(path: &str) -> Result<(), ()>
Delete a file.
fn stop(code: usize)
The system will reboot with 0xCAFE
and halt with 0xDEAD
.
fn sleep(seconds: f64)
The system will sleep for the given amount of seconds.
fn poll(list: &[(usize, IO)]) -> Option<(usize, IO)>
Given a list of file handles and IO
operations:
enum IO {
Read,
Write,
}
The index of the first file handle in the list that is ready for the given IO
operation is returned by the raw syscall on success or a negative number if no
operations are available for any file handles. The syscall is not blocking and
will return immediately.
For example polling the console will show when a line is ready to be read, or polling a socket will show when it can receive or send data.
fn connect(handle: usize, addr: IpAddress, port: u16) -> Result<(), ()>
Connect a socket to an endpoint at the given IpAddress
and port:
struct Ipv4Address([u8; 4]);
struct Ipv6Address([u8; 16]);
enum IpAddress {
Ipv4(Ipv4Address),
Ipv6(Ipv6Address),
}
NOTE: Only IPv4 is currently supported.
fn listen(handle: usize, port: u16) -> Result<(), ()>
Listen for incoming connections to a socket.
fn accept(handle: usize) -> Result<IpAddress, ()>
Accept an incoming connection to a socket.
The raw syscall takes the pointer and the length of a mutable reference to an
IpAddress
that will be overwritten on success and returns a isize
indicating the result of the operation.
fn alloc(size: usize, align: usize) -> *mut u8
Allocate memory.
fn free(ptr: *mut u8, size: usize, align: usize)
Free memory.
fn kind(handle: usize) -> Option<FileType>
Return the file type of a file handle.
A FileType
will be returned when successful:
enum FileType {
Dir = 0,
File = 1,
Device = 2,
}
The raw syscall returns a isize
that will be converted a FileType
if the
number is positive.