diff --git a/src/Cargo.lock b/src/Cargo.lock
index c56fdb5e..57906b52 100644
--- a/src/Cargo.lock
+++ b/src/Cargo.lock
@@ -218,6 +218,33 @@ dependencies = [
"libsupport_zynq",
]
+[[package]]
+name = "kernel"
+version = "0.1.0"
+dependencies = [
+ "build_zynq",
+ "byteorder",
+ "core_io",
+ "cslice",
+ "dwarf",
+ "dyld",
+ "io",
+ "libasync",
+ "libboard_artiq",
+ "libboard_zynq",
+ "libc",
+ "libconfig",
+ "libcortex_a9",
+ "libm",
+ "libregister",
+ "libsupport_zynq",
+ "log",
+ "log_buffer",
+ "nb 0.1.3",
+ "unwind",
+ "void",
+]
+
[[package]]
name = "libasync"
version = "0.0.0"
@@ -438,18 +465,17 @@ dependencies = [
"embedded-hal",
"futures",
"io",
+ "kernel",
"libasync",
"libboard_artiq",
"libboard_zynq",
"libc",
"libconfig",
"libcortex_a9",
- "libm",
"libregister",
"libsupport_zynq",
"log",
"log_buffer",
- "nb 0.1.3",
"num-derive",
"num-traits",
"unwind",
diff --git a/src/libkernel/Cargo.toml b/src/libkernel/Cargo.toml
new file mode 100644
index 00000000..0d633441
--- /dev/null
+++ b/src/libkernel/Cargo.toml
@@ -0,0 +1,33 @@
+[package]
+name = "kernel"
+description = "Kernel support for Zynq-based platforms"
+version = "0.1.0"
+authors = ["M-Labs"]
+edition = "2018"
+
+[build-dependencies]
+build_zynq = { path = "../libbuild_zynq" }
+
+[dependencies]
+cslice = "0.3"
+log = "0.4"
+nb = "0.1"
+core_io = { version = "0.1", features = ["collections"] }
+byteorder = { version = "1.3", default-features = false }
+void = { version = "1", default-features = false }
+log_buffer = { version = "1.2" }
+libm = { version = "0.2", features = ["unstable"] }
+
+libboard_zynq = { git = "https://git.m-labs.hk/M-Labs/zynq-rs.git", features = ["ipv6"]}
+libsupport_zynq = { default-features = false, features = ["alloc_core"], git = "https://git.m-labs.hk/M-Labs/zynq-rs.git" }
+libcortex_a9 = { git = "https://git.m-labs.hk/M-Labs/zynq-rs.git" }
+libasync = { git = "https://git.m-labs.hk/M-Labs/zynq-rs.git" }
+libregister = { git = "https://git.m-labs.hk/M-Labs/zynq-rs.git" }
+libconfig = { git = "https://git.m-labs.hk/M-Labs/zynq-rs.git", features = ["fat_lfn", "ipv6"] }
+
+dyld = { path = "../libdyld" }
+dwarf = { path = "../libdwarf" }
+unwind = { path = "../libunwind" }
+libc = { path = "../libc" }
+io = { path = "../libio" }
+libboard_artiq = { path = "../libboard_artiq" }
\ No newline at end of file
diff --git a/src/libkernel/build.rs b/src/libkernel/build.rs
new file mode 100644
index 00000000..ba3b31b8
--- /dev/null
+++ b/src/libkernel/build.rs
@@ -0,0 +1,5 @@
+extern crate build_zynq;
+
+fn main() {
+ build_zynq::cfg();
+}
diff --git a/src/runtime/src/eh_artiq.rs b/src/libkernel/src/eh_artiq.rs
similarity index 100%
rename from src/runtime/src/eh_artiq.rs
rename to src/libkernel/src/eh_artiq.rs
diff --git a/src/runtime/src/i2c.rs b/src/libkernel/src/i2c.rs
similarity index 100%
rename from src/runtime/src/i2c.rs
rename to src/libkernel/src/i2c.rs
diff --git a/src/runtime/src/irq.rs b/src/libkernel/src/irq.rs
similarity index 100%
rename from src/runtime/src/irq.rs
rename to src/libkernel/src/irq.rs
diff --git a/src/runtime/src/kernel/api.rs b/src/libkernel/src/kernel/api.rs
similarity index 99%
rename from src/runtime/src/kernel/api.rs
rename to src/libkernel/src/kernel/api.rs
index 87b57aee..479525e0 100644
--- a/src/runtime/src/kernel/api.rs
+++ b/src/libkernel/src/kernel/api.rs
@@ -5,6 +5,8 @@ use libc::{c_char, c_int, size_t};
use libm;
use log::{info, warn};
+#[cfg(has_drtio)]
+use super::subkernel;
use super::{cache,
core1::rtio_get_destination_status,
dma,
diff --git a/src/runtime/src/kernel/cache.rs b/src/libkernel/src/kernel/cache.rs
similarity index 100%
rename from src/runtime/src/kernel/cache.rs
rename to src/libkernel/src/kernel/cache.rs
diff --git a/src/runtime/src/kernel/control.rs b/src/libkernel/src/kernel/control.rs
similarity index 92%
rename from src/runtime/src/kernel/control.rs
rename to src/libkernel/src/kernel/control.rs
index fcd35dcc..7d03236c 100644
--- a/src/runtime/src/kernel/control.rs
+++ b/src/libkernel/src/kernel/control.rs
@@ -3,8 +3,8 @@ use core::mem::{forget, replace};
use libcortex_a9::sync_channel::{Receiver, Sender};
use libsupport_zynq::boot::Core1;
-use super::{Message, CHANNEL_0TO1, CHANNEL_1TO0, CHANNEL_SEM, INIT_LOCK};
-use crate::irq::restart_core1;
+use super::{CHANNEL_0TO1, CHANNEL_1TO0, CHANNEL_SEM, INIT_LOCK};
+use crate::{irq::restart_core1, Message};
pub struct Control {
pub tx: Sender<'static, Message>,
diff --git a/src/runtime/src/kernel/core1.rs b/src/libkernel/src/kernel/core1.rs
similarity index 100%
rename from src/runtime/src/kernel/core1.rs
rename to src/libkernel/src/kernel/core1.rs
diff --git a/src/runtime/src/kernel/dma.rs b/src/libkernel/src/kernel/dma.rs
similarity index 100%
rename from src/runtime/src/kernel/dma.rs
rename to src/libkernel/src/kernel/dma.rs
diff --git a/src/libkernel/src/kernel/mod.rs b/src/libkernel/src/kernel/mod.rs
new file mode 100644
index 00000000..6e02c608
--- /dev/null
+++ b/src/libkernel/src/kernel/mod.rs
@@ -0,0 +1,27 @@
+use core::ptr;
+
+use libcortex_a9::{mutex::Mutex, semaphore::Semaphore, sync_channel};
+
+use crate::Message;
+
+mod control;
+pub use control::Control;
+mod api;
+pub mod core1;
+mod dma;
+mod rpc;
+pub use dma::DmaRecorder;
+mod cache;
+#[cfg(has_drtio)]
+mod subkernel;
+
+static CHANNEL_0TO1: Mutex