diff --git a/README.md b/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..e0a7a4c863b03bb06474b13b076ae6857486c926
--- /dev/null
+++ b/README.md
@@ -0,0 +1,75 @@
+# Small Rust library for teaching Operating Systems & Computer Networks
+
+## Rationale
+
+The goal in many OSCN courses is to teach concepts and applying these in small
+simple exercises in order to widen understanding.  Due to the nature of
+operating systems this often is done using the C programming language.  C
+provides much insight to the machine in contrast to other more high-level
+languages such as Python or Java.  However the tooling around C is quite old
+and mostly targets professional programmers rather than novices.  Rust has come
+to provide a "modern" replacement for C where applicable.  However, plain Rust
+hides details of the operating system quite well, while in OSCN courses we
+actually want to look specifically at those details that are now hidden.
+
+To be able to use the modern tooling of Rust with many of its benefits we thus
+might want to look into creating an alternative library with more thin and
+closer-to-the-machine wrappers.  Ideally this combines the tooling of Rust with
+the level of insight of C.
+
+## Usage
+
+Add to your `Cargo.toml`:
+```toml
+[dependencies]
+libc = "0.2"
+ti3-rust = { git = "https://git.imp.fu-berlin.de/koenigl2/ti3-rust.git" }
+```
+
+You can now run `cargo build` or `cargo run` and look at the documentation of
+`ti3-rust` using `cargo doc --open` in your browser.  The documentation includes
+a brief overview, further readings as well as code samples.
+
+## Example
+
+The following are snippets from a cat(1) implementation in C and Rust using this
+library respectively:
+
+Reading a file descriptor and handling the return value:
+```c
+ssize_t n = read(src, buffer, sizeof(buffer));
+if (n < 0) { return 1; }
+if (n == 0) { return 0; }
+
+const size_t read = (size_t)n;
+```
+Rust equivalent:
+```rust
+let read = match read(src, &mut buffer, BUFSIZ) {
+    0 => return 0,
+    n if n < 0 => return 1,
+    n => n as size_t,
+};
+```
+
+Writing a buffer to a file descriptor:
+```c
+while (remaining > 0) {
+        ssize_t written = write(dest, &buffer[read - remaining],
+                                remaining);
+        if (written < 0) { return 1; }
+
+        remaining -= written;
+}
+```
+Rust equivalent:
+```rust
+let mut remaining = read;
+while remaining > 0 {
+    let written = match write(dest, &mut buffer[read - remaining..], remaining) {
+        n if n < 0 => return 1,
+        n => n as size_t,
+    };
+    remaining -= written;
+}
+```