Hafnium is a hypervisor, initially supporting aarch64 (64-bit ARMv8 CPUs).
Further details are available in the design doc.
git clone --recurse-submodules sso://hafnium/hafnium && (cd hafnium && f=`git rev-parse --git-dir`/hooks/commit-msg ; curl -Lo $f https://gerrit-review.googlesource.com/tools/hooks/commit-msg ; chmod +x $f)
To upload a change for review:
git push origin HEAD:refs/for/master
By default, the hypervisor is built for an aarch64 QEMU target by running:
make
To build for the HiKey board, change the target platform:
PLATFORM=hikey make
To build using gcc instead of clang, the aarch64 variant must be installed:
sudo apt install gcc-aarch64-linux-gnu GCC=true make
The compiled binary is stored in out/{clang,gcc}_aarch64/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.