diff --git a/contrib/crosvm/.gitignore b/contrib/crosvm/.gitignore new file mode 100644 index 000000000..e52379710 --- /dev/null +++ b/contrib/crosvm/.gitignore @@ -0,0 +1,2 @@ +/build +iid diff --git a/contrib/crosvm/Dockerfile b/contrib/crosvm/Dockerfile new file mode 100644 index 000000000..94db79209 --- /dev/null +++ b/contrib/crosvm/Dockerfile @@ -0,0 +1,36 @@ +FROM rust:1.25.0-stretch + +ENV CROSVM_REPO=https://chromium.googlesource.com/chromiumos/platform/crosvm +ENV CROSVM_COMMIT=7a7268faf0a43c79b6a4520f5c2f35c3e0233932 +ENV MINIJAIL_REPO=https://android.googlesource.com/platform/external/minijail +ENV MINIJAIL_COMMIT=d45fc420bb8fd9d1fc9297174f3c344db8c20bbd + +# Install deps +RUN apt-get update && apt-get install -y libcap-dev libfdt-dev + +# Get source code +RUN git clone ${MINIJAIL_REPO} && \ + cd /minijail && \ + git checkout ${MINIJAIL_COMMIT} && \ + cd / && \ + git clone ${CROSVM_REPO} && \ + cd crosvm && \ + git checkout ${CROSVM_COMMIT} + +# Compile and install minijail +WORKDIR /minijail +RUN make && \ + cp libminijail.so /usr/lib/ && \ + cp libminijail.h /usr/include/ + +# Compile crosvm +WORKDIR /crosvm +RUN cargo build --release + +RUN mkdir /out && \ + cp /minijail/libminijail.so /out && \ + cp /crosvm/target/release/crosvm /out && \ + cp -r /crosvm/seccomp /out + +WORKDIR /out +ENTRYPOINT ["tar", "cf", "-", "libminijail.so", "crosvm", "seccomp"] diff --git a/contrib/crosvm/Makefile b/contrib/crosvm/Makefile new file mode 100644 index 000000000..59e43d678 --- /dev/null +++ b/contrib/crosvm/Makefile @@ -0,0 +1,9 @@ +.PHONY: extract +extract: iid + rm -rf ./build + mkdir -p ./build + docker run --rm $(shell cat iid) | tar xf - -C ./build + rm iid + +iid: Makefile Dockerfile + docker build --no-cache --iidfile iid . diff --git a/contrib/crosvm/README.md b/contrib/crosvm/README.md new file mode 100644 index 000000000..d1770b297 --- /dev/null +++ b/contrib/crosvm/README.md @@ -0,0 +1,85 @@ +The Chrome OS Virtual Machine Monitor +[`crosvm`](https://chromium.googlesource.com/chromiumos/platform/crosvm/) +is a lightweight VMM written in Rust. It runs on top of KVM and +optionally runs the device models in separate processes isolated with +seccomp profiles. + + +## Build/Install + +The `Makefile` and `Dockerfile` compile `crosvm` and a suitable +version of `libminijail`. To build: + +```sh +make +``` + +You should end up with a `crosvm` and `libminijail.so` binaries as +well as the seccomp profiles in `./build`. Copy `libminijail.so` to +`/usr/lib` or wherever `ldd` picks it up. You may also need `libcap` +(on Ubuntu or Debian `apt-get install -y libcap-dev`). + +You may also have to create an empty directory `/var/empty`. + + +## Use with LinuxKit images + +You can build a LinuxKit image suitable for `crosvm` with the +`kernel+squashfs` build format. For example, using this LinuxKit +YAML file (`minimal.yml`): + +``` +kernel: + image: linuxkit/kernel:4.9.91 + cmdline: "console=tty0 console=ttyS0 console=ttyAMA0" +init: + - linuxkit/init:v0.3 + - linuxkit/runc:v0.3 + - linuxkit/containerd:v0.3 +services: + - name: getty + image: linuxkit/getty:v0.3 + env: + - INSECURE=true +trust: + org: + - linuxkit +``` + +run: + +```sh +linuxkit build -output kernel+squashfs minimal.yml +``` + +The kernel this produces (`minimal-kernel`) needs to be converted as +`crosvm` does not grok `bzImage`s. You can convert the LinuxKit kernel +image with +[extract-vmlinux](https://raw.githubusercontent.com/torvalds/linux/master/scripts/extract-vmlinux): + +```sh +extract-vmlinux minimal-kernel > minimal-vmlinux +``` + +Then you can run `crosvm`: +```sh +./crosvm run --seccomp-policy-dir=./seccomp/x86_64 \ + --root ./minimal-squashfs.img \ + --mem 2048 \ + --multiprocess \ + --socket ./linuxkit-socket \ + minimal-vmlinux +``` + +## Known issues + +- With 4.14.x, a `BUG_ON()` is hit in `drivers/base/driver.c`. 4.9.x + kernels seem to work. +- Networking does not yet work, so don't include a `onboot` `dhcpd` service. +- `poweroff` from the command line does not work (crosvm does not seem + to support ACPI). So to stop a VM you can use the control socket + and: `./crosvm stop ./linuxkit-socket` +- `crosvm` and its dependencies compile on `arm64` but `crosvm` seems + to lack support for setting op the IRQ chip on the system I + tested. I got: `failed to create in-kernel IRQ chip: + CreateGICFailure(Error(19))`.