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
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.
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: