MMotor OS
System

Architecture

Motor OS is a microkernel system. The kernel manages memory, threads, scheduling, capabilities, and wait/wake objects. One userspace process, sys-io, owns the devices, the filesystem, and the network stack. A per-process runtime object, rt.vdso, implements the system interface that Rust's standard library calls.

  +----------------------------------------------------------------------+
  |  programs: rush, russhd, httpd, red, rmux, your code ...              |
  |     Rust std  ->  moto-rt  ->  rt.vdso (allocator, fs and net clients,|
  |                                 spawn, threads, futex, poll, stdio)   |
  +----------------------------------------------------------------------+
        | io_channel (shared memory rings)        | bounded IPC
        v                                         v
  +----------------------------+   +-----------+  +--------------+  +--------+
  | sys-io                     |   | sys-init  |  | dns-resolver |  | strobe |
  |  virtio-blk  virtio-net    |   | sys-tty   |  +--------------+  +--------+
  |  Motor FS    moto-netstack |   +-----------+
  +----------------------------+
        | syscalls (4 of them)
        v
  +----------------------------------------------------------------------+
  |  kernel: address spaces, paging, threads, scheduler, capabilities,    |
  |          wait/wake objects, shared memory, IRQ routing, serial log    |
  +----------------------------------------------------------------------+

Boot

Under QEMU the VM boots from an MBR boot sector; under Cloud Hypervisor and Firecracker it boots via PVH. Either way a small loader brings the CPUs up in 64-bit mode and loads the kernel from the initrd into high memory (hence "himem kernel"), at a fixed address with no address randomization. The initrd also carries sys-io; the kernel loads it as the first process, with every capability, and halts the machine if it ever exits. sys-io initializes the VirtIO devices, mounts the filesystem, and starts sys-init, which reads /system/cfg/sys-init.cfg and starts strobe, the configured services, and the console.

The kernel

The kernel is about 18,600 lines of no_std Rust for x86-64, under src/sys/kernel. It contains no drivers other than the serial port, no filesystem, no network code, and no program loader. What it does:

The syscalls

There are four syscalls, each with a small set of operations selected by an argument. Userspace names kernel objects with a SysHandle; a few handles are predefined (SELF, PARENT, KERNEL, and so on).

SyscallOperations
SysObjCreate an object from a URL (address_space, process, shared memory, ipc_pair, irq_wait, serial_console); look up or connect to an object; drop or duplicate a handle; query a handle (is it waitable, is the peer connected, the peer's PID and capabilities).
SysMemMap and unmap memory: heap, reservations, shared and cross-address-space mappings, and, for the I/O manager only, MMIO and physically contiguous memory; query memory and admission statistics.
SysCpuWait on up to N handles with an optional deadline; wake a handle or a thread; spawn a thread; exit; kill a child; query per-CPU usage; set thread affinity.
SysRayObservability: list processes, describe and read metrics, write a log record (needs CAP_LOG), and the debugger interface.

The Rust definitions are in src/sys/lib/moto-sys. Most programs never see them: they use Rust's standard library, and the runtime below it makes the calls.

sys-io

sys-io is the I/O manager. It is one process that owns every VirtIO device, provides the filesystem service, and provides the network service. All of its work runs as tasks on a single-threaded asynchronous runtime, moto-async, on one thread pinned to CPU 0, where the device interrupts are routed; there are no locks in its hot paths. Two small helper threads answer synchronous statistics queries.

Programs talk to sys-io over io_channel, a shared-memory channel inspired by io_uring: a submission ring and a completion ring of 64 entries each, with 64 pages of buffer space per direction split into four sub-channels, and kernel wait handles for cross-process wakeups. The wire definitions live in moto-sys-io; the native client library is moto-io, and rt.vdso uses them on behalf of std. Because the kernel allows a process at most 1024 wait handles, sys-io serves at most 960 channels, at most 896 per kind (filesystem or network); at four sub-channels per network channel that is roughly 3,500 concurrent sockets per machine.

If a client misbehaves on its channel, sys-io drops that client. If sys-io itself exits or is killed, the kernel logs its status and halts the VM: sys-io holds live filesystem and network state that cannot be rebuilt safely by a replacement, so a clear stop is preferred over a partial restart.

The services

ServiceRole
sys-initReads /system/cfg/sys-init.cfg: a tty: line (required) names the console program and its role, strobe: names the logging service, and svc:CAPS:COMMAND lines start services with an explicit capability mask. It starts strobe first, then the services, then the console.
sys-ttyThe serial console: a polled 16550 UART, driven as a byte pump. It starts the console shell (rush) with the environment from /system/cfg/sys-tty.cfg.
strobeLogging and the metrics registry. Services send log records over IPC through moto-log; strobe writes /system/logs/TAG.log and rotates to .prev. Userspace metric providers register with it so that collectors such as sysbox stats can find them.
dns-resolverA bounded IPC service that resolves names over UDP with TCP fallback; runs with the None role (see DNS resolver).
russhdThe SSH server: password and public-key authentication, shells, command execution, and SFTP; runs with the Interactive role.

rt.vdso and moto-rt

Motor OS has no dynamic linking, but it does have one shared component. The runtime, rt.vdso, is a position-independent ELF object that the spawning process maps into every new process at a fixed address, together with a one-page table of function pointers. Rust's standard library on Motor OS is deliberately thin: it calls moto-rt, a small crate that mostly forwards to that table. The runtime can therefore be updated with the OS, and already-compiled programs pick up the new version on their next start. The table is versioned (RT_VERSION, currently 17, matching moto-rt 0.17.x).

rt.vdso is where most of what a Unix kernel would do in system calls actually happens:

Programs are statically linked x86-64 ELF executables with no interpreter and no ELF TLS segment; thread-local storage is provided by the runtime. Anything that needs a Motor-specific interface, for example a service that wants to know a peer's capabilities, uses moto-sys or moto-rt directly.

Where things are in the source tree

PathContents
src/bootMBR boot sector, second-stage loader, and the kernel loader.
src/sys/kernelThe kernel.
src/sys/sys-ioThe I/O manager; netstack/ is the networking stack.
src/sys/sys-init, sys-tty, strobe, dns-resolverThe services.
src/sys/libSystem libraries: moto-sys (syscalls), moto-rt and rt.vdso (the runtime), moto-ipc (io_channel, pipes), moto-io and moto-sys-io (sys-io clients and wire formats), motor-fs and async-fs, virtio-async, moto-async, moto-dns, moto-log, moto-stats, moto-mpmc, frusa, moto-rt-cabi (the C ABI shim under the C library).
src/sys/toolssysbox (the commands) and mdbg.
src/sys/testsThe in-VM test suites.
src/binUser programs: rush, rmux, red, kibim, russhd, httpd, httpd-axum, curl, lorry, gears, rnetbench.
src/imagerThe image builder and the image descriptions.
src/vm_scriptsScripts to run VMs; copied next to the images.
src/testsThe host-driven test scripts, including full-test.sh.
img_filesStatic files placed into the images: configuration, scripts, this website.
docsDesign documents, plans, and recipes.

Size

Lines of Rust, including tests, as of August 2026: the kernel about 18,600; rt.vdso about 10,700; sys-io about 13,900 plus about 73,900 in the networking stack; Motor FS about 10,300; the VirtIO drivers about 3,400; moto-async about 2,800.