diff --git a/.travis.yml b/.travis.yml
index 3337d3f0c265f180b72210e67c71dc1ff56d51b9..0bd90015ee78fe41aa4cad5d467ec0d109b2628e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,22 +1,27 @@
-cache: cargo
 dist: trusty
 language: rust
-rust: nightly
 services: docker
 sudo: required
 
+rust: nightly
+
+env: TARGET=x86_64-unknown-linux-gnu
 matrix:
   include:
     - env: TARGET=thumbv6m-none-eabi
-    - env: TARGET=thumbv7m-none-eabi
     - env: TARGET=thumbv7em-none-eabi
     - env: TARGET=thumbv7em-none-eabihf
-env: TARGET=x86_64-unknown-linux-gnu
+    - env: TARGET=thumbv7m-none-eabi
+
+install:
+  - sh ci/install.sh
+  - source ~/.cargo/env || true
 
 script:
-  - cargo generate-lockfile
-  - sh ci/run-docker.sh $TARGET
-  # Travis can't cache files that are not readable by "others"
+  - bash ci/script.sh
+
+cache: cargo
+before_cache:
   - chmod -R a+r $HOME/.cargo
 
 branches:
diff --git a/ci/docker/thumbv6m-none-eabi/Dockerfile b/ci/docker/thumbv6m-none-eabi/Dockerfile
deleted file mode 100644
index fa5439aac788b556d137be0801751b2b608a2c5b..0000000000000000000000000000000000000000
--- a/ci/docker/thumbv6m-none-eabi/Dockerfile
+++ /dev/null
@@ -1,9 +0,0 @@
-FROM ubuntu:16.04
-RUN apt-get update
-RUN apt-get install -y --no-install-recommends \
-    ca-certificates \
-    curl \
-    libcurl4-openssl-dev \
-    libssh2-1
-RUN curl -sf "https://raw.githubusercontent.com/japaric/rust-everywhere/master/install.sh" | \
-    bash -s -- --at /usr/bin --from japaric/xargo --for x86_64-unknown-linux-gnu --tag v0.1.13
diff --git a/ci/docker/thumbv7em-none-eabi/Dockerfile b/ci/docker/thumbv7em-none-eabi/Dockerfile
deleted file mode 100644
index fa5439aac788b556d137be0801751b2b608a2c5b..0000000000000000000000000000000000000000
--- a/ci/docker/thumbv7em-none-eabi/Dockerfile
+++ /dev/null
@@ -1,9 +0,0 @@
-FROM ubuntu:16.04
-RUN apt-get update
-RUN apt-get install -y --no-install-recommends \
-    ca-certificates \
-    curl \
-    libcurl4-openssl-dev \
-    libssh2-1
-RUN curl -sf "https://raw.githubusercontent.com/japaric/rust-everywhere/master/install.sh" | \
-    bash -s -- --at /usr/bin --from japaric/xargo --for x86_64-unknown-linux-gnu --tag v0.1.13
diff --git a/ci/docker/thumbv7em-none-eabihf/Dockerfile b/ci/docker/thumbv7em-none-eabihf/Dockerfile
deleted file mode 100644
index fa5439aac788b556d137be0801751b2b608a2c5b..0000000000000000000000000000000000000000
--- a/ci/docker/thumbv7em-none-eabihf/Dockerfile
+++ /dev/null
@@ -1,9 +0,0 @@
-FROM ubuntu:16.04
-RUN apt-get update
-RUN apt-get install -y --no-install-recommends \
-    ca-certificates \
-    curl \
-    libcurl4-openssl-dev \
-    libssh2-1
-RUN curl -sf "https://raw.githubusercontent.com/japaric/rust-everywhere/master/install.sh" | \
-    bash -s -- --at /usr/bin --from japaric/xargo --for x86_64-unknown-linux-gnu --tag v0.1.13
diff --git a/ci/docker/thumbv7m-none-eabi/Dockerfile b/ci/docker/thumbv7m-none-eabi/Dockerfile
deleted file mode 100644
index fa5439aac788b556d137be0801751b2b608a2c5b..0000000000000000000000000000000000000000
--- a/ci/docker/thumbv7m-none-eabi/Dockerfile
+++ /dev/null
@@ -1,9 +0,0 @@
-FROM ubuntu:16.04
-RUN apt-get update
-RUN apt-get install -y --no-install-recommends \
-    ca-certificates \
-    curl \
-    libcurl4-openssl-dev \
-    libssh2-1
-RUN curl -sf "https://raw.githubusercontent.com/japaric/rust-everywhere/master/install.sh" | \
-    bash -s -- --at /usr/bin --from japaric/xargo --for x86_64-unknown-linux-gnu --tag v0.1.13
diff --git a/ci/docker/x86_64-unknown-linux-gnu/Dockerfile b/ci/docker/x86_64-unknown-linux-gnu/Dockerfile
deleted file mode 100644
index dbbecfa920e5da89a0314373e58267254c0f28e0..0000000000000000000000000000000000000000
--- a/ci/docker/x86_64-unknown-linux-gnu/Dockerfile
+++ /dev/null
@@ -1,5 +0,0 @@
-FROM ubuntu:16.04
-RUN apt-get update
-RUN apt-get install -y --no-install-recommends \
-    ca-certificates gcc libc6-dev
-ENV PATH=$PATH:/rust/bin
diff --git a/ci/install.sh b/ci/install.sh
new file mode 100644
index 0000000000000000000000000000000000000000..1a72b33c0da5b1f3b42ea2c35fddb2a6db39bd33
--- /dev/null
+++ b/ci/install.sh
@@ -0,0 +1,15 @@
+set -ex
+
+main() {
+    curl https://sh.rustup.rs -sSf | \
+        sh -s -- -y --default-toolchain $TRAVIS_RUST_VERSION
+
+    curl -LSfs https://japaric.github.io/trust/install.sh | \
+        sh -s -- \
+           --force \
+           --git japaric/cross \
+           --tag v0.1.4 \
+           --target x86_64-unknown-linux-gnu
+}
+
+main
diff --git a/ci/run-docker.sh b/ci/run-docker.sh
deleted file mode 100755
index 5a4762daa920581d459e37031a71bf71be02f26d..0000000000000000000000000000000000000000
--- a/ci/run-docker.sh
+++ /dev/null
@@ -1,35 +0,0 @@
-set -ex
-
-run() {
-    local target=$1
-
-    echo $target
-
-    # This directory needs to exist before calling docker, otherwise docker will create it but it
-    # will be owned by root
-    mkdir -p target
-
-    docker build -t $target ci/docker/$target
-    docker run \
-           --rm \
-           --user $(id -u):$(id -g) \
-           -e CARGO_HOME=/cargo \
-           -e CARGO_TARGET_DIR=/target \
-           -e HOME=/tmp \
-           -v $HOME/.cargo:/cargo \
-           -v `pwd`/target:/target \
-           -v `pwd`:/checkout:ro \
-           -v `rustc --print sysroot`:/rust:ro \
-           -w /checkout \
-           -it $target \
-           sh -c "PATH=\$PATH:/rust/bin ci/run.sh $target"
-}
-
-
-if [ -z "$1" ]; then
-    for d in `ls ci/docker/`; do
-        run $d
-    done
-else
-    run $1
-fi
diff --git a/ci/run.sh b/ci/run.sh
deleted file mode 100755
index fdd3fd27cc3138257b702bbad35130ce7476d726..0000000000000000000000000000000000000000
--- a/ci/run.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/bash
-
-set -ex
-
-case $1 in
-    thumbv*)
-        xargo build --target $1
-    ;;
-    *)
-        cargo test --target $1
-    ;;
-esac
diff --git a/ci/script.sh b/ci/script.sh
new file mode 100644
index 0000000000000000000000000000000000000000..53215a82c38bea7996ae74a4eea401629a511f50
--- /dev/null
+++ b/ci/script.sh
@@ -0,0 +1,11 @@
+set -ex
+
+main() {
+    cross build --target $TARGET
+
+    if [ $TARGET = x86_64-unknown-linux-gnu ]; then
+        cross test --target $TARGET
+    fi
+}
+
+main