UX/RT - a Universally eXtensible Real-Time OS

Andrew Warkentin andreww591 at gmail.com
Thu Jan 29 02:39:36 CET 2015

More about UX/RT:

The most distinctive feature of UX/RT will be its nearly pure file-oriented
architecture. Under UX/RT, the only primitive APIs that won't operate on
files will be a few process-related ones like fork() and the threading API (of
course, direct access to L4 message passing will also be available, but no OS
services will use it outside the filesystem); even process memory like stack and
heap that is anonymous on other OSes will be in mapped memory-resident files on
UX/RT. The environment provided to applications will be a reasonably
standards-compliant Unix/POSIX environment with a few extensions (nearly all
the non-file-based "system calls" will be implemented as library functions that
access special files).

There will be no attempt to keep the root task "personality-neutral" (it will
implement a subset of the Unix API directly) and little support for coexisting
with other environments (there may be some limited support for running L4Linux
to support Linux-only drivers, although at least on PCs a lightweight hostless
Xen setup will be installed by default, and this will allow running Linux
driver domains on Xen so UX/RT probably won't have to go out of its way to be
able to support coexisting with L4Linux). There will however be support for
multiple "universes" that implement different variants of Unix-like environments
(kind of like some Unices of the late 80s and early 90s), although this will be
implemented using generic per-process binding of directories instead
of any special
support in the root task. The default universe will be partially based on BSD
commands and libraries (although some duplication of functionality in commands
will be removed and some commands will be split up). There will be a universe
that provides an environment that is binary compatible with Linux (which will be
easy enough to implement since UX/RT binaries will be built almost identically
to Linux ones, meaning that dynamically-linked binaries could be run by
providing a VDSO replacement that uses the UX/RT API, as opposed to trapping
Linux system calls). This would further reduce the need for co-hosting with
L4Linux. Also provided will be a universe that uses native libraries, but with
the default BSD-ish UX/RT base commands replaced with GNU ones.

The root task will contain the process manager and VFS, as well as a few
built-in special filesystems (it will be similar in scope to QNX's process
manager, except that it will be a separate program, rather than colocated in
the microkernel, of course). The VFS will be somewhat simpler than that of a
typical Unix, and will function mostly as a name service and memory mapping
layer (it will have no concept of devices at all, and filesystems will be
mounted from "ports", which will be special files used as communication channels
between file servers and the root task, much like the ones in Plan 9; this
means that UX/RT will not have device numbers, on-disk device nodes, or
Hurd-style translators). File descriptors will be mapped directly onto sets of
L4 capabilities and IPC gates, and read() and write() will bypass the VFS layer
entirely in most cases, and will call L4 IPC APIs to interact directly with the
target server (or client) process. read() and write() will always preserve
message boundaries and will never combine or split calls (similarly to
SOCK_SEQPACKET sockets on Linux), although some servers (like the disk
filesystems and network stack) will rearrange or ignore message boundaries
internally. Basically, as far as the VFS layer is concerned, a file will be a
stream of packets rather than a stream of bytes that can be broken up in
arbitrary places.

The other file system API functions (including mmap()) will call the root task.
There will be a tmpfs-like virtual memory filesystem built into the root task,
which will be used for both shared memory and for process-private memory
segments like the heap and stack (each process will get its own in-memory
filesystem in its /proc directory). Using mmap() on a file in an in-memory
filesystem with MAP_SHARED will map that file's pages directly into the
process's address space; mapping in-memory files with MAP_PRIVATE will create a
copy-on-write shadow file in the process's memory filesystem. Mapping
files that aren't in an in-memory filesystem will also create a shadow file that
is similar to the ones for private mappings of in-memory files, except that the
root task will use normal reads and writes to access the backing.

All of the low-level system call stuff will be in a library separate from libc,
which will translate basic Unix API functions into L4 messages. This library
will contain only low-level functions (read(), write(), and those implemented by
the root task and microkernel). The root task will use a permanent anonymous
file descriptor for APIs that don't operate on file descriptors. The default
libc will be forked from one of the BSDs (probably NetBSD); however, the Linux
compatibility environment will use glibc.

Similarly to Plan 9, there will be no ioctl() primitive that is implemented by
file servers, and out-of-band messages will be implemented with normal reads and
writes on separate files. However, there will be a pure library implementation
of ioctl() that will support some common types of device files, like terminals
(it will just use normal reads and writes; there will also be an ioctl_read()
function for servers that reads an ioctl request from an FD and splits it into
request type and payload and an ioctl_reply() function to send a reply).

Security will be implemented by having a per-process list of "file capabilities"
that specify which files the process can access and what kind of access is
permitted (these "capabilities" won't get translated into kernel capabilities
until the file gets open()ed). It will be possible for a file capability to
apply to all files in a particular directory. It will also be possible for file
capabilities to use the normal Unix permission bits in the filesystem for a
particular file or directory rather than explicitly specifying permissions.
Checking of file capabilities and translation of them into kernel capabilities
will be handled by the VFS layer in the root task, and manipulation of them will
be done through special files in /proc (meaning it will be possible to control
which processes can manipulate each other's file capabilities). There will be
no privileged system calls like virtually all other Unix-like OSes; all
privileged APIs will be implemented using special files.

I am planning to use a different boot process than that of L4Re or Genode.
It will be similar to QNX's boot process, but more flexible. All OS components
and configuration files required for booting, including the kernel, sigma0, and
proc (the root task) will be contained in a ROM filesystem image. There will be
an in-memory bootloader that reads a list of OS components from the image (the
image will contain some other files besides the ones in this list; only the
files required to get to the point where the image can actually be mounted will
be included in the list), sets up a modified version of a Multiboot table with
module addresses pointing at the modules in the boot image (this way, neither
the kernel nor the root task will have to be able to understand the filesystem
of the boot image), and sets up some initial page tables that map everything at
the correct virtual addresses. Read-only sections will be mapped in place, and
only writeable sections will ever be copied (although for the kernel, sigma0,
and the root task, which aren't going to be reused, it might make sense to map
everything in place except for the bss sections). I am planning to move the
option parsing, KIP initialization, and all the other L4-specific boot code into
the kernel so I can just use my own bootloader to boot it (my bootloader is
intended to be generic, although its variant of Multiboot has several
enhancements over the GRUB version and is designed for extensibility). Once the
root task is running, it will create a temporary filesystem from the Multiboot
module list and will run the init process (it will be like a cut-down System V
init). The init process will call the mount command to mount the real image
filesystem (init, mount, and the shared libraries they depend on will be
included in the boot module list), and after the image filesystem is mounted it
will run a set of more advanced service management daemons that manage the rest
of the boot process (probing for hardware, starting the required servers,
mounting the real disk- or network-based root filesystem, etc.).

The disk filesystem support and network stack will be based on the rump kernel
from NetBSD with some UX/RT-specific glue code added on top. For performance
reasons the disk drivers and disk filesystem drivers will run in one process
(there will probably be one process per host adapter); the network stack will
probably also run in a single process.

Initially I am just going to use Xorg (with a UX/RT-specific device file
transport) as the window system, but I will replace that with a lightweight
compositing window server, which will probably be partially based on
Weston or one of the other Wayland compositors, but with a completely
different protocol (which
will use a server-allocated special file for each surface rather than
client-allocated anonymous memory) and with any server-side window management
ripped out (my window system will use a conventional reparenting window manager
like X does; the window server will only handle event delivery and
low-level graphics operations). Of course X will still be available
even after I have my own window server working (there will be a
rootless X server available). The default desktop environment will be

What does everyone here think of my design? Would anyone here be interested in

On 1/28/15, Nils Asmussen <nils at os.inf.tu-dresden.de> wrote:
> Hash: SHA256
> Hi,
> as you want to build a UNIX-like microkernel-based OS, it might be
> interesting for you to look at my OS, Escape [1]. It is some mixture
> of UNIX, Plan 9 and L4, I would say. It is not directly related
> though, but completely written from scratch and also UNIX-like at its
> heart in contrast to emulating that on top. However, since it does not
> consider real-time, you probably don't want to use it, but perhaps
> it's interesting to see how it works.

I downloaded an older version of your OS a while back. Didn't really
look all that closely at the source though. I'll have to look at it a
bit closer, although its architecture seems to be rather different
from how UX/RT will be.

More information about the l4-hackers mailing list