Required reading: Improving IPC by kernel design


the microkernel vision
  implement main o/s abstractions as user-space servers
    files, tcp, process mgmt, paging
  kernel provides minimum to support servers
    address spaces
    inter-process communication (IPC)
why attractive?
  (compared to monolithic UNIX-style design)
  isolation (vs bugs)
  fault-tolerant (restart individual services)
  modular (understandable, replaceable services)
  easier to distribute (IPC allows services on other hosts)
  easier to run on multiprocessor (since many servers)
  individual ideas around since the beginning
  lots of research projects starting early 1980s
  hit the big time w/ CMU's Mach in 1986
  thought to be too slow in early 1990s
  now slowly returning (OSX, QNX in Cisco, &c)
  ideas very influential on non-microkernels
Mach overview
  (today's L3 paper very much a reaction to Mach)
  ambitious: multiprocessors, distrib systems
  multiple threads in process / address space
    as a style of programming
    i/o concurrency; multi-processors
    fetching a web page with many images?
      browser creates a thread for each (fetch, decode jpeg)
    Mach did a lot to popularize this style
    "port" an independent kernel abstraction
    send to port, recv from port
    a port queues messages, waiting for someone to read
    processes have rights to send/recv from ports
    can send send or recv right for port via IPC msg
      so can't tell at send time who will recv
  process control via ports
    process creation gives parent "kernel port" to empty process
    IPC messages to map mem, create threads, stop, start, wait()
    parent can give away child's kernel port
    thus wait() not tied only to parent
    easy to write e.g. debugger
  paging via ports
    goal: move most of VM / memory mgmt out of the kernel
    an address space consists of mapped "memory objects"
      object is a file or anonymous disk-backed memory
    each object implemented by a server
      handles page faults that refer to that object
      kernel gives it an offset, it returns page content
    kernel keeps object / virtual address table for each process
      that's the real address space
    model: process LD/ST operates on mem objs; VM decides which obj
      hardware doesn't let us directly turn LD into an IPC msg
      but can mark pages invalid to detect LDs and STs
      so use page faults and caching in physical memory
  how to build full systems on Mach?
    goal was general-purpose O/S for servers and workstations
    huge issue: UNIX compatibility
      critical to widespread adoption
    split UNIX kernel code into many servers?
      too hard, design is fairly non-modular
      so they left UNIX as a single entity
    mostly new services as servers
      e.g. network file system, window system, pagers, LAN IPC, name servers
      my Mach-based OSX Mac has dozens of servers, 100s of ports
    Mach 2.5: 
      left UNIX in kernel, mostly unchanged
      so micro- and UNIX side-by-side in kernel
    Mach 3.0:
      UNIX in a big server process
      forward UNIX system calls via IPC
  big problem: Mach 3.0 was slow
    high cost of sending syscalls via IPC
    result: many people decided microkernels were a bad idea

L3/L4 Overview

partially an attempt to see if Mach 3.0 slowness was inherent
  or an accident of design / implementation
L3 used for education and embedded systems
L4 a more modern re-implementation
  has associated user-space Linux port (not a VM...)
  can fetch from sourceforge
just seven system calls!
  can send page mappings
  this the only way to set up address space
task creation
  creates fixed # of threads
task/thread manipulation
  can set/get PC, SP, state, &c
  need capability, initially granted to task creator

L3/L4 paper discussion