Setting up a KVM virtual machine on an ARM64 platform (RK3399). Guest and host are different flavours of Debian - Armbian stretch and Ubuntu 18.04. Guest kernel is a mainline stable LTS release, not a vendor kernel - as it is does not need the vendor hardware drivers. The aim is to run some NAS setup on the VM to serve an old USB Raid disk - and retire an old Power MacMini that had been doing the job.

Target Guest:

References:

What is needed:

  • An Kernel Image.gz file.
  • A root filesystem image.

What is not needed:

  • A device tree - Qemu can generate this for us.
  • An initram image. The boot disk drivers (virtio-blk) will be compiled into the kernel.

Kernel Image

As there is no need for vendor drivers, a mainline tree can be used.

git clone git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
git checkout v4.9.164
make defconfig

The defconfig enables most drivers we need by default(CONFIG_PARAVIRT=y, CONFIG_VIRTIO_*). Some optimization can be done, e.g.

  • Most Virtio drivers are enabled by default, but these were not enabled:
    • HW_RANDOM_VIRTIO (Location : Device Drivers -> Character devices -> Hardware Random Number Generator Core support) “Device Drivers > Virtualization”
    • CONFIG_VIRTIO_INPUT is not enabled by default. Not needed for a headless server.
  • Remove SoC vendor specific drivers:
    • “Platform Selection”
      • (Not strictly needed, but the “ARMv8 software model (Versatile Express)” platform can be emulated by QEMU)
  • Removed xen/kvm host options (“Virtualization”, “Kernel Features > Xen guest support on ARM64”)

For this use case, other config options are useful:

  • Legacy Filesystems
    • The USB raid disk is formatted in HFS (CONFIG_HFS_FS).
    • There are older Amiga FFS HD images that should be accessible (CONFIG_AFFS_FS).

Create the kernel image (locally compiled on host):

make vmlinux -j 4
make Image.gz
make defconfig

Copy the image to the vm environment dir.

cp arch/arm64/boot/Image.gz /vm/armbian/Image.4.9.164.gz
cp defconfig /vm/armbian/defconfig.4.9.164.gz

Root Filesystem

Using a raw filesystem image, formatted for ext4. This is the simplest, other options can be created with qemu-img

dd if=/dev/zero conv=sparse of=rootfs.img bs=1G count=8
mkfs.ext4 rootfs.img
mkdir rootfs
sudo mount -o loop rootfs.img rootfs

The Armbian rootfs image is here. Downloaded and extracted to the loop mounted rootfs image:

wget https://dl.armbian.com/_rootfs/stretch-ng-arm64.65f8bb574253c9bcf68fbd09876b7485.tar.lz4
sudo apt-get install liblz4-tool
cd rootfs/
lz4cat ../stretch-ng-arm64.65f8bb574253c9bcf68fbd09876b7485.tar.lz4 | sudo tar px
cd ..

Setup an account and password:

sudo chroot rootfs
root@Firefly-RK3399:/# useradd xxxx
root@Firefly-RK3399:/# passwd xxxx
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
usermod -G sudo xxxx
exit

The next step is to setup QEMU/KVM.