Repository navigation
Services
Three userspace services currently exist: console, exy-vfs, and
echo. All follow the same pattern: receive an ATTACH on the
bootstrap channel with a reply channel as a capability, then loop
serving requests.
Source: src/userspace/console/main.c.
Headers: src/userspace/include/exyde/console_rpc.h,
console_client.h. Client lib: libc/console_client.c.
The console server wraps the kernel's KPUTS primitive. It exists
so that when real device drivers arrive, the console can be
repointed without touching every writer. For now it is a thin
passthrough.
RPC ops:
CONSOLE_OP_ATTACH client -> server: register ch_resp
CONSOLE_OP_WRITE client -> server: bytes to print
CONSOLE_OP_READ client -> server: read (returns 0 = EOF)
CONSOLE_OP_SHUTDOWN ask the server to exit
Two channels: ch_req (client → server) and ch_resp
(server → client). Same pattern as VFS.
The libc write(1/2, ...) path uses the console server when it is
attached and falls back to SYS_KPUTS otherwise. read(0, ...)
returns -EBADF without a live console.
Orderly shutdown matters: if the client closes ch_req while the
server is blocked on IPC_RECV, the channel's destructor panics.
init therefore calls console_client_shutdown() and waits for
the child before exiting.
Source: src/userspace/vfs/.
Headers: src/userspace/include/exyde/vfs_rpc.h,
vfs_client.h. Client lib: libc/vfs_client.c and
libc/vfs_fdtab.c.
The server holds a RAMFS tree and a table of open files. Clients
get a small integer fd back from OPEN; subsequent READ /
WRITE / CLOSE / SEEK use it.
RPC ops:
VFS_OP_ATTACH client -> server: register ch_resp
VFS_OP_OPEN path, flags, mode -> fd
VFS_OP_CLOSE fd -> 0
VFS_OP_READ fd, len -> bytes
VFS_OP_WRITE fd, bytes -> bytes
VFS_OP_SEEK fd, offset, whence -> new offset
VFS_OP_MKDIR path, mode -> 0
VFS_OP_UNLINK path -> 0
VFS_OP_RMDIR path -> 0
VFS_OP_READDIR fd, index, name -> 0 / -ENOENT
VFS_OP_SHUTDOWN () -> 0
The request and response structs are fixed-size (vfs_req,
vfs_rsp) and fit in a single IPC_MSG_SIZE_MAX == 1024 message.
libc/vfs_client.c exposes:
vfs_client_init(ch_req, ch_resp)
vfs_client_open / close / read / write / seek
vfs_client_mkdir / unlink / rmdir / readdir
vfs_client_shutdown
Every public entry point checks that vfs_client_init has been
called and returns -1 with ENOSYS otherwise. A program that
never touches VFS gets a clean error instead of a crash.
libc/vfs_fdtab.c keeps a per-process table mapping local fds
(>= 3) to server-side fds. open, read, write, close,
lseek in libc/unistd.c branch on the fd number:
-
fdin[0, 3)— stdio. Console RPC orSYS_KPUTS. -
fd >= 3— local table lookup + VFS RPC. -
open()always goes through VFS.
Source: src/userspace/echo/echo.c.
Minimal service: receives a fixed-size message, sends the same
message back. Exits on the literal string quit. Used by init
and by the SPAWN_ELF test.
- Create
src/userspace/<name>/main.c. - In
main, get the bootstrap handle withexyde_get_bootstrap(), receiveATTACHon it, extract the reply channel from the capability field, and enter your RPC loop. - Add the binary to
userspace/Makefile. - Add it to
tools/mkinitrd.sh's program list so it lands in the initrd asbin/<name>. - In
init.c, callspawn_from_initrd("bin/<name>", "<name>", ch)and wire up a client.
The kernel is not touched. Services are pure userspace.