K42 is structured around a client-server model (see Figure 2). The kernel is one of the core servers, currently providing memory management, process management, inter-process communication (IPC) infrastructure, base scheduling, networking, device support, etc. (In the future we plan to move networking and device support into user-mode servers).
Above the kernel are applications and system servers, including the NFS file server, name space server, socket server, pty server, and pipe server. For flexibility, and to avoid IPC overhead, we implement as much functionality as possible in application-level libraries. For example, all thread scheduling is done by a user-level scheduler linked into each process.
All layers of K42, the kernel, system servers, and user-level libraries, make extensive use of object-oriented technology. All IPC is between objects in the client and server address spaces. We use a stub compiler with decorations (additional keywords) on the C++ class declarations to automatically generate IPC calls from a client to a server. The kernel provides the basic IPC transport and attaches sufficient information for the server to provide authentication on those calls, including specific identification of the client being granted access. We have optimized the IPC path as described in Gamsa et. al. [12] and obtained good performance via efficient IPCs similar to L4[20].
From an application's perspective, K42 supports the Linux API and ABI. This is accomplished by an emulation layer that implements Linux system calls by method invocations on K42 objects. When writing an application to run on K42, it is possible to program to the Linux API or directly to the native K42 interfaces. All applications, including servers, are free to reach past the Linux interfaces and call the K42 interfaces directly. Programming against the native interfaces allows the application to take advantage of K42 optimizations.
The translation of standard Linux system calls is done by intercepting glibc system calls and directing them to their K42 implementation, as described in Section 4.1. Although Linux is the first and currently only personality we support, the base facilities of K42 were designed to be personality-independent. As mentioned in the introduction K42 also supports a Linux-kernel internal personality allowing us to use the large code base of drivers, networking, and file-system code.