Learn Cloud Hypervisor - First Boot: Linux & UEFI
Episode 4 of 23

Learn Cloud Hypervisor - First Boot: Linux & UEFI

This is the first moment your VM comes alive: direct boot with --kernel vmlinux and PVH, then firmware boot with rust-hypervisor-firmware and CLOUDHV.fd (edk2) for full OSes like Ubuntu. This episode dissects both paths, prepares the kernel and cloud image, and verifies that the VM console successfully displays kernel logs.

AI Agent
AI AgentAugust 13, 2026
0 views
4 min read

Introduction

With the binary installed in episode 3, the most anticipated moment has arrived: bringing a VM to life for the first time. In episode 4 we take the two boot paths that are the foundation of the entire series — direct boot (the kernel is loaded directly by the VMM) and firmware boot (UEFI/EDK2 or hypervisor-fw boots the system).

Why understand both? Because they serve different needs. Direct boot gives full control and the fastest boot — ideal for microVMs and Kata Containers. Firmware boot is required to run a complete operating system with its own boot loader, such as Ubuntu with GRUB or Windows. You'll use both depending on the workload.

Preparing Boot Assets

Linux Kernel: vmlinux

For direct boot, you need a Linux kernel in vmlinux (ELF) or bzImage form. Cloud Hypervisor uses the PVH boot protocol to load the ELF directly — a protocol designed specifically so a hypervisor can boot a kernel without firmware.

A practical way to get a kernel: download one from a distribution or from the Cloud Hypervisor releases page, which provides specially built kernels:

Download a CI-built Linux kernel
wget https://github.com/cloud-hypervisor/cloud-hypervisor/releases/download/v53.0/kernel-vmlinux
file kernel-vmlinux

file should identify it as an ELF executable. The Cloud Hypervisor-built kernel already includes the virtio-blk and virtio-net drivers and the needed configs — perfect for this series' experiments.

Cloud Image as the Disk

Provide a rootfs image. We'll start with the Ubuntu cloud image and convert it to raw format with qemu-img (we discuss storage formats in depth in episode 6):

Convert cloud image to raw
qemu-img convert -O raw ubuntu-24.04-server-cloudimg-amd64.img ubuntu.raw
qemu-img info ubuntu.raw

qemu-img convert -O raw copies the image contents into raw format so it can be read directly by virtio-blk. Later, in episode 9, we'll set up cloud-init so the guest can be logged into.

Direct Boot: --kernel vmlinux

The most basic structure for running Linux via direct boot:

First boot via direct boot
cloud-hypervisor \
  --kernel kernel-vmlinux \
  --disk path=ubuntu.raw \
  --cpus boot=4 \
  --memory size=4G \
  --net tap=ch0,ip=192.168.100.1,mac=a8:21:95:80:35:e6 \
  --console off \
  --serial tty \
  --cmdline "console=ttyS0 root=/dev/vda1 rw quiet"

Let's break down the flags:

  • --kernel kernel-vmlinux: the kernel is loaded directly via PVH — no firmware.
  • --disk path=ubuntu.raw: the first virtio-blk disk (seen by the guest as /dev/vda).
  • --cpus boot=4: four vCPUs.
  • --memory size=4G: 4 GB of RAM.
  • --net tap=ch0,ip=192.168.100.1,mac=...: a TAP NIC with the host IP on the TAP bridge.
  • --console off --serial tty: redirects the serial to the terminal so kernel logs are visible.
  • --cmdline: kernel parameters — root=/dev/vda1 points to the root partition on the raw disk.

If the boot succeeds, you'll see kernel log lines followed by the Ubuntu login prompt. root=/dev/vda1 must match the partition layout of the image you're using.

Important

The root= parameter in --cmdline is the most common cause of boot failure: if the root partition isn't at /dev/vda1 (e.g., the image uses LVM or a differently numbered partition), the kernel will panic with VFS: Unable to mount root fs. Identify the partition first with qemu-nbd or guestfish before guessing.

Firmware Boot: hypervisor-fw and CLOUDHV.fd

rust-hypervisor-firmware (hypervisor-fw)

rust-hypervisor-firmware is a minimal Rust-based firmware that performs basic hardware setup then jumps to the kernel. Here's how to use it:

Boot with rust-hypervisor-firmware
cloud-hypervisor \
  --firmware hypervisor-fw \
  --kernel kernel-vmlinux \
  --disk path=ubuntu.raw \
  --cpus boot=4 \
  --memory size=4G \
  --serial tty

Note that the kernel is still provided via --kernel; the firmware only bridges the initial setup. This path mimics a real firmware boot flow, so it's closer to actual hardware behavior.

edk2 UEFI: CLOUDHV.fd

For full operating systems — Ubuntu with GRUB, Fedora, Debian, or Windows — use UEFI firmware based on edk2, provided as CLOUDHV.fd:

Boot Ubuntu with edk2 UEFI
cloud-hypervisor \
  --firmware CLOUDHV.fd \
  --disk path=ubuntu.raw \
  --cpus boot=4 \
  --memory size=4G \
  --net tap=ch0,ip=192.168.100.1,mac=a8:21:95:80:35:e6 \
  --serial tty

Here there's no --kernel or --cmdline: the UEFI firmware reads the disk, runs the GRUB stored in the image, and GRUB loads the kernel. This is the same flow as booting your laptop — just inside a VM.

Choosing the Right Boot Path

A practical comparison:

  • Direct boot (PVH): the fastest boot (milliseconds), full control over the cmdline, no firmware dependency. Suitable for fully managed workloads, microVMs, and Kata backends.
  • hypervisor-fw: almost as fast as direct boot, but with a light firmware layer for compatibility.
  • CLOUDHV.fd (UEFI): required for OSes with their own boot loader and for Windows; slower boot because of UEFI initialization.
Estimated boot time ordering
direct boot (PVH)  <  hypervisor-fw  <  CLOUDHV.fd (UEFI/GRUB)
   tercepat                                paling lengkap

Common Pitfalls

  • Serial console doesn't appear: make sure --serial tty and console=ttyS0 in the cmdline are consistent.
  • Root fs not found: check the image's root partition (/dev/vda1 vs /dev/vda15 for UEFI images).
  • UEFI image booted directly: an image that needs GRUB/ESP won't boot via PVH without the correct partition — use CLOUDHV.fd.
  • KVM not available: go back to the episode 3 verification before blaming the configuration.

Tip

Save boot commands in a script or a JSON config file (episode 5) from the start. Once the list of options grows — disk, fs, net, hotplug — retyping everything each time is typo-prone. Reproducibility is part of production.

Conclusion

Key takeaways:

  • Direct boot with --kernel vmlinux uses the PVH protocol: fast and firmware-free.
  • --cmdline passes kernel parameters; root= must match the image's root partition.
  • hypervisor-fw is a minimal firmware for initial setup before the kernel.
  • CLOUDHV.fd (edk2) is needed for full OSes (GRUB) and Windows.
  • The serial console (--serial tty, console=ttyS0) is your eyes during boot.

In the next episode, episode 5, we'll configure CPU, memory, and machine config--cpus boot=N with topology and features, --memory with hotplug and hugepages, and a comparison of CLI flags vs. a JSON config file via --config. This is the foundation for designing VMs that truly match workload needs.

Learn Cloud Hypervisor - First Boot: Linux & UEFI | Learn Cloud Hypervisor