Modify, compile and execute a Linux Kernel in QEMU

November 30, 2015

I wanted to modify the Linux Kernel and execute it in QEMU. After multiple hours of searching the web, reading poor guides, tracking debian package bugs and hacking I finally found a way to do that. In the end it is quite simple...

Things you need

  • a Linux Kernel of our choice
  • for the make menuconfig you need ncurses dev package, for ubuntu it is libncurses5-dev
  • a installed QEMU for the emulation
  • a GCC version that is able to compile your kernel version (the newest gcc should work for the newer kernel versions, however I needed gcc 4.9 for kernel 3.6.2)
  • mkinitramfs generates a initial filesystem on Ubuntu which can be used by QEMU

Get the kernel files

Go to kernel.org, download a kernel and extract it.

$ wget https://cdn.kernel.org/pub/linux/kernel/v3.x/linux-3.6.2.tar.gz
$ tar -xvf linux-3.6.2.tar.gz 

Optional: modify / patch the Kernel

This applies a patch to the kernel. You can check the detailed changes in the file if you want to.

$ patch --directory linux-3.6.2/ -p1 < some-kernel-patch-3.6.2_aesni

Make menuconfig

Switch to the linux directory and execute menuconfig. There you can enable and disable all the modules you want.

$ cd linux-3.6.2
linux-3-6-2$ make menuconfig

Compile the kernel

linux-3-6-2$ make -j 4 bzImage

I need to compile with the older gcc version, so I typed:

linux-3-6-2$ make -j 4 CC=/usr/bin/gcc-4.9 bzImage

The -j 4 executes 4 parallel make recipes at once. So it runs quicker. My PC needed about 3 minutes to compile. This command generated a bzimage file in linux-3.6.2/arch/x86/boot. This file is a compiled image of the kernel.

Create initial file system

Switch to the location of the bzimage and call mkinitramfs there. The initial filesystem is needed to execute the kernel.

linux-3-6-2$ cd arch/x86/boot/
linux-3.6.2/arch/x86/boot$ mkinitramfs -o initrd.img-3.6.2

This generates a initrd.img-3.6.2 file in that directory.

Start QEMU

Now we can start QEMU with our custom kernel and the initial file system on 1GB of RAM.

linux-3.6.2/arch/x86/boot$ qemu-system-x86_64 -kernel bzImage -initrd initrd.img-3.6.2 -m 1GB

This should open a window with the running BusyBox Linux:

Photo