Friday, June 9, 2017

Microkernel

Introduction

A microkernel provides only mechanisms: virtual memory management,  thread management, inter-process communications(IPC) and optionally scheduling that are needed to implement an operating system(OS), while OS functionalities, like devices driver, file system,  interrupts and network stack are implemented as services in user space.

Why Microkernel

  • Reliability: A major source of linux panic is device driver because it makes a large part of Linux kernel source and some are not written very carefully. By running it as services in user space, devices driver in false situation can be restarted without restarting the complete OS which is very helpful for high availability use cases.
  • Security: With services running in user space, access to privileged resources is restricted. Some also argued that minimality principle of microkernel is a direct consequence of principle of least privilege.
  • Realtime performance: With microkernel, kernel operations are few and short duration, keep use of locks at minimal level and lower scheduling latency. 
  • Debuggability: Since all services are running in user land, debugging a service is the same as debugging an application. 

Challenge of Microkernel

  • IPC: In monolithic systems, service is obtained with a system call which requires two kernel/user mode switches. In mircokernel systems, this requires four context switches plus overhead of user data copying.
  • Performance: Since all services, e.g. page fault handling, interrupt handling etc. are implemented as user space program, means of communications between server and client as well as context switch and scheduling latency are essential for microkernel system design.

Implementations

L4 Microkernel Family

L4 is a family of second generation microkernels including L4 kernel interface after its predecessor L3, which was developed by Jochen Liedtke as a response to poor performance of earlier microkernel-based operating systems.

L4 was written in assembly language. To prove that high performance could also be achieved with high level programming language, Liedtke started L4Ka::Hazelnut, a c++ version that supports IA-32 and ARM architectures.  L4Ka::Pistachio is a platform-independent implementation with new L4 API release.

L4/Fiasco is another c++ version implemented independently by TUD:OS of TU Dresden. It is fully preemptiable and used as a basis of hard real-time operating system. Its successor, Fiasco.OC is a third generation microkernel, characterised by a security-oriented API with resource access controlled by capabilities, virtualization as a first-class concern, novel approaches to kernel resource management[1].  NOVA is a virtualization environment running on x86 multi-core systems.

L4/MIPS and L4/Alpha are 64-bit implementations, developed by University of New South Wales(UNSW).  Later UNSW forked L4Ka::Pistachio into new version of NICTA::L4-embedded. OKL4 is a spinoff version from NICTA with focus on commercial use. OK Labs also owns seL4, a high assurance version which has achieved complete formal verification and thus gone beyond CC EAL 7. 

Figure 1: L4 family tree, from Wikipedia.

QNX Neutrino RTOS

This sections, however, will try to dig into implementation details. QNX Neutrino RTOS features open standards POSIX and messaged-based IPC.

POSIX threads and processes

A process contains one or more threads, which is the minimum unit of execution.  The threads share process's MMU-protected address space. Threads are scheduled globally and there are 256 ready queues, one for each priority. QNX Neutrino RTOS supports following scheduling algorithms[3]:

  • FIFO scheduling
  • round-robin scheduling
  • sporadic scheduling
It provides following primitives for synchronizing threads:
  • Mutexes
  • Condvars
  • Barriers
  • Sleepon locks
  • Reader/writer locks
  • Semaphores
  • FIFO scheduling
  • Send/Receive/Reply
  • Atomic operations
Synchronization can also be done by scheduling policies, message passing and atomic operations.

IPC

Message-passing

Message passing is synchronous which means that a thread that sends message with MsgSend will be blocked until the receiving thread does MsgReceive, processes the message and replies it. The message-passing primitive also supports multipart transfers which mean that the message itself doesn't have to in single, continuous buffer. Before passing a message, a sending thread needs to first make a connection attaching to a channel that is made available by a receiving thread. Message-passing is the primary form of IPC. Other forms of IPC are mostly based on Message-passing.
Figure 2: Client(top)/Server(bottom) states change in a send-receive-reply transaction[3]

Pulses

Pulse is a non-blocking notification mechanism that often used within interrupt handlers. A pulse carries a small, fixed size payload.

Mach Family

Mach is one of the earliest implementations of microkernels, developed by Carnegie Mellon University(CMU). Its derivatives are the basis of modern operating system kernels, e.g. GNU Hurd, iOS, MacOS etc. Mach was started as monolithic kernel on the base of BSD 4.2 kernel with an effort to produce a kernel with a short list of generic concepts: task, thread, port and message. A public release 1 was made in 1987 and release 2 next year.  A "true" microkernel Mach 3 was released in 1990 after moving UNIX layer out of the kernel into user space.

GNU Hurd consists of a set of protocols and services that runs on top of CMU's Mach 3. In 1994, Mach development was stopped at CMU.  GNU Hurd switched to Utah's Mach 4. Once the Mach 4 was discontinued, GNU Hurd's Mach was known as GNU Mach. There were also other efforts of porting GNU Hurd to other microkernels, e.g. L4, Coyotos. There are 24 services included in GNU Hurd[2].

XNU, stands for "X is Not Unix", is a modified "hybrid" Mach 3 kernel, with file system, network, process and memory management implemented in kernel space. XNU is the kernel for Apple's iOS, tvOS, watchOS and macOS. 

References

[1] Elkaduwe, Dhammika; Derrin, Philip; Elphinstone, Kevin (April 2008). "Kernel design for isolation and assurance of physical memory". 1st Workshop on Isolation and Integration in Embedded Systems. Glasgow, UK.
[2] "Preliminary GNU/Hurd User Interface Description". Debian. 2016-07-05. Retrieved 2017-06-10
[3] "QNX Neutrino RTOS System Architecture". (2014, Feb. 20). QNX Software Systems Limited.  Retrieved 2017-06-07, from http://support7.qnx.com/download/download/26183/QNX_Neutrino_RTOS_System_Architecture.pdf

No comments:

Post a Comment