The typical Kernel development cycle consists of the iteration of this four steps:
If deploy our kernel in our own machines we run the risk of crashing our whole computer. Or even worst: we will have very slow iterations because we need to restart and load our kernel after each change. And even if we deploy the kernel in other pc or board, we need to go through a very time expensive process.
I made this post with the intention of sharing how I tested my own kernel modifications with QEMU.
An hypervisor is the element that supervises a group of virtualized OSes. For example, Virtualbox and VMware are hypervisors, they run virtual machines inside. Also they are what is called a Type-2 or hosted hypervisors. Type-2 means that those hypervisors run as any other program would do: having to talk first to the underlining OS. Instead a Type-1 or bare-metal hypervisor talks directly to the hardware instead, that is the case for KVM and Hyper-V.
Because type-1 runs directly against the hardware it’s much faster than it’s counterpart type-2.
KVM, Kernel-based Virtual Machine, is called “Kernel-Based” because it is a module you can load into your kernel. KVM is an hypervisor type-1 that is inside your SO kernel. KVM provides what is called paravirtualization, this means that KVM runs in ring-0 with the kernel and therefore the guest system is interacting directly with it. You can read more about virtualization here.
You want to use KVM because it will give you near native performance while running a guest system. You need a x86 or x86_64 processor with Intel VT or AMD-V enabled in your bios. Also your kernel you be 2.6.17 or above. In ubuntu you can check it with
$ sudo apt-get install cpu-checker $ kvm-ok INFO: /dev/kvm exists KVM acceleration can be used
If you have a x86_64 processor you will be able to run 32 and 64 bits hosts with very good performance.
“Qemu is like the curl of hypervisors. It runs on the command-line and takes every option under the sun” - Stephen Brennan
QEMU is extremely useful because it allow us to run code in another architecture different from our host processor. For example you can test your ARMv7 kernel in your x86_64 machine.
The installation is very simple:
$ sudo apt-get install qemu-kvm qemu virt-manager virt-viewer libvirt0
Then we can for example create a x86_64 machine with 521MB of ram with KVM enabled:
$ qemu-system-x86_64 -m 512 -smp 1 -enable-kvm
To actually run our compiled kernel, with a custom
initramfs the command is the following:
$ qemu-system-x86_64 -m 512 -smp 1 -enable-kvm \ -kernel arch/x86/boot/bzImage \ -initrd ../build-initramfs/initramfs \ -append 'console=ttyS0' \ -nographic
This approach will let us to rapidly iterate by running everything sandboxed in qemu and we can also put our test programs inside the
initramfs. If you don’t know how to create an
initramfs check this.