DEV Community

Cover image for Test Kernel changes on QEMU
Carlo Lobrano
Carlo Lobrano

Posted on

Test Kernel changes on QEMU

This is all about testing Linux kernel changes on a QEMU virtual machine in cycles of build, install and run shortest than 5 minutes.

The Internet is full of tutorials about building the Linux Kernel, yet I found less content about applying the changes to a virtualized environment, so that will be the goal of this post.

Running QEMU virtual image

Also this content is quite common, so I will be short

# Create the disk: a qcow2 format image of 2G
$ qemu-img create -f qcow2 alpine.img 2G

# Download a live CD ISO image (e.g. Ubuntu, Alpine, whatever), then run the live image and install
# it into the disk created above.
$ qemu-system-x86_64 -cdrom alpine-downloaded.iso alpine.img -m 512M -enable-kvm

# Run the newly installed image from the disk
$ qemu-system-x86_64 -enable-kvm -m 512M -smp 4 -cpu host -drive file=alpine.img
Enter fullscreen mode Exit fullscreen mode

Running QEMU with a custom kernel

You downloaded and built the Linux Kernel under ~/workspace/linux, that is you know have a /linux/arch/x86_64/boot/bzImage, the command to run it in QEMU is

$ qemu-system-x86_64 \
        -enable-kvm -m 512M -smp 4 -cpu host \
        -kernel ~/workspace/linux/arch/x86_64/boot/bzImage \
        -append "root=/dev/sda3 console=ttyS0 rw" \
        -drive file=alpine.img
Enter fullscreen mode Exit fullscreen mode

Make a change and test it

Consider now you made a change to the kernel. Any change, maybe even so silly like the one below

diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index e7755d9cf..534e8051e 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -2138,7 +2138,7 @@ static struct usb_serial_driver option_1port_device = {
        .owner =    THIS_MODULE,
        .name =     "option1",
    },
-   .description       = "GSM modem (1-port)",
+   .description       = "it's me, Mario!",
    .id_table          = option_ids,
    .num_ports         = 1,
    .probe             = option_probe,
Enter fullscreen mode Exit fullscreen mode

How do you test it on your QEMU VM?

First, mount the VM image on the host

$ mkdir /tmp/alpine
$ guestmount --add alpine.img --root /dev/sda3 /tmp/alpine
$ ls /tmp/alpine
bin   dev  home  lost+found  mnt  proc  run   srv   sys  usr
boot  etc  lib   media       opt  root  sbin  swap  tmp  var
Enter fullscreen mode Exit fullscreen mode

Second and last, during the build, tell the kernel to install the modules inside the mounted image

$ make -j$(nproc)
...
$ make -j$(nproc) modules
$ INSTALL_MOD_PATH=/tmp/alpine make modules_install
INSTALL /tmp/alpine/lib/modules/5.18.0-rc2-custom-ga1901b464e7e-dirty/kernel/drivers/thermal/intel/x86_pkg_temp_thermal.ko
INSTALL /tmp/alpine/lib/modules/5.18.0-rc2-custom-ga1901b464e7e-dirty/kernel/drivers/usb/serial/option.ko
INSTALL /tmp/alpine/lib/modules/5.18.0-rc2-custom-ga1901b464e7e-dirty/kernel/drivers/usb/serial/usb-serial-simple.ko
INSTALL /tmp/alpine/lib/modules/5.18.0-rc2-custom-ga1901b464e7e-dirty/kernel/drivers/usb/serial/usb_wwan.ko
INSTALL /tmp/alpine/lib/modules/5.18.0-rc2-custom-ga1901b464e7e-dirty/kernel/drivers/usb/serial/usbserial.ko
INSTALL /tmp/alpine/lib/modules/5.18.0-rc2-custom-ga1901b464e7e-dirty/kernel/fs/efivarfs/efivarfs.ko
INSTALL /tmp/alpine/lib/modules/5.18.0-rc2-custom-ga1901b464e7e-dirty/kernel/net/ipv4/netfilter/iptable_nat.ko
INSTALL /tmp/alpine/lib/modules/5.18.0-rc2-custom-ga1901b464e7e-dirty/kernel/net/netfilter/nf_log_syslog.ko
INSTALL /tmp/alpine/lib/modules/5.18.0-rc2-custom-ga1901b464e7e-dirty/kernel/net/netfilter/xt_LOG.ko
INSTALL /tmp/alpine/lib/modules/5.18.0-rc2-custom-ga1901b464e7e-dirty/kernel/net/netfilter/xt_MASQUERADE.ko
INSTALL /tmp/alpine/lib/modules/5.18.0-rc2-custom-ga1901b464e7e-dirty/kernel/net/netfilter/xt_addrtype.ko
INSTALL /tmp/alpine/lib/modules/5.18.0-rc2-custom-ga1901b464e7e-dirty/kernel/net/netfilter/xt_mark.ko
INSTALL /tmp/alpine/lib/modules/5.18.0-rc2-custom-ga1901b464e7e-dirty/kernel/net/netfilter/xt_nat.ko
DEPMOD  /tmp/alpine/lib/modules/5.18.0-rc2-custom-ga1901b464e7e-dirty
Enter fullscreen mode Exit fullscreen mode

don't forget to UNMOUNT the image

$ umount /tmp/alpine
Enter fullscreen mode Exit fullscreen mode

Run again your kernel, the change (at least the one above) will be visible loading "option" module.

Final words

This process is so fast that one can test changes to the kernel in few seconds, moreover you are going to have a wide range of debug features provided by QEMU and, not less important, your machine is preserved.

Top comments (0)