From c7f23d9f3ea6a53f5346e3d93b6cf3fde2f21efc Mon Sep 17 00:00:00 2001 From: Mark Poliakov Date: Tue, 12 Mar 2024 13:37:40 +0200 Subject: [PATCH 1/2] Initial commit --- .gitignore | 1 + Cargo.lock | 7 ++ Cargo.toml | 6 ++ src/lib.rs | 1 + yggdrasil.abi | 239 ++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 254 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 src/lib.rs create mode 100644 yggdrasil.abi diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..ea8c4bf7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 00000000..738141c2 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "yggdrasil-abi-def" +version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 00000000..aca414f9 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "yggdrasil-abi-def" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 00000000..c8ef1980 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1 @@ +pub const ABI_FILE: &str = include_str!("../yggdrasil.abi"); diff --git a/yggdrasil.abi b/yggdrasil.abi new file mode 100644 index 00000000..1689f657 --- /dev/null +++ b/yggdrasil.abi @@ -0,0 +1,239 @@ +// vi:syntax=yggdrasil_abi: + +extern { + type Duration = core::time::Duration; + type SocketAddr = core::net::SocketAddr; + type AtomicU32 = core::sync::atomic::AtomicU32; + + type MappingSource; + + type SystemInfo = yggdrasil_abi::system::SystemInfo; + + type SignalEntryData = yggdrasil_abi::process::SignalEntryData; + type SpawnOptions = yggdrasil_abi::process::SpawnOptions; + type MutexOperation = yggdrasil_abi::process::MutexOperation; + type ExecveOptions = yggdrasil_abi::process::ExecveOptions; + #[thin] + type ExitCode = yggdrasil_abi::process::ExitCode; + + type SocketOption = yggdrasil_abi::net::SocketOption; + + type SentMessage = yggdrasil_abi::io::SentMessage; + type ReceivedMessageMetadata = yggdrasil_abi::io::ReceivedMessageMetadata; + type MountOptions = yggdrasil_abi::io::MountOptions; + type UnmountOptions = yggdrasil_abi::io::UnmountOptions; + type DeviceRequest = yggdrasil_abi::io::DeviceRequest; + type FileMetadataUpdate = yggdrasil_abi::io::FileMetadataUpdate; + type DirectoryEntry = yggdrasil_abi::io::DirectoryEntry; + type FileAttr = yggdrasil_abi::io::FileAttr; + #[thin] + type SeekFrom = yggdrasil_abi::io::SeekFrom; + #[thin] + type MessageDestination = yggdrasil_abi::io::MessageDestination; + + type TerminalOptions = yggdrasil_abi::io::TerminalOptions; + type TerminalSize = yggdrasil_abi::io::TerminalSize; +} + +// abi::error + +enum Error(u32) { + OutOfMemory = 1, + AlreadyExists = 2, + NotImplemented = 3, + DoesNotExist = 4, + InvalidFile = 5, + InvalidArgument = 6, + Interrupted = 7, + WouldBlock = 8, + UnrecognizedExecutable = 9, + InvalidOperation = 10, + InvalidMemoryOperation = 11, + NotADirectory = 12, + IsADirectory = 13, + ReadOnly = 14, + PermissionDenied = 15, + AddrInUse = 16, + QueueFull = 17, + BufferTooSmall = 18, + ConnectionReset = 19, + MissingData = 20, + NetworkUnreachable = 21, + TimedOut = 22, + ConnectionRefused = 23, + HostUnreachable = 24, + UndefinedSyscall = 25, + DirectoryNotEmpty = 26, +} + +// abi::process + +enum Signal(u32) { + /// Process has tried to perform an illegal memory operation + MemoryAccessViolation = 1, + /// Process has hit a breakpoint or was aborted + Aborted = 2, + /// Process was killed + Killed = 3, + /// Process was interrupted + Interrupted = 4, +} + +// abi::io + +newtype RawFd(u32); + +newtype UserId(u32); +newtype GroupId(u32); + +bitfield FileMode(u32) { + /// Other user execution access + OTHER_EXEC: 0, + /// Other user write access + OTHER_WRITE: 1, + /// Other user read access + OTHER_READ: 2, + + /// Group execution access + GROUP_EXEC: 3, + /// Group write access + GROUP_WRITE: 4, + /// Group read access + GROUP_READ: 5, + + /// User execution access + USER_EXEC: 6, + /// User write access + USER_WRITE: 7, + /// User read access + USER_READ: 8, +} + +bitfield OpenOptions(u32) { + /// The file is to be opened with read capability + READ: 0, + /// The file is to be opened with write capability + WRITE: 1, + + /// Open file at the end + APPEND: 2, + /// Truncate the file to zero bytes when opening + TRUNCATE: 3, + + /// Create the file if it does not exist + CREATE: 4, + /// When combined with CREATE, will fail if the file already exists + CREATE_EXCL: 5, +} + +enum FileType(u32) { + /// Regular file + File = 1, + /// Directory + Directory = 2, + /// Not yet implemented + Symlink = 3, + /// Block device + Block = 4, + /// Character device (e.g. terminal) + Char = 5, +} + +enum PollControl(u32) { + AddFd = 1, +} + +// abi::net + +enum SocketType(u32) { + /// Raw packet socket + RawPacket = 0, + /// TCP stream socket + TcpStream = 1, + /// UDP packet socket + UdpPacket = 2, +} + +// TODO allow splitting types into separate modules + +syscall debug_trace(message: &str); +syscall get_random(buffer: &mut [u8]); +syscall get_system_info(info: &mut SystemInfo) -> Result<()>; +syscall mount(opts: &MountOptions<'_>) -> Result<()>; +syscall unmount(opts: &UnmountOptions) -> Result<()>; + +// Memory management +syscall map_memory(hint: Option, len: usize, source: &MappingSource) -> Result; +syscall unmap_memory(address: usize, len: usize) -> Result<()>; + +// Process/thread management +syscall exit_process(code: ExitCode) -> !; +syscall spawn_process(options: &SpawnOptions<'_>) -> Result; +syscall wait_process(pid: u32, status: &mut ExitCode) -> Result<()>; +syscall get_pid() -> u32; + +syscall nanosleep(dur: &Duration); + +syscall exit_signal(frame: &SignalEntryData) -> !; +syscall set_signal_entry(ip: usize, sp: usize); +syscall send_signal(target: u32, signal: Signal) -> Result<()>; + +syscall mutex(mutex: &AtomicU32, op: &MutexOperation) -> Result<()>; + +syscall start_session() -> Result<()>; + +// I/O +syscall open(at: Option, path: &str, opts: OpenOptions, mode: FileMode) -> Result; +syscall close(fd: RawFd) -> Result<()>; +syscall write(fd: RawFd, data: &[u8]) -> Result; +syscall read(fd: RawFd, data: &mut [u8]) -> Result; +syscall seek(fd: RawFd, pos: SeekFrom) -> Result; + +syscall open_directory(at: Option, path: &str) -> Result; +syscall read_directory_entries(fd: RawFd, entries: &mut [MaybeUninit]) -> Result; +syscall create_directory(at: Option, path: &str, mode: FileMode) -> Result<()>; +syscall remove_directory(at: Option, path: &str) -> Result<()>; + +syscall remove(at: Option, path: &str) -> Result<()>; +syscall clone_fd(source: RawFd, target: Option) -> Result; +syscall update_metadata(at: Option, path: &str, update: &FileMetadataUpdate) -> Result<()>; +syscall get_metadata(at: Option, path: &str, metadata: &mut MaybeUninit, follow: bool) -> Result<()>; +syscall device_request(fd: RawFd, req: &mut DeviceRequest) -> Result<()>; + +// Misc I/O +syscall open_channel(name: &str, subscribe: bool) -> Result; +syscall create_timer(repeat: bool) -> Result; +syscall create_pty(opts: &TerminalOptions, size: &TerminalSize, fds: &mut [MaybeUninit; 2]) -> Result<()>; +syscall create_shared_memory(size: usize) -> Result; +syscall create_poll_channel() -> Result; +syscall create_pipe(fds: &mut [MaybeUninit; 2]) -> Result<()>; + +syscall poll_channel_wait( + poll_fd: RawFd, + timeout: &Option, + output: &mut Option<(RawFd, Result<()>)> +) -> Result<()>; +syscall poll_channel_control(poll_fd: RawFd, ctl: PollControl, fd: RawFd) -> Result<()>; + +syscall send_message(fd: RawFd, msg: &SentMessage<'_>, dst: MessageDestination) -> Result<()>; +syscall receive_message( + fd: RawFd, + meta: &mut MaybeUninit, + data: &mut [u8], + from: &mut MaybeUninit +) -> Result<()>; + +// Network +syscall connect_socket(sock_fd: Option, remote: &SocketAddr, ty: SocketType, local: &mut MaybeUninit) -> Result; +syscall bind_socket(address: &SocketAddr, ty: SocketType) -> Result; +syscall accept(sock_fd: RawFd, remote: &mut MaybeUninit) -> Result; + +syscall send_to(sock_fd: RawFd, data: &[u8], remote: &Option) -> Result; +syscall receive_from(sock_fd: RawFd, data: &mut [u8], remote: &mut MaybeUninit) -> Result; + +syscall get_socket_option(sock_fd: RawFd, option: &mut SocketOption<'_>) -> Result<()>; +syscall set_socket_option(sock_fd: RawFd, option: &SocketOption<'_>) -> Result<()>; + +// C compat +syscall fork() -> Result; +syscall execve(options: &ExecveOptions<'_>) -> Result<()>; From 9fd6415c95bf4427998ed23fa283d2cef5c7ef77 Mon Sep 17 00:00:00 2001 From: Mark Poliakov Date: Tue, 12 Mar 2024 14:47:30 +0200 Subject: [PATCH 2/2] Wrap IDs in ChannelPublisherId/ProcessId/ThreadId --- yggdrasil.abi | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/yggdrasil.abi b/yggdrasil.abi index 1689f657..d8b45113 100644 --- a/yggdrasil.abi +++ b/yggdrasil.abi @@ -79,6 +79,9 @@ enum Signal(u32) { Interrupted = 4, } +newtype ProcessId(u32); +newtype ThreadId(u32); + // abi::io newtype RawFd(u32); @@ -86,6 +89,8 @@ newtype RawFd(u32); newtype UserId(u32); newtype GroupId(u32); +newtype ChannelPublisherId(u32); + bitfield FileMode(u32) { /// Other user execution access OTHER_EXEC: 0, @@ -168,15 +173,15 @@ syscall unmap_memory(address: usize, len: usize) -> Result<()>; // Process/thread management syscall exit_process(code: ExitCode) -> !; -syscall spawn_process(options: &SpawnOptions<'_>) -> Result; -syscall wait_process(pid: u32, status: &mut ExitCode) -> Result<()>; -syscall get_pid() -> u32; +syscall spawn_process(options: &SpawnOptions<'_>) -> Result; +syscall wait_process(pid: ProcessId, status: &mut ExitCode) -> Result<()>; +syscall get_pid() -> ProcessId; syscall nanosleep(dur: &Duration); syscall exit_signal(frame: &SignalEntryData) -> !; syscall set_signal_entry(ip: usize, sp: usize); -syscall send_signal(target: u32, signal: Signal) -> Result<()>; +syscall send_signal(target: ProcessId, signal: Signal) -> Result<()>; syscall mutex(mutex: &AtomicU32, op: &MutexOperation) -> Result<()>; @@ -220,7 +225,7 @@ syscall receive_message( fd: RawFd, meta: &mut MaybeUninit, data: &mut [u8], - from: &mut MaybeUninit + from: &mut MaybeUninit ) -> Result<()>; // Network @@ -235,5 +240,5 @@ syscall get_socket_option(sock_fd: RawFd, option: &mut SocketOption<'_>) -> Resu syscall set_socket_option(sock_fd: RawFd, option: &SocketOption<'_>) -> Result<()>; // C compat -syscall fork() -> Result; +syscall fork() -> Result; syscall execve(options: &ExecveOptions<'_>) -> Result<()>;