Your submission was sent successfully! Close

You have successfully unsubscribed! Close

Testing Ubuntu Core with QEMU

You can test Ubuntu Core without specific hardware from within a virtual machine.

To test Ubuntu Core with QEMU (https://www.qemu.org/) on Ubuntu, first install the qemu-kvm package and test it with kvm-ok (a utility that comes with the cpu-checker package):

$ sudo apt install qemu-kvm
$ kvm-ok
INFO: /dev/kvm exists
KVM acceleration can be used

To ensure compatibility with the required UEFI features in Ubuntu Core 22 and 20, also install the OVMF package:

sudo apt install ovmf

Download the preferred Ubuntu Core image for your device platform. See Supported platforms for links to images.

By default, images are compressed with xz and can be expanded from the Linux command line with the following command:

xz -d <image-name>.img.xz

Booting an Ubuntu Core image with QEMU

The exact QEMU command to run will depend on your host hardware capabilities, such as available memory and CPU cores, but the following should work in the majority of cases:

For Ubuntu Core 22 and 20:

We recommend first installing a test snap that emulates TPM in software with libtpms (see the swtpm documentation for implementation details):

snap install --edge test-snapd-swtpm

The path to the snap’s libtpms-based socket (/var/snap/test-snapd-swtpm/current/swtpm-sock) is passed to the QEMU command:

$ sudo qemu-system-x86_64 \
 -enable-kvm \
 -smp 1 \
 -m 2048 \
 -machine q35 \
 -cpu host \
 -global ICH9-LPC.disable_s3=1 \
 -net nic,model=virtio \
 -net user,hostfwd=tcp::8022-:22,hostfwd=tcp::8090-:80  \
 -drive file=/usr/share/OVMF/OVMF_CODE.secboot.fd,if=pflash,format=raw,unit=0,readonly=on \
 -drive file=/usr/share/OVMF/OVMF_VARS.ms.fd,if=pflash,format=raw,unit=1 \
 -chardev socket,id=chrtpm,path="/var/snap/test-snapd-swtpm/current/swtpm-sock" \
 -tpmdev emulator,id=tpm0,chardev=chrtpm \
 -device tpm-tis,tpmdev=tpm0 \
 -drive "file=uc.img",if=none,format=raw,id=disk1 \
 -device virtio-blk-pci,drive=disk1,bootindex=1 \
 -serial mon:stdio

To test Ubuntu Core 22 and 20 without TPM emulation, omit the three lines that reference the TPM device:

$ sudo qemu-system-x86_64 \
 -enable-kvm \
 -smp 1 \
 -m 2048 \
 -machine q35 \
 -cpu host \
 -global ICH9-LPC.disable_s3=1 \
 -net nic,model=virtio \
 -net user,hostfwd=tcp::8022-:22,hostfwd=tcp::8090-:80  \
 -drive file=/usr/share/OVMF/OVMF_CODE.secboot.fd,if=pflash,format=raw,unit=0,readonly=on \
 -drive file=/usr/share/OVMF/OVMF_VARS.ms.fd,if=pflash,format=raw,unit=1 \
 -drive "file=uc.img",if=none,format=raw,id=disk1 \
 -device virtio-blk-pci,drive=disk1,bootindex=1 \
 -serial mon:stdio

For Ubuntu Core 18:

$ qemu-system-x86_64 \ 
 -enable-kvm \ 
 -smp 2 \
 -m 1500 \
 -netdev user,id=mynet0,hostfwd=tcp::8022-:22,hostfwd=tcp::8090-:80 \
 -device virtio-net-pci,netdev=mynet0 \
 -drive file=uc.img,format=raw

In both of the above commands, the Ubuntu Core image is called uc.img and we forward the virtual SSH port 22 to port 8022 on the host, and 80 to 8090 for any web server application you wish to install in the VM.

To access this configuration from your host machine, type the following:

$ ssh -i <path-to-private-key> <sso-username>@localhost -p 8022

In addition to SSH access, QEMU will start a VNC-shared console which can be accessed at vnc://localhost:5900 on the system.

For a brief introduction on how to get started with Ubuntu Core, see Using Ubuntu Core.

Booting an ARM64 Ubuntu Core image with QEMU

It is possible to boot Ubuntu Core 22 arm64 images with qemu-system for arm64. The additional requirements that are needed can be installed by running

$ sudo apt install qemu-efi-aarch64 qemu-system-arm

To run the arm64 image without TPM, execute

$ qemu-system-aarch64 -machine virt -cpu cortex-a57 -smp 2 -m 4096 \
                        -bios /usr/share/AAVMF/AAVMF_CODE.fd \
                        -netdev user,id=net0,hostfwd=tcp::8022-:22 \
                        -device virtio-net-pci,netdev=net0 \
                        -drive if=virtio,file="uc.img",format=raw \
                        -device virtio-gpu-pci \
                        -device virtio-keyboard \
                        -device virtio-mouse \
                        -serial mon:stdio

As the hardware is being emulated, the full installation can take several minutes.

It is also possible to run with an emulated TPM by installing the test-snapd-swtpm snap as for x86. For this to work, you need to first copy the UEFI variables from your system to the local directory. This only needs to be done once, before the first boot of a clean image:

$ cp /usr/share/AAVMF/AAVMF_VARS.ms.fd .

Then run

$ sudo qemu-system-aarch64 -machine virt -cpu cortex-a57 -smp 2 -m 4096 \
        -drive file=/usr/share/AAVMF/AAVMF_CODE.fd,if=pflash,format=raw,unit=0,readonly=on \
        -drive file=AAVMF_VARS.ms.fd,if=pflash,format=raw,unit=1 \
        -netdev user,id=net0,hostfwd=tcp::8022-:22 \
        -device virtio-net-pci,netdev=net0 \
        -drive "file=uc.img",if=none,format=raw,id=disk1 \
        -device virtio-blk-pci,drive=disk1,bootindex=1 \
        -chardev socket,id=chrtpm,path=/var/snap/test-snapd-swtpm/current/swtpm-sock \
        -tpmdev emulator,id=tpm0,chardev=chrtpm \
        -device tpm-tis-device,tpmdev=tpm0 \
        -object rng-random,filename=/dev/urandom,id=rng0 \
        -device virtio-rng-pci,rng=rng0,id=rng-device0 \
        -device virtio-gpu-pci \
        -device virtio-keyboard \
        -device virtio-mouse \
        -serial mon:stdio

It will typically take several minutes for the system to be up and running.

Resetting the TPM

If you wish to run a new clean image after previously running QEMU with the emulated TPM, you will need to reset the emulated TPM state. The safest way to do this is to purge remove and reinstall the emulator snap:

$ snap remove --purge test-snapd-swtpm
$ snap install --edge test-snapd-swtpm

Last updated a month ago. Help improve this document in the forum.