FLUSP logo FLUSP - FLOSS at USP

Use QEMU to Play with Linux Kernel

Written by Rodrigo Siqueira

This tutorial provides a guide for setting up your QEMU VM. We first cover basic installation issues. We then explain how to use the basic features of QEMU. Finally, we show how to configure ssh and shared directory.

Command Summary

If you did not read this tutorial yet, skip this section. I added this section as a summary for someone that already read this tutorial and just want to remember a specific command.

qemu-img create -f qcow2 [NAME] 10G

qemu-system-x86_64 -cdrom ~/PATH/DISTRO_ISO.iso -boot order=d -drive \
                file=[NAME],format=qcow2 -m 2G

qemu-system-x86_64 -enable-kvm -net nic -net user,hostfwd=tcp::2222-:22,smb=$PWD/ \
                   -daemonize -m 4G -smp cores=4,cpus=4 [NAME]

Introduction

If you are curious about Linux Kernel development but feel afraid of accidentally breaking your system due to experiments, the solution for such problems can be summarized in one technology: Virtual Machine (VM). In this tutorial, we’ll examine how to use QEMU, which is an extremely powerful hardware virtualization tool that can be used in many different contexts. I particularly appreciate QEMU because it’s a very popular tool (thus easy to find information about it on the Internet), it’s continuously updated, it features rich machine emulation, it’s free software, and it was initially designed for development.

QEMU is a generic machine emulator based on dynamic translation [3] that can operate in two different modes [2]:

If you have an x86 machine, you can use QEMU with KVM and achieve high performance.

Keep in mind that we should avoid working inside the VM because it is a waste of computational resource. We want to work as much as possible inside the host and use the VM only for testing; because of this and for making our work environment comfortable, we need:

Finally, take a careful look at Figure 1 in order to get an overview of the adopted workflow for this tutorial.

Figure 1: Workflow
Figure 1. Figure 1: Workflow

Info: If you find any problem with this tutorial, please let me know. I will be glad to fix it.

Note

In this tutorial we will work inside and outside of a VM, for simplicity sake, we will add the following comment on top of each command:

Prerequisites: Installing QEMU, KVM and Openssh

To follow this tutorial you need to install QEMU and Samba Client (samba is required for sharing directories between your host and guest).

→ On Arch Linux [1]:

# @HOST
sudo pacman -S qemu samba qemu-arch-extra openssh

→ On Debian [2]:

# @HOST
sudo apt install qemu samba samba-client openssh

Creating an Image

We want QEMU running a Linux distribution for our future experiments with Linux. With this goal in mind, we have to create an image disk with the following command:

# @HOST
qemu-img create -f qcow2 kernel_experiments 15G

Attention: Don’t blindly copy and paste the command above or any other found in this tutorial, try to understand it, by reading the brief description below the command and examining the documentation.

In this tutorial, I recommend using qcow2 with 10 or 15G.

Finally, check if everything is fine by with the command:

# @HOST
file kernel_experiments

The output of the command above, should be something similar to kernel_experiments: QEMU QCOW Image (v3), 16106127360 bytes

Installing a Distro

Next, download any Linux distribution image you want to use (I recommend Debian or ArchLinux [6] [7], but it can be any). With your QEMU image file created above and your distro’s ISO, follow the command below:

# @HOST
qemu-system-x86_64 -cdrom ~/PATH/TO/YOUR_DISTRO_ISO.iso -boot order=d -drive file=kernel_experiments,format=qcow2 -m 2G

The command above will start up a VM and mount the ISO file you’ve downloaded on it. After installation has finished, it’ll reboot the VM automatically.

Proceed with the installation, and come back here after you finish. For the sake of simplicity, create a user in the VM that match with your host machine user.

Booting up a QEMU VM

Finally, it is time to start the machine. Take a look at the command below and adapt it for your needs:

# @HOST
qemu-system-x86_64 -enable-kvm -net nic -net user,hostfwd=tcp::2222-:22,smb=$PWD/ -daemonize -m 2G -smp cores=4,cpus=4 kernel_experiments

This command will pop up a window with the recently installed distribution from the step before. For detailed information about the options used in this command, take a look at the man page.

In some distros, the above command fails or show a warning due to the -enable-kvm parameter. Probably, your host user isn’t part of the KVM group. You can fix it by adding yourself to the KVM group. For example: sudo usermod -a -G kvm $USER. Finally, reboot your machine.

Configuring SSH

At this point, probably you can log in and out of the VM by typing the VM’s user’s password; this can be cumbersome during the work.

To make your work experience better, follow the steps below for creating a passwordless ssh connection, using an RSA key pair.

Info: There’re many ways for setting up an SSH connection; here’s a 1000 foot view of the process.

First, create an RSA key pair on the host machine (if there isn’t any already) with the command:

# @HOST
ssh-keygen -t rsa # Note: For full passwordless, do not add a password in this step

Explaining the above command is beyond this tutorial. There’s plenty of information about it on the Internet [4]. After the key is set up, you need to prepare the recently created VM to accept ssh connections. Just install the package openssh on it (Arch: openssh, Debian: openssh-server).

Since you are working in a fresh installation, you will need to temporally enable password authentication in the VM in order to log in from the host machine. Follow the steps below:

  1. In the VM: sudo sed -i 's/#.*PasswordAuthentication.*/PasswordAuthentication yes/' /etc/ssh/sshd_config;
  2. Restart the service: sudo systemctl restart sshd.

Now, from the host machine test logging in into the VM with:

# @HOST
ssh -p 2222 127.0.0.1

Note that the above command will try to log into the VM using the default host’s username, which is $USER.

If everything works as expected, at this point, you can access the VM’s shell. Moving on, log out of the VM, and from the host machine type the following:

# @HOST
ssh-copy-id -p 2222 $USER@127.0.0.1

Try to reaccess the VM, open the file /etc/ssh/sshd_config, comment the line with PasswordAuthentication, restart the sshd service, and leave the VM. Finally, try to ssh into the VM, and you will be able to access the machine using your ssh key.

Sharing a Directory With your Local Machine

We are close of having a great development environment for playing with Linux Kernel; we just have to set up a final detail: share a directory between our VM and our host system. We want to share a directory because we only need to use our VM for testing and not for developing; i.e., we compile the kernel in our powerful host machine and install the final binaries in the VM. To accomplish this task, we use a share mechanism provided by samba.

First, we need to install the samba and cisfs package in the system. Try:

→ ArchLinux

# @HOST
sudo pacman -S samba cifs-utils

→ Debian

# @HOST
sudo apt install samba cifs-utils

Second, start the VM and install the same packages.

# @HOST
qemu-system-x86_64 -enable-kvm -net nic -net user,hostfwd=tcp::2222-:22,smb=$PWD/ -daemonize -m 2G -smp cores=4,cpus=4 kernel_experiments

$ ssh -p 2222 127.0.0.1

# @VM
sudo pacman -S samba cifs-utils

Now, we want to make an automatic setup in our VM that make the directory shareable on-demand, i.e., the VM and host start to share a directory if the user tries to access the folder. For doing it, we have to create a new systemctl entry.

Before we start this step, it is important to highlight that you need to customize some of the steps described hereafter; basically, you have to replace USER by your username.

1) Let’s start by create the file home-USER-shared.mount (e.g., home-siqueira-shared.mount) inside /etc/systemd/system/ under the VM. Add the following content (again, replace USER in the file):

[Unit]
Description=Mount Share at boot
Requires=systemd-networkd.service
After=network-online.target
Wants=network-online.target

[Mount]
What=//10.0.2.4/qemu
Where=/home/USER/shared
Options=vers=3.0,x-systemd.automount,_netdev,x-systemd.device-timeout=10,uid=1000,noperm,credentials=/root/.cifs
Type=cifs
TimeoutSec=30

[Install]
WantedBy=multi-user.target

You have to use the correct uid here; you can use the command id YOUR_USER.

2) Additionally, create another file named .cifs in /root/ with the following content:

username=YOUR_USER_NAME
password=ANY_PASSWORD_YOU_WANT

3) We have to update the /etc/fstab. In the end of fstab file add the following line:

//10.0.2.4/qemu         /home/USER/shared/  cifs    uid=1000,credentials=/root/.cifs,x-systemd.automount,noperm 0 0

4) Now we to create a shared directory:

# @VM
mkdir shared

5) Finally, we have to put the finishing touches to systemctl:

# @VM
sudo systemctl daemon-reload
sudo systemctl enable home-USER-shared.mount
sudo systemctl start home-USER-shared.mount

6) Try to access the shared directory created on step 4.

Reboot your VM, start it using the command mentioned early, then access it via ssh, and try to access the shared directory. If everything works well, you should see the directory and files that you shared with your host machine.

Conclusion

Keep in mind that we just scratched QEMU’s surface, this tool provides many features and have other tools for easily manage VMs. Finally, follow my feed for new tutorials about QEMU and Linux development.

Acknowledgments

I would like to thanks Charles Oliveira, Shayenne da Luz Moura, Rodrigo Ribeiro, Matheus Tavares, Melissa Wen, and Marcelo Schmitt for their reviews and contributions for this tutorial.

History

  1. V1: Release
  2. V2: Improve highlights
  3. V3: Add Melissa suggestions in some of the steps

References

[1] “QEMU Arch Wiki”. URL: https://wiki.archlinux.org/index.php/QEMU

[2] “QEMU Debian Wiki”. URL: https://wiki.debian.org/QEMU#Installation

[3] “QEMU Official Website”. URL: https://www.qemu.org/

[4] Etel Sverdlov. “How To Set Up SSH Keys”. URL: https://www.digitalocean.com/community/tutorials/how-to-set-up-ssh-keys–2

[5] “Kernel-based Virtual Machine”. URL: https://en.wikipedia.org/wiki/Kernel-based_Virtual_Machine

[6] “Installation guide”. URL: https://wiki.archlinux.org/index.php/installation_guide

[7] “How to Install Arch Linux [Step by Step Guide]”. URL: https://itsfoss.com/install-arch-linux/


comments powered by Disqus