Linux Kernel Development Workflow: Testing Changes in a Virtual Machine

I think we can all agree that the faster a code-compile-test development cycle is, the better. Working on an operating system kernel like Linux throws a bit of a wrench in the development cycle that most of us are used to simply because Linux expects to be driving some hardware! This means that the kernel you’re working on needs to be running on a machine.

When working on the kernel, crashing the computer you’re testing with is an occupational hazard, so I prefer to test my changes on a computer that is not the one I depend on. This means the kernel I’m hacking on goes on a separate machine (a so-called sacrificial box) or even better: a virtual machine.

I love virtual machines. You can put a positively vile kernel on a virtual machine and rest easy that it’s not going to affect your personal system. Virtual machines also expose mechanisms to aid in debugging without the need of any additional hardware (neat!). Not to mention, you can shoot a virtual machine right in the head and resurrect it in no time.

Pretty neat, huh? Chances are the kernel code you’re hacking on can be safely tested under the purview of a virtual machine. Let’s get started.

Prerequisites

We’ll be using the following packages (on Ubuntu):

  • qemu-kvm
  • uvtool-libvirt

Once the packages have been installed, restart your session (either log out and back in or reboot your machine) so that your session includes your new membership to the libvirt group.

Membership to the libvirt group allows you to create, modify, and otherwise interact with your KVM-accelerated virtual machines (which we are doing here). Otherwise, you’d have to be the root user to do so.

Download Cloud Images

$ uvt-simplestreams-libvirt sync --source https://cloud-images.ubuntu.com/daily release=eoan arch=amd64

We’ll equip ourselves with the latest amd64 Ubuntu Eoan cloud image for the VM. Cloud images are a fast way to get a lean, fully functioning Ubuntu installation.

Create the Virtual Machine

$ uvt-kvm create dev \
  arch=amd64 \
  release=eoan \
  --memory 1024 \
  --cpu 2 \
  --disk 15 \
  --unsafe-caching

This will create an amd64 virtual machined named “dev”. It’s based on the Ubuntu Eoan 19.10 cloud image with 1024 MB of RAM, 2 vCPUs, and 15 GB of disk space.

Wait for the VM to come up with uvt-kvm wait dev.

Let’s also make our lives easier by taking a snapshot of the VM, just in case our future changes bork it.

$ virsh snapshot-create-as dev stock

That will create a snapshot of our virtual machine and the snapshot’s name is “stock”. If the VM does end up in a poor state, you can revert to your new snapshot thusly:

$ virsh snapshot-revert dev stock

Copy the VM Config

SSH into the VM with uvt-kvm ssh dev and take note of your config:

$ ls /boot/config-*
 /boot/config-5.3.0-19-generic

We’ll be copying that config from the virtual machine to use as our .config in the kernel tree. Either exit from your SSH session with the VM, or in another terminal window, navigate to the root of your Linux tree and copy the config down:

$ scp ubuntu@`uvt-kvm ip dev`:/boot/config-5.3.0-19-generic .config 
$ yes "" | make oldconfig

Now we have a good base config for our VM, you can enable or disable whatever features you want, like the driver you’re working on!

Hurray! The first time setup is all done. Now what follows will be the development, build, test loop.

Make a Kernel Change

The kernel is your playground!

Compile the Kernel

You can compile the kernel normally with make; however, we also want those Debian packages to conveniently install the test kernel in the VM. Running the bindeb-pkg target will compile the kernel AND produce Debian packages.

If you have already built the kernel, be absolutely sure you run use the bindeb-pkg target instead of deb-pkg as the latter will invoke make clean!

Copy the New Kernel Packages to the VM

Go ahead and copy the *image*.deb over the the virtual machine:

$ cd ../
$ scp *image*.deb ubuntu@`uvt-kvm ip dev`:

Test!

SSH into the virtual machine and install the new packages:

$ uvt-kvm ssh dev
$ sudo dpkg -i *.deb
$ sudo reboot

Now, it might be a good idea to monitor the serial console of your VM as it boots so you can see if you unleashed any gremlins. In another terminal window:

$ virsh console dev

And in the terminal with which you’d like to interact with the VM:

$ uvt-kvm ssh dev

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s