diff --git a/doc/PlatformDesignStory.md b/doc/PlatformDesignStory.md
new file mode 100644
index 0000000..0632494
--- /dev/null
+++ b/doc/PlatformDesignStory.md
@@ -0,0 +1,572 @@
+`libtock_platform` Design Story
+===============================
+
+Note: At the time of this writing, `libtock_platform` is still a work in
+progress that exists largely in @jrvanwhy's head.
+
+`libtock_platform` is a crate that will contain core abstractions that will be
+used by `libtock_core`'s drivers. For example, it will contain abstractions for
+asynchronous APIs that are lighter weight (in terms of code size and RAM usage)
+than Rust's futures.
+
+This document serves as a justification for, and explanation of, the high-level
+design of `libtock_platform`. Instead of describing the various components and
+how they interact, it starts with a hello world application and extracts some of
+the functionality out into a reusable library. As we do so, we see that
+`libtock_core`'s [design considerations](DesignConsiderations.md) lead
+incrementally to a design for `libtock_platform`.
+
+In order to keep things understandable, this document makes several
+simplifications. Error handling logic is omitted, although we still structure
+the code so as to allow it. We use `unsafe` in places where we should instead
+have an additional, safe, abstraction. We use a simplified form of the Tock 2.0
+system calls, which are currently undergoing design revisions.
+
+## Hello World
+
+We start with the following example app. In order to show how `libtock_platform`
+will handle asynchronous callbacks, it is written in an asynchronous manner.
+
+```rust
+#![no_std]
+
+static GREETING: [u8; 7] = *b"Hello, ";
+static NOUN: [u8; 7] = *b"World!\n";
+static mut DONE: bool = false;
+
+// Driver, command, allow, and subscription numbers.
+const DRIVER: usize = 1;
+const WRITE_DONE: usize = 1;
+const WRITE_BUFFER: usize = 1;
+const START_WRITE: usize = 1;
+
+fn main() {
+    libtock_runtime::subscribe(DRIVER, WRITE_DONE, write_complete, 0);
+    libtock_runtime::const_allow(DRIVER, WRITE_BUFFER, &GREETING);
+    libtock_runtime::command(DRIVER, START_WRITE, GREETING.len(), 0);
+    loop {
+        libtock_runtime::yieldk();
+    }
+}
+
+extern "C" fn write_complete(bytes: usize, _: usize, _: usize, _data: usize) {
+    // Detect if this write completion is a result of writing NOUN (the
+    // second write). If so, return immediately to avoid an infinite loop.
+    unsafe {
+        if DONE { return; }
+        DONE = true;
+    }
+    // At this point, we just finished writing GREETING and need to write NOUN.
+    libtock_runtime::const_allow(DRIVER, WRITE_BUFFER, &NOUN);
+    libtock_runtime::command(DRIVER, START_WRITE, NOUN.len(), 0);
+}
+```
+
+Strictly speaking, in this app, `DONE` could be tracked by passing it as the
+`data` argument to `subscribe`. However, most applications will need to track
+more than 32 bits of persistent state -- and use more than one callback -- so
+they will need to manage persistent state themselves. To make this app
+representative of most apps, we keep the state in userspace memory.
+
+This example assumes that the `libtock_runtime` crate exposes system call
+implementations that look like the following (these are a simplification of the
+Tock 2.0 system calls):
+
+```rust
+pub fn subscribe(driver_num: usize,
+                 subscription_num: usize,
+                 callback: extern "C" fn(usize, usize, usize, usize),
+                 data: usize);
+
+pub fn const_allow(driver_num: usize, buffer_num: usize, buffer: &'static [u8]);
+pub fn command(driver_num: usize, command_num: usize, arg1: usize, arg2: usize);
+pub fn yieldk();
+```
+
+What do we already get "right" in this example? Except for the two intentional
+inefficiencies explained above (performing the write in two steps rather than 1
+and maintaining the `DONE` state in process memory), it is very efficient. It
+has only 3 global variables: `GREETING`, `NOUN`, and `DONE`. It has almost zero
+bookkeeping overhead; it fairly directly makes 8 system calls (`subscribe`,
+`const_allow`, `command`, `yieldk`, `const_allow`, `command`, `yieldk`,
+`yieldk`).
+
+What do we want to improve? It calls system calls directly from application code
+-- there should be a reusable `console` library that implements the system calls
+instead! The application shouldn't need to know what command number starts a
+write, it should just tell the console driver to do that for it.
+
+## Adding a Console Library
+
+Let's start taking some of the console-specific parts and moving them into a new
+crate. The first system call the app makes is to `subscribe` to the write done
+callback, so let's add a function to a new `libtock_console` crate that sets a
+write callback using `subscribe`:
+
+```rust
+#![no_std]
+
+const DRIVER: usize = 1;
+const WRITE_DONE: usize = 1;
+
+fn set_write_callback(callback: fn(bytes: usize, data: usize), data: usize) {
+    libtock_runtime::subscribe(DRIVER, WRITE_DONE, write_complete, data);
+    // We need to store `callback` somewhere -- where to do so?
+}
+
+extern "C" fn write_complete(bytes: usize, _: usize, _: usize, data: usize) {
+    // Hmm, how do we access the callback?
+}
+```
+
+You may notice that the code is not quite complete: `set_write_callback` takes a
+callback but doesn't store it anywhere. We don't want to store it in a global
+variable because doing so would not be zero-cost: the original app didn't need
+to store a function pointer, and we want to do this refactoring without bloating
+the app. We could pass it through `data`, but what if the client code needs to
+use `data` itself? That pattern isn't extensible: if there is another
+asynchronous layer about the console (e.g. a virtualization system), it won't
+have access to `data` to pass its callbacks through.
+
+Instead, we can pass the callback through the type system. We need a new trait
+to represent the callback. This trait won't be specific to `libtock_console`,
+and we'll later use it in unit tests -- which run on Linux, not Tock, so we'll
+put it in the `libtock_platform` crate:
+
+```rust
+pub trait FreeCallback<AsyncResponse> {
+    fn call(response: AsyncResponse);
+}
+```
+
+We call this `FreeCallback` because it represents a free function as opposed to
+a method. (This forshadows `MethodCallback`, which we will need later)
+
+The reason why we made this a shared generic trait rather than adding a
+`libtock_console::Client` trait as the Tock kernel does will be apparent later.
+
+Using this trait, we can now write `libtock_console::set_write_callback`:
+
+```rust
+#![no_std]
+
+use libtock_platform::FreeCallback;
+
+const DRIVER: usize = 1;
+const WRITE_DONE: usize = 1;
+
+pub struct WriteCompleted {
+    pub bytes: usize,
+    pub data: usize,
+}
+
+pub fn set_write_callback<Callback: FreeCallback<WriteCompleted>>(data: usize) {
+    libtock_runtime::subscribe(DRIVER, WRITE_DONE, write_complete::<Callback>, data);
+}
+
+extern "C" fn write_complete<Callback: FreeCallback<WriteCompleted>>(
+    bytes: usize, _: usize, _: usize, data: usize)
+{
+    Callback::call(WriteCompleted { bytes, data });
+}
+```
+
+To finish `libtock_console`, we also need to add `set_write_buffer` (which calls
+`allow`) and `start_write` (which calls `command`), which are much simpler:
+
+```rust
+const WRITE_BUFFER: usize = 1;
+const START_WRITE: usize = 1;
+
+pub fn set_write_buffer(buffer: &'static [u8]) {
+    libtock_runtime::const_allow(DRIVER, WRITE_BUFFER, buffer);
+}
+
+pub fn start_write(bytes: usize) {
+    libtock_runtime::command(DRIVER, START_WRITE, bytes, 0);
+}
+```
+
+We can then make use of `libtock_console` in our app as follows:
+
+```rust
+#![no_std]
+
+static GREETING: [u8; 7] = *b"Hello, ";
+static NOUN: [u8; 7] = *b"World!\n";
+static mut DONE: bool = false;
+
+fn main() {
+    libtock_console::set_write_callback::<App>(0);
+    libtock_console::set_write_buffer(&GREETING);
+    libtock_console::start_write(GREETING.len());
+    loop {
+        libtock_runtime::yieldk();
+    }
+}
+
+struct App;
+
+impl libtock_platform::FreeCallback<libtock_console::WriteCompleted> for App {
+    fn call(_response: WriteCompleted) {
+        unsafe {
+            if DONE { return; }
+            DONE = true;
+        }
+        libtock_console::set_write_buffer(&NOUN);
+        libtock_console::start_write(NOUN.len());
+    }
+}
+```
+
+Now we have a reusable console library! However, we still don't have any unit
+tests.
+
+## Adding a Fake Kernel
+
+A good unit test for the console driver would test not only the driver's
+operation with successful system calls but also also test the driver's
+error-handling logic. That is difficult to do if we test using a real Tock
+kernel in an emulator -- the real kernel has the goal of avoiding system call
+errors! Instead of using a real Tock kernel, driver unit tests should use a
+"fake kernel" that simulates the kernel's functionality while allowing errors to
+be injected.
+
+To keep this document reasonably short and understandable, we have omitted error
+handling, but we can still structure our unit tests in a manner that would allow
+a test to inject errors when error handling logic is added.
+
+To allow the console driver to work with both a real kernel and a fake kernel,
+we add a `Syscalls` trait to `libtock_platform`. When compiled into a Tock
+process binary, `Syscalls` will be implemented by a zero-sized type, which
+avoids wasting non-volatile storage space or RAM area. To avoid passing around
+references to a `Syscalls` implementation, we can pass the `Syscalls` by value
+rather than by reference (i.e. take `self` rather than `&self`). For practical
+use, this requires the `Syscalls` implementations to be `Copy`.
+
+```rust
+pub trait Syscalls: Copy {
+    fn subscribe(self, driver: usize, minor: usize,
+                 callback: extern "C" fn(usize, usize, usize, usize),
+                 data: usize);
+
+    fn const_allow(self, major: usize, minor: usize, buffer: &'static [u8]);
+    fn command(self, major: usize, miner: usize, arg1: usize, arg2: usize);
+    fn yieldk(self);
+}
+```
+
+We then implement `Syscalls` using a real Tock kernel in `libtock_runtime`:
+
+```rust
+#[derive(Clone, Copy)]
+pub struct TockSyscalls;
+
+impl libtock_platform::Syscalls for TockSyscalls {
+    /* Omitted implementation details */
+}
+```
+
+We adapt `libtock_console` to use an app-provided `Syscalls` implementation
+rather than directly calling into `libtock_runtime`:
+
+```rust
+pub fn set_write_callback<S: Syscalls, Callback: FreeCallback<WriteCompleted>>(
+    syscalls: S, data: usize)
+{
+    syscalls.subscribe(1, 1, write_complete::<Callback>, data);
+}
+
+extern "C" fn write_complete<Callback: FreeCallback<WriteCompleted>>(
+    bytes: usize, _: usize, _: usize, data: usize)
+{
+    Callback::call(WriteCompleted { bytes, data });
+}
+
+pub fn set_write_buffer<S: Syscalls>(syscalls: S, buffer: &'static [u8]) {
+    syscalls.const_allow(1, 1, buffer);
+}
+
+pub fn start_write<S: Syscalls>(syscalls: S, bytes: usize) {
+    syscalls.command(1, 1, bytes, 0);
+}
+```
+
+We'll create a new crate, `libtock_unittest`, which contains test utilities such
+as the fake Tock kernel. The fake kernel, unlike
+`libtock_runtime::TockSyscalls`, needs to maintain state, so it cannot be a
+zero-sized type. Instead of implementing `Syscalls` on the fake kernel directly,
+we implement it on a shared reference:
+
+```rust
+type RawCallback = extern "C" fn(usize, usize, usize, usize);
+
+pub struct FakeSyscalls {
+    callback_pending: core::cell::Cell<Option<usize>>,
+    output: core::cell::Cell<Vec<u8>>,
+    write_buffer: core::cell::Cell<Option<&'static [u8]>>,
+    write_callback: core::cell::Cell<Option<RawCallback>>,
+    write_data: core::cell::Cell<usize>,
+}
+
+impl FakeSyscalls {
+    pub fn new() -> Self {
+        FakeSyscalls {
+            callback_pending: Cell::new(None),
+            output: Cell::new(Vec::new()),
+            write_buffer: Cell::new(None),
+            write_callback: Cell::new(None),
+            write_data: Cell::new(0),
+        }
+    }
+
+    pub fn read_buffer(&self) -> &'static [u8] {
+        self.write_buffer.take().unwrap_or(&[])
+    }
+}
+
+impl libtock_platform::Syscalls for &FakeSyscalls {
+    fn subscribe(self, driver: usize, minor: usize, callback: RawCallback, data: usize) {
+        if driver == 1 && minor == 1 {
+            self.write_callback.set(Some(callback));
+            self.write_data.set(data);
+        }
+    }
+
+    fn const_allow(self, major: usize, minor: usize, buffer: &'static [u8]) {
+        if major == 1 && minor == 1 {
+            self.write_buffer.set(Some(buffer));
+        }
+    }
+
+    fn command(self, major: usize, minor: usize, arg1: usize, _arg2: usize) {
+        if major != 1 || minor != 1 { return; }
+        if let Some(buffer) = self.write_buffer.get() {
+            let mut output = self.output.take();
+            let bytes = core::cmp::min(arg1, buffer.len());
+            output.extend_from_slice(&buffer[..bytes]);
+            self.output.set(output);
+            self.callback_pending.set(Some(bytes));
+        }
+    }
+
+    fn yieldk(self) {
+        let bytes = match self.callback_pending.take() {
+            Some(bytes) => bytes,
+            None => return,
+        };
+        if let Some(callback) = self.write_callback.get() {
+            callback(bytes, 0, 0, self.write_data.get());
+        }
+    }
+}
+```
+
+## Adding a Synchronous Adapter
+
+We're still not ready to add unit tests to `libtock_console` yet!
+`libtock_console` is asynchronous, which is difficult to work with in a unit
+test. `libtock_core` should provide synchronous APIs for apps that do not wish
+to be fully asynchronous, so lets go ahead and implement a synchronous API. To
+avoid re-implementing synchronous APIs for every driver, let's make it work
+generically with all `libtock_core` drivers. This is where we benefit from
+making `FreeCallback` a generic trait rather than having a
+`libtock_console::Client` trait.
+
+The synchronous adapter will need to store a copy of an `AsyncResponse`, so its
+callback cannot be a free function (it needs access to `self`). Therefore, we
+add the `MethodCallback` trait to `libtock_platform`:
+
+```rust
+pub trait MethodCallback<AsyncResponse> {
+    fn call(&self, response: AsyncResponse);
+}
+```
+
+Using `MethodCallback`, we can now write `SyncAdapter`. We add `SyncAdapter` to
+a new crate, `libtock_sync`, as not all Tock apps will want it:
+
+```rust
+use libtock_platform::MethodCallback;
+
+pub struct SyncAdapter<AsyncResponse, Syscalls> {
+    response: core::cell::Cell<Option<AsyncResponse>>,
+    syscalls: Syscalls,
+}
+
+impl<AsyncResponse, Syscalls> SyncAdapter<AsyncResponse, Syscalls> {
+    pub const fn new(syscalls: Syscalls) -> SyncAdapter<AsyncResponse, Syscalls> {
+        SyncAdapter { response: core::cell::Cell::new(None), syscalls }
+    }
+}
+
+impl<AsyncResponse, Syscalls: libtock_platform::Syscalls> SyncAdapter<AsyncResponse, Syscalls> {
+    pub fn wait(&self) -> AsyncResponse {
+        loop {
+            match self.response.take() {
+                Some(response) => return response,
+                None => self.syscalls.yieldk(),
+            }
+        }
+    }
+}
+
+impl<AsyncResponse, Syscalls: libtock_platform::Syscalls>
+MethodCallback<AsyncResponse> for SyncAdapter<AsyncResponse, Syscalls> {
+    fn call(&self, response: AsyncResponse) {
+        self.response.set(Some(response));
+    }
+}
+```
+
+## Adding a Unit Test
+
+Before we write the test itself, we should add one more utility to
+`libtock_unittest`. That utility is the `test_component!` macro, which creates a
+thread-local instance of a type and provides `FreeCallback` implementations for
+every `MethodCallback` implementation the type has:
+
+```rust
+#[macro_export]
+macro_rules! test_component {
+    [$link:ident, $name:ident: $comp:ty = $init:expr] => {
+        let $name = std::boxed::Box::leak(std::boxed::Box::new($init)) as &$comp;
+        std::thread_local!(static GLOBAL: std::cell::Cell<Option<&'static $comp>>
+                           = std::cell::Cell::new(None));
+        GLOBAL.with(|g| g.set(Some($name)));
+        struct $link;
+        impl<T> libtock_platform::FreeCallback<T> for $link
+        where $comp: libtock_platform::MethodCallback<T> {
+            fn call(response: T) {
+                GLOBAL.with(|g| g.get().unwrap()).call(response);
+            }
+        }
+    };
+}
+```
+
+We can finally add a unit test to `libtock_console`:
+
+```rust
+#[cfg(test)]
+mod tests {
+    #[test]
+    fn write() {
+        extern crate std;
+
+        use libtock_platform::MethodCallback;
+        use libtock_sync::SyncAdapter;
+        use libtock_unittest::FakeSyscalls;
+        use std::boxed::Box;
+        use std::thread_local;
+        use super::{set_write_buffer, set_write_callback, start_write, WriteCompleted};
+
+        let syscalls: &_ = Box::leak(Box::new(FakeSyscalls::new()));
+        libtock_unittest::test_component![SyncAdapterLink, sync_adapter: SyncAdapter<WriteCompleted, &'static FakeSyscalls>
+                                          = SyncAdapter::new(syscalls)];
+
+        set_write_callback::<_, SyncAdapterLink>(syscalls, 1234);
+        set_write_buffer(syscalls, b"Hello");
+        start_write(syscalls, 5);
+        let response = sync_adapter.wait();
+        assert_eq!(response.bytes, 5);
+        assert_eq!(response.data, 1234);
+        assert_eq!(syscalls.read_buffer(), b"Hello");
+    }
+}
+```
+
+## Adding `static_component!`
+
+We added `libtock_unittest::test_component!` to make it easy to set up
+components in unit tests, but we have no equivalent for apps. Our app still uses
+`unsafe` to access its `DONE` variable. Instead, lets hide that unsafety behind
+a new macro. This macro is only sound in `libtock_runtime`'s single-threaded
+environment, so we add it to `libtock_runtime` directly:
+
+```rust
+#[macro_export]
+macro_rules! static_component {
+    [$link:ident, $name:ident: $comp:ty = $init:expr] => {
+        static mut COMPONENT: $comp = $init;
+        struct $link;
+        impl<T> libtock_platform::FreeCallback<T> for $link
+        where $comp: libtock_platform::MethodCallback<T> {
+            fn call(response: T) {
+                unsafe { &COMPONENT }.call(response);
+            }
+        }
+    };
+}
+```
+
+We can now use `static_component!` in our Hello World app to instantiate the
+`App` struct:
+
+```rust
+#![no_std]
+
+static GREETING: [u8; 7] = *b"Hello, ";
+static NOUN: [u8; 7] = *b"World!\n";
+
+fn main() {
+    libtock_console::set_write_callback::<_, AppLink>(0);
+    libtock_console::set_write_buffer(&GREETING);
+    libtock_console::start_write(GREETING.len());
+    loop {
+        libtock_runtime::yieldk();
+    }
+}
+
+struct App {
+    done: core::cell::Cell<bool>
+}
+
+impl App {
+    pub const fn new() -> App {
+        App {
+            done: core::cell::Cell::new(false)
+        }
+    }
+}
+
+impl MethodCallback<WriteCompleted> for App {
+    fn call(&self, _response: WriteCompleted) {
+        if self.done.get() { return; }
+        self.done.set(true);
+        set_write_buffer(TockSyscalls, &NOUN );
+        start_write(TockSyscalls, NOUN.len() );
+    }
+}
+
+libtock_runtime::static_component![AppLink, APP: App = App::new()];
+```
+
+Now our app has no more unsafe!
+
+## Recap
+
+We wrote a Hello World application that uses Tock's console system calls and
+asynchronous callbacks. We then extracted the console system call interface into
+a reusable library, creating the `FreeCallback` trait along the way.
+
+In order to provide unit tests for the console library, we needed to create
+several new abstractions. We created `Syscalls` so that we can direct tho
+console driver's system calls to a fake kernel. We created the
+`libtock_unittest` crate which contains the fake kernel as well as a
+`test_component!` helper macro. We created `SyncAdapter` so that the unit test
+can be written in a synchronous manner -- although `SyncAdapter` is not
+testing-specific! We created `MethodCallback` because `FreeCallback` is not a
+powerful-enough abstraction on its own for `SyncAdapter`.
+
+We ended up with six Rust crates:
+
+1. `libtock_console`, which contains the console driver logic and unit test
+   code.
+2. `libtock_platform`, which provides abstractions that can be shared with other
+   drivers.
+3. `libtock_runtime`, which contains non-portable system call implementations.
+4. `libtock_sync`, which provides a synchronous interface using
+   `libtock_platform`'s traits.
+5. `libtock_unittest`, which provides a fake Tock kernel and other utilities.
+6. The hello world app itself.
