Jimix
Note: This project is discontinued in favour of Pedigree.
Jimix is a hobby operating system, designed for the x86 and possibly x86-64/ia64 architectures.
It is written almost entirely in C++, with some assembly. The user application interface is POSIX compliant - actually implemented as a wrapper around the object-orientated native API.
Application programming interface
The native system call API revolves around 'resources'. Many kernel classes such as Files, Processes and MemoryMaps inherit from the Resource kernel class, which enables exposing of an interface to user programs.
The Resource class has a function which adds a function to its interface. It accepts any member function of a class which inherits from the abstract class Callable. The function is also given a numeric ID, and is referenced as such from userspace. Usually these IDs are hardcoded in a namespace definition, for example:
{
const int execve =0;
const int createFileDescriptor =1;
const int destroyFileDescriptor=2;
const int getFileDescriptor =3;
const int getPid =4;
const int sbrk =5;
const int waitPid =6;
const int setErrnoAddress =7;
const int setProcessPtrAddress =8;
const int exit =9;
const int getMessageSender =10;
const int getCtty =11;
const int initialiseSignals =12;
const int setCtty =13;
}
Once a Resource object is created it itself is given a numeric ID which can be passed between kernel and user space. It is this that allows object orientated system calls (albeit without C++'s syntax sugar).
Interprocess communication
Staying with the object oriented theme, IPC is done through a remote method invocation-style mechanism. User processes can create "Resources", just like inside the kernel. The only difference is that these objects are actually implicitly created using a subclass of Resource - RemoteResource. It stores the PID of the creating process. When functions are added to it (Any member functions of a subclass of Callable) they, again, take an ID. If another process is given a RemoteResource ID, it can call functions on it just as if it were a kernel syscall resource. Implicitly the kernel stores the parameters given and executes the given function in the resource creator's address space, just as a signal handler would in a linux implementation.