Hafnium is a hypervisor, initially supporting aarch64 (64-bit ARMv8 CPUs).
Further details are available in the design doc.
mkdir hafnium cd hafnium repo init -u sso://hafnium/manifest repo sync -j4
You will need a cross-compilation toolchain, for example, aarch64-linux-gnu
, which can be installed with apt
using the following command-line:
sudo apt install gcc-aarch64-linux-gnu
Makefiles use the CROSS_COMPILE
variable to specify the prefix of the tools; in the case above it is aarch64-linux-gnu-
(note the trailing dash). In the examples that follow, we will assume that this toolchain is installed and available for use.
The hypervisor proper is in the hafnium
subdirectory. It can be built for QEMU using the following command:
CROSS_COMPILE=aarch64-linux-gnu- make
The compiled binary is stored in out/aarch64/qemu/hafnium.bin
.
You will need at least version 2.9 for QEMU. The following command line can be used to run Hafnium on it:
qemu-system-aarch64 -M virt -cpu cortex-a57 -nographic -machine virtualization=true -kernel out/aarch64/qemu/hafnium.bin
Though it is admittedly not very useful because it doesn't have any virtual machines to run. The next sections describe how to build an image that can be run using the following command-line:
qemu-system-aarch64 -M virt -cpu cortex-a57 -nographic -machine virtualization=true -kernel out/aarch64/qemu/hafnium.bin -initrd initrd.img -append "rdinit=/sbin/init"
Hafnium expects to find the following files in the root directory of its ramdisk:
vmlinuz
-- the kernel of the primary VM.initrd.img
-- the initial ramdisk of the primary VM.vms.txt
-- optionally describes the secondary VMs.vms.txt
.vms.txt
fileThe format is currently one line per secondary VM, with the following format:
<memory-size-in-bytes> <number-of-cpus> <kernel-filename>
For example, the following defines two secondary VMs, the first one with 1MB of memory, 2 CPUs and kernel image called kernel0
, while the second one has 2MB of memory, 4 CPUs and a kernel image called kernel1
.
1048576 2 kernel0 2097152 4 kernel1
Assuming that a subdirectory called initrd
contains the files listed in the previous section, we can build initrd.img
with the following command:
cd initrd; find . | cpio -o > ../initrd.img; cd -
The linux kernel for the primary VM can be built using the following command-line:
git clone https://github.com/torvalds/linux.git cd linux ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- make defconfig ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- make -j24
The compiled image is stored in arch/arm64/boot/Image
. This should be copied to the Hafnium ramdisk's root as vmlinuz
.
From the hafnium root directory, the following commands can be used to compile the kernel module, replacing <kernel-path>
with the path to the kernel built in the previous section:
cd hafnium/driver/linux/ ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- KERNEL_PATH=<kernel-path> make
The compiled module is called hafnium.ko
, and should be copied into the ramdisk described in the next section.
An initial ramdisk for the primary VM containing busybox can be built with the following commands:
git clone git://busybox.net/busybox.git cd busybox ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- make defconfig ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- make menuconfig
At this point you should ensure that the option Settings > Build static binary (no shared libs)
is selected. Then you can proceed with the following commands:
ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- make -j24 ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- make install cd _install mkdir proc mkdir sys mkdir -p etc/init.d cat <<EOF > etc/init.d/rcS #!bin/sh mount -t proc none /proc mount -t sysfs none /sys EOF chmod u+x etc/init.d/rcS grep -v tty ../examples/inittab > ./etc/inittab
At this point you can copy into the current directory additional files you may want in the ramdisk, for example, the kernel module built in the previous section. Then run the following commands:
find . | cpio -o -H newc | gzip > ../initrd.img cd ..
The resulting file is initrd.img
. It should be copied to the Hafnium ramdisk's root.