aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--static/md/srvre/kernel/wiki.md2
-rw-r--r--static/md/srvre/kernel/wiki/startup.md3
-rw-r--r--static/md/srvre/kernel/wiki/syscalls.md267
-rw-r--r--static/md/srvre/kernel/wiki/userinit.md3
-rw-r--r--static/md/srvre/kernel/wiki/vfs.md128
5 files changed, 72 insertions, 331 deletions
diff --git a/static/md/srvre/kernel/wiki.md b/static/md/srvre/kernel/wiki.md
index 2480cd3..44309e8 100644
--- a/static/md/srvre/kernel/wiki.md
+++ b/static/md/srvre/kernel/wiki.md
@@ -15,7 +15,7 @@ List
* [Startup](/md/srvre/kernel/wiki/startup.md)
* [userinit](/md/srvre/kernel/wiki/userinit.md)
* [Syscalls](/md/srvre/kernel/wiki/syscalls.md)
-* [VFS](/md/srvre/kernel/wiki/vfs.md) and [builtin resources](/md/srvre/kernel/wiki/vfs.md#builtin-resources)
+* [Message passing](/md/srvre/kernel/wiki/msgpass.md)
* [Errors](/md/srvre/kernel/wiki/errors.md)
[Project Page](/md/srvre/kernel.md)
diff --git a/static/md/srvre/kernel/wiki/startup.md b/static/md/srvre/kernel/wiki/startup.md
index 8cf05aa..58d52a1 100644
--- a/static/md/srvre/kernel/wiki/startup.md
+++ b/static/md/srvre/kernel/wiki/startup.md
@@ -7,9 +7,8 @@ When the kernel starts up on the boot hart it performs the following steps:
1. Initialize the SBI console
2. Enable all interrupts
-3. Configure Sv39 identity paging
+3. Configure Sv39 paging
4. Configure the PLIC (Platform-Level Interrupt Controller) if present
-5. Enumerate PCI(e) devices if present
6. Start `/init` from the embedded [userinit](/md/srvre/kernel/wiki/userinit.md)
It is legal for the init process to terminate, but only if there is at least
diff --git a/static/md/srvre/kernel/wiki/syscalls.md b/static/md/srvre/kernel/wiki/syscalls.md
index 28b9d50..0f44f98 100644
--- a/static/md/srvre/kernel/wiki/syscalls.md
+++ b/static/md/srvre/kernel/wiki/syscalls.md
@@ -4,8 +4,8 @@ date: "Wed Jun 19 2024"
---
System calls are the most fundamental interface between processes
-and the kernel. They provide access to kernel APIs such as the
-[VFS](/md/srvre/kernel/wiki/vfs.md).
+and the kernel. They provide access to kernel APIs such as
+[message passing](/md/srvre/kernel/wiki/msgpass.md).
Calling convention
==================
@@ -29,8 +29,14 @@ registers:
| Register | Friendly name | Meaning |
| :------: | :-----------: | :-------------- |
-| x10 | a0 | Return value #0 |
-| x11 | a1 | Return value #1 |
+| x10 | a0 | Return value |
+| x11 | a1 | Error code |
+
+The operation was successful if and only if the error code is zero.
+Any other value indicates an [error](/md/srvre/kernel/wiki/errors.md).
+Error codes are not stable across source code changes due to the use of Zig's
+`@intFromError` cast. You may however pass such an error code to
+[errorName](#errorname-100000) to retrieve its name.
List
====
@@ -38,253 +44,118 @@ List
The following syscalls are currently available.
Detailed descriptions follow after the summary table.
-| Number | Name |
-| :----: | :--------------------------------------- |
-| 100000 | [uprint](#uprint-100000) |
-| 100001 | [open](#open-100001) |
-| 100002 | [close](#close-100002) |
-| 100003 | [provideStream](#providestream-100003) |
-| 100004 | [provideFile](#providefile-100004) |
-| 100005 | [provideHook](#providehook-100005) |
-| 100006 | [mkdir](#mkdir-100006) |
-| 100007 | [provideDirHook](#providedirhook-100007) |
-| 100008 | [remove](#remove-100008) |
-| 100009 | [read](#read-100009) |
-| 100010 | [write](#write-100010) |
-
-uprint (#100000)
-----------------
-
-Signature:
-```
-uprint(str_addr: usize, len: usize) void
-```
-
-**WARNING:** This system call will be removed in a future version.
-
-Prints the string at `str_addr` to the debug console,
-preceeded by "User message: " and succeeded by "\n".
-
-* `str_addr` is the memory address of the first character of the string
-* `len` is the length of the string in bytes
+| Number | Name |
+| :----: | :----------------------------------- |
+| 100000 | [errorName](#errorname-100000) |
+| 100001 | [consoleWrite](#consoleWrite-100001) |
+| 100002 | [launch](#launch-100002) |
+| 100003 | [end](#end-100003) |
+| 100004 | [terminate](#terminate-100004) |
+| 100005 | [processId](#processid-100005) |
+| 100006 | [threadId](#threadid-100006) |
-open (#100001)
---------------
+errorName (#100000)
+-------------------
Signature:
```
-open(path_c: [*:0]const u8, data: usize) Result(usize)
+errorName(code: usize, buffer: [*]u8, len: usize) !usize
```
-Opens the resource at `path_c`, returning a handle to a descriptor
-(or a driver-specific return value) or an error.
-All but the last component of the path must already exist
-and support holding sub-resources.
-
-* `path_c` is a null-terminated POSIX path
-* `data` is either passed to the driver or used to decide
-how to open the resource (i.e. read-only, read-write, append etc.)
-
-close (#100002)
----------------
-
-Signature:
+Possible errors:
```
-close(handle: usize) void
+ZeroAddressSupplied
+ErrorCodeOutOfRange
```
-Closes the resource descriptor identified by `handle`.
-This system call cannot fail, invalid handles are silently ignored.
+Writes the name matching an error code to a buffer.
+If the name exceeds the length of the buffer the remaining bytes are truncated.
-* `handle` is a handle to a resource descriptor
+* `code` is the error code to get the name of
+* `buffer` is a pointer to the output buffer
+* `len` is the length of the buffer in bytes
-provideStream (#100003)
------------------------
+consoleWrite (#100001)
+----------------
Signature:
```
-provideStream(
- path_c: [*:0]const u8,
- readFn: ?*const fn (buffer: []u8) Result(usize),
- writefn: ?*const fn (bytes: []const u8) Result(usize),
-) Result(void)
+consoleWrite(bytes: [*]const u8, len: usize) void
```
-Provides a [stream resource](/md/srvre/kernel/wiki/vfs.md#stream)
-at `path_c`. This system call can fail. The callbacks are optional,
-omitting them causes their respective operations to raise a
-"\*NotSupported" error.
-All but the last component of the path must already exist
-and support holding sub-resources.
+Writes the string at `bytes` directly to the debug console.
-* `path_c` is a null-terminated POSIX path
-* `readFn` is the callback to invoke when a process tries to read from the resource
-* `writeFn` is the callback to invoke when a process tries to write to the resource
+* `bytes` is a pointer to the string
+* `len` is the length of the string in bytes
-provideFile (#100004)
----------------------
+launch (#100002)
+----------------
Signature:
```
-provideFile(
- path_c: [*:0]const u8,
- readFn: ?*const fn (context: *vfs.FileContext, buffer: []u8) Result(usize),
- writeFn: ?*const fn (context: *vfs.FileContext, bytes: []const u8) Result(usize),
- closeFn: ?*const fn (context: *vfs.FileContext) void,
- initializer: ?*anyopaque,
-) Result(void)
-```
-
-Provides a [file resource](/md/srvre/kernel/wiki/vfs.md#file)
-at `path_c`. This system call can fail. All callbacks are optional,
-omitting them causes their respective operations to raise a "\*NotSupported"
-error with the exception of `close` which will still work without invoking a
-custom callback.
-All but the last component of the path must already exist
-and support holding sub-resources.
-
-* `path_c` is a null-terminated POSIX path
-returning a pointer to a driver-specific context data structure which is passed
-to the other callbacks but never exposed to any other processes by the kernel,
-or an error; You may store the process ID in this context object if required
-* `readFn` is the callback to invoke when a process tries to read from the resource
-* `writeFn` is the callback to invoke when a process tries to write to the resource
-* `closeFn` is the callback to invoke when a process closes the resource
-* `initializer` is an optional pointer to an initial context object passed to the callback functions.
-
-The `vfs.FileContext` struct is defined as follows:
-
-```
-pub const FileContext = extern struct {
- inner: ?*anyopaque,
-};
+launch(bytes: [*]align(@alignOf(std.elf.Elf64_Ehdr)) const u8, len: usize) !usize
```
-Callbacks, particularly `readFn` and `writeFn`, may initialize this value
-if unset or modify it later and it will be preserved across calls from the
-same process.
+Maps the provided ELF into memory and starts its entry point in a new process,
+returning its ID.
-The `inner` field is set to `null` by default. Most callback implementations
-will want to check for this and initialize it using the `initializer` field
-if necessary.
+The bytes need to have the same alignment as the ELF header (currently 8).
-The `initializer` field is set to the `initializer` parameter of this
-system call. Changing it will not affect its value for later
-[open](#open-100001) operations.
+* `bytes` is a pointer to the ELF data
+* `len` is the length of the ELF data in bytes
-provideHook (#100005)
----------------------
+end (#100003)
+-------------
Signature:
```
-provideHook(
- path_c: [*:0]const u8,
- callback: *allowzero const fn (pid: u16, data: usize) Result(usize),
-) Result(void)
+end() noreturn
```
-Provides a [hook resource](/md/srvre/kernel/wiki/vfs.md#hook)
-at `path_c`. This system call can fail.
-All but the last component of the path must already exist
-and support holding sub-resources.
-
-* `path_c` is a null-terminated POSIX path
-* `callback` is the callback to invoke when a process tries to open the resource,
-returning a driver-specific integer value or an error; This callback gets access
-to the `data` parameter passed to the [open](#open) syscall by the process
+Terminates the calling thread. If the calling thread is the main thread (ID 0)
+of the calling process, the entire process is terminated.
+This may change in the future.
-mkdir (#100006)
----------------
+terminate (#100004)
+-------------------
Signature:
```
-mkdir(path_c: [*:0]const u8, options: usize) Result(void)
+terminate(pid: u16, tid: usize) !void
```
-**WARNING:** This system call is currently not implemented and will cause a kernel panic.
-**WARNING:** The options will be removed before this version is released.
-
-Creates a [directory](/md/srvre/kernel/wiki/vfs.md#directory)
-at `path_c`. This system call can fail.
-All but the last component of the path must already exist
-and support holding sub-resources, unless the `full` option is set
-which creates missing components as directories unless they already exist
-as non-directory resources (which raises an error).
-
-* `path_c` is a null-terminated POSIX path
-* `options` is a bit field holding any combination of the following flags:
- * `full` (1): Create all required components as directories if possible (comparable to `mkdir -p` on Linux)
-
-provideDirHook (#100007)
-------------------------
-
-Signature:
+Possible errors:
```
-provideDirHook(
- path_c: [*:0]const u8,
- provideFn: *allowzero const fn (inode: Inode) Result(void),
- findFn: *allowzero const fn (name: []const u8) ?Inode,
- removeFn: *allowzero const fn (name: []const u8) Result(void),
-) Result(void)
+PidOutOfRange
+ProcessNotFound
```
-Creates a [directory hook](/md/srvre/kernel/wiki/vfs.md#directory-hook)
-at `path_c`. This system call can fail.
-All but the last component of the path must already exist
-and support holding sub-resources.
+Terminates the specified thread. If the thread is the main thread (ID 0)
+of the process, the entire process is terminated.
+This may change in the future.
-* `path_c` is a null-terminated POSIX path
-* `provideFn` is the callback to invoke when any "provide\*" syscall provides a direct sub-resource of this resource
-* `findFn` is the callback to invoke to get a sub-resource by name if it exists
-* `removeFn` is the callback to invoke when the [remove](#remove-100008) syscall removes a direct sub-resource of this resource
+* `pid` is the ID of the process to apply the termination to
+* `tid` is the ID of the thread to terminate within the process
-remove (#100008)
-----------------
+processId (#100005)
+-------------------
Signature:
```
-remove(path_c: [*:0]const u8) Result(void)
+processId() usize
```
-**WARNING:** This system call is currently not implemented and will cause a kernel panic.
-
-Removes a [resource](/md/srvre/kernel/wiki/vfs.md#resources)
-from the [VFS](/md/srvre/kernel/wiki/vfs.md).
+Returns the ID of the calling process.
-* `path_c` is a null-terminated POSIX path
-
-read (#100009)
---------------
+threadId (#100006)
+------------------
Signature:
```
-read(handle: usize, buffer: [*]u8, len: usize) Result(usize)
+threadId() usize
```
-Reads up to `len` bytes from the resource referenced by `handle` into `buffer`,
-returning how many bytes were read or an error.
-A return value of zero indicates that there is no more data to be read
-or that `len` is zero.
-
-* `handle` is a handle to a resource descriptor
-* `buffer` is the buffer to read into
-* `len` is the maximum number of bytes to read and **must not be larger than the length of the buffer to prevent buffer overflows**
-
-write (#100010)
----------------
-
-Signature:
-```
-write(handle: usize, bytes: [*]const u8, len: usize) Result(usize)
-```
-
-Writes up to `len` bytes from `bytes` to the resource referenced by `handle`,
-returning how many bytes were written or an error.
-A return value of zero indicates that `len` is zero.
-
-* `handle` is a handle to a resource descriptor
-* `bytes` is the buffer to write from
-* `len` is the maximum number of bytes to write and **must not be larger than the length of the buffer to prevent buffer underflows**
+Returns the ID of the calling thread within the calling process.
[Return to Wiki Main Page](/md/srvre/kernel/wiki.md)
diff --git a/static/md/srvre/kernel/wiki/userinit.md b/static/md/srvre/kernel/wiki/userinit.md
index 67d6100..a835002 100644
--- a/static/md/srvre/kernel/wiki/userinit.md
+++ b/static/md/srvre/kernel/wiki/userinit.md
@@ -13,8 +13,7 @@ The kernel cannot be built if a userinit cannot be accessed at a predefined
path. This is because it is embedded into the kernel binary so that it can be
accessed without requiring any in-kernel drivers.
-A userinit is simply an uncompressed `tar(1)` blob containing a directory tree
-that is made available via the [VFS](/md/srvre/kernel/wiki/vfs.md).
+A userinit is an uncompressed `tar(1)` blob.
The kernel searches for an `init` executable at its root
(ignoring file permissions). This file is executed to hand over control
to userspace and is typically responsible for starting essential drivers,
diff --git a/static/md/srvre/kernel/wiki/vfs.md b/static/md/srvre/kernel/wiki/vfs.md
deleted file mode 100644
index 377095e..0000000
--- a/static/md/srvre/kernel/wiki/vfs.md
+++ /dev/null
@@ -1,128 +0,0 @@
----
-title: "VFS - SRVRE Kernel Wiki"
-date: "Wed Jun 19 2024"
----
-
-The VFS (Virtual File System) is the universal interface between processes
-and resources. It is protected by the permission system.
-
-Authorized processes have the ability to access or provide resources.
-
-Resources
-=========
-
-A resource is a control or data interface in the file system.
-Examples include process metadata and termination, files on storage media
-and network protocols. They are uniquely identified by unique POSIX paths,
-though it is possible to reuse the same implementation with multiple paths.
-There are several different kinds of resources.
-
-Stream
-------
-
-A stream is a shared byte stream that can be readable, writable,
-both or none. The data will be distributed across all readers
-in an unpredictable (but cryptographically insecure) fashion.
-Writes can be interleaved. The combination of process authorization
-and provider-side implementation decides which directions are available.
-
-Example use cases: Random byte stream, infinite zeroes, null/void
-
-File
-----
-
-A file is similar to a stream in that it provides a byte stream
-that can be readable, writable, both or none. The main difference
-is that the provider can tell the handles to it apart.
-
-Example use cases: Stored files, network sockets, runtime configuration
-and control options
-
-Hook
-----
-
-A hook performs an action when opened. Resources of this kind
-don't allocate a resource descriptor when opened, meaning that they can't
-and never need to be closed. The provider can return any `usize` value instead.
-
-Example use cases: Process termination, system shutdown, UNIX time retrieval
-
-Directory
----------
-
-A directory is a collection of resources and managed by the kernel.
-Nesting is supported.
-
-Example use cases: Grouping of runtime configuration and control options,
-hardware devices, network protocols etc.
-
-Directory hook
---------------
-
-A directory hook functions like a regular directory, but is managed by
-a U-mode provider instead of the kernel keeping track of the items
-contained within.
-
-Example use cases: Filesystem drivers, network protocols
-
-Builtin resources
-=================
-
-The kernel provides the following builtin resources for providers
-and other programs to build upon:
-
-`/io`
------
-
-The `/io` directory provides interfaces for byte-grained, often text-based
-communication with the environment the program is running in.
-
-* `/io/debug`: Write-only access to the debug console, usually provided by the SBI (firmware)
-
-`/userinit`
------------
-
-The `/userinit` directory provides read-only access to the
-[userinit](/md/srvre/kernel/wiki/userinit.md) tree.
-Its purpose is to make essential drivers and the data required to run them
-to the init process.
-
-* `/userinit/init`: The executable started as the init process. There is nothing special about it internally but it's noteworthy enough to be listed here explicitly.
-
-`/process`
-----------
-
-The `/process` directory provides information about as well as control
-interfaces to processes and threads, including the caller.
-
-* `/process/create`: A [hook](#hook) that adds a new process to the scheduler, returning its ID. The extra data is the null-terminated path of the program to start.
-
-### `/process/self`
-
-The `/process/self` subdirectory provides information about as well as control
-interfaces to the calling process and thread.
-
-* `/process/self/terminate`: A [hook](#hook) that terminates the current thread. The extra data is ignored. This is likely to be made more powerful in the future.
-* `/process/self/id`: A [hook](#hook) that returns the ID of the current process. The extra data is ignored.
-* `/process/self/thread_id`: A [hook](#hook) that returns the ID of the current thread within the current process. The extra data is ignored.
-
-Interaction from U-mode
-=======================
-
-VFS resources are provided or accessed using
-[system calls](/md/srvre/kernel/wiki/syscalls.md):
-
-* [open](/md/srvre/kernel/wiki/syscalls.md#open-100001): Opens a resource, obtaining a resource descriptor handle.
-* [close](/md/srvre/kernel/wiki/syscalls.md#close-100002): Closes a resource descriptor handle.
-* [provideStream](/md/srvre/kernel/wiki/syscalls.md#providestream-100003): Provides a stream resource.
-* [provideFile](/md/srvre/kernel/wiki/syscalls.md#providefile-100004): Provides a file resource.
-* [provideHook](/md/srvre/kernel/wiki/syscalls.md#providehook-100005): Provides a hook resource.
-* [mkdir](/md/srvre/kernel/wiki/syscalls.md#mkdir-100006): Creates a kernel-managed directory.
-* [provideDirHook](/md/srvre/kernel/wiki/syscalls.md#providedirhook-100007): Provides a directory hook.
-* [remove](/md/srvre/kernel/wiki/syscalls.md#remove-100008): Removes a resource from the VFS.
-* [read](/md/srvre/kernel/wiki/syscalls.md#read-100009): Reads from a resource descriptor handle into a buffer.
-* [write](/md/srvre/kernel/wiki/syscalls.md#write-100010): Writes to a resource descriptor handle from a buffer.
-
-[Return to Wiki Main Page](/md/srvre/kernel/wiki.md)
-
-[Return to Index Page](/md/index.md)