Category Archives: qemu

Using GRUB and QEMU with TFTP

GRUB boot-loader and QEMU virtual machine are two invaluable tools for any OS developer. GRUB greatly simplifies your OS boot-up mechanism. All you need to do is, make your OS kernel binary multi-boot complaint. This can be done very very easily, within one hour of work. And QEMU gives an easy and fast, PC compatible virtual machine to experiment your OS with. No rebooting your machine every time your kernel crashes 🙂

In this post, i will tell you how to setup an efficient testing environment with QEMU and GRUB for your OS development. We make use of QEMU’s user-mode networking and TFTP features with GRUB’s network boot magic.

For booting QEMU virtual machine, we need a boot-disk. A GRUB boot-disk can be created very easily using the below command:

    cat /usr/lib/grub/i386-pc/stage{1,2} > bootdisk.img

You can test this image using QEMU by simply running the below command. Once the virtual machine starts, you will be stopped at GRUB command-line prompt and you can enter GRUB commands.

    $ qemu bootdisk.img

Now you can check whether your GRUB has network boot support or not using dhcp or bootp GRUB commands. If GRUB cribs with invalid command message, it means your GNU/Linux distribution has GRUB installed with network boot support disabled. In this case, you can download and compile GRUB manually with network boot options enabled as shown below:

    $ wget ftp://alpha.gnu.org/gnu/grub/grub-0.97.tar.gz
    $ tar xzf grub-0.97.tar.gz
    $ cd grub-0.97
    $ ./configure --enable-ne
    $ make

If you are not able to build GRUB using above commands then, you might be using a newer version of GCC compiler. Try compiling with gcc-3.4 compiler. Once you built GRUB with network support, you need to rebuild the bootdisk.img using stage{1,2} files from the current build directory as shown below:

    $ cat stage1/stage1 stage2/stage2 > bootdisk.img

This bootdisk.img should have GRUB with network boot support enabled for NE2000 ISA network card. You can start QEMU virtual machine with this network card and built-in TFTP server using below command:

    $ qemu bootdisk.img -net nic,model=ne2k_isa -net user -tftp TFTP-ROOT-DIR

The “-net user” option tells the QEMU to enable internal DHCP server, so that GRUB can get a valid IP address to talk TFTP protocol. The TFTP-ROOT-DIR can be any directory within your host system, where you should place your OS kernel binaries and modules. Now you can issue commands at GRUB prompt which will fetch your OS binaries using TFTP protocol, as shown below:

    grub> dhcp
    grub> kernel (nd)/path/to/kernel-image
    grub> boot

Above commands will assign a DHCP IP address to virtual machine network card and fetches kernel-image from the host, where path is relative to TFTP-ROOT-DIR directory. Final boot command will pass control to your multiboot complaint OS kernel and your OS starts inside the QEMU virtual machine.

Everything is fine, except that you have to enter GRUB commands manually every time you start your virtual machine, right? Thankfully, there is a way to preset a GRUB commands into the GRUB bootdisk itself using “–enable-preset-menu” configure time option. I leave it for you to explore!

Now what is the advantage of doing all this?

The advantage is, you don’t need to rebuild any boot disk images every time you rebuild your OS kernel. Once you setup your build environment and preset GRUB configuration menu, just run QEMU with proper arguments and GRUB boot disk. Your virtual machine automatically starts with your latest kernel bits!

Yes, build your kernel, run QEMU to try it. Nothing more to do! Have Fun!