Creating GRUB virtual floppy image
I’m was playing with writing my own kernel for fun, but the first thing I realized that I don’t need to write my own boot loader thanks to the multiboot specifications[1].
Most tutorials I saw on the Internet were talking about how to install a grub on a physical floppy. Of course no one these days use floppy disks not they have floppy drives on their machines on the first place. This tutorial is inspired by an OSDev article http://wiki.osdev.org/GRUB#Installing_to_floppy.
Creating a grub boot loader disk, two stages are needed. First stage is creating an auxiliary disk. The auxiliary disk is needed to copy stage1 and stage2 of the grub boot loader[2] in block 1 and block2 of the disk. This means we have a bootable disk but the filesystem of the floppy is corrupted. We need a floppy with a fully functional filesystem that we can use to copy our kernel on it. Second step is create the actual boot floppy with a fully functional filesystem. The second floppy is made by using the auxiliary disk. Enough talking and lets go to the practical steps.
Stage 1: Creating Auxiliary Virtual Floppy
1. The very first thing is is to create the virtual image that we are going to work on.
dd bs=512 count=2880 if=/dev/zero of=auxiliary.img
Basically, this command will create a file of 2880 block each one is 512 bytes (remember floppy disk is 1.44MB). Because we are reading from /dev/zero the new file will be initialized to zeros.
2. Copy stage1 and stage2 to the image. This is done with the dd command. But things we have to be aware of. First, stage1 should be in the first block of the disk and stage2 in the second block. Second, dd by default with truncate the floppy image, something definitely we don’t want, so make sure to use conv=notrunc option.
dd if=stage1 of=auxiliary.img bs=512 count=1 conv=notrunc dd if=stage2 of=auxiliary.img bs=512 seek=1 conv=notrunc
You can download a ready made disk from here: auxiliary.img.tar
Stage 2: Making the actual boot disk
1. Same as first stage, we need to create the image file initialized to zeros.
dd bs=512 count=2880 if=/dev/zero of=grubboot.img
2. (Not necessary step, but I like it), Attach the image file that we just creating to a loop device.
sudo losetup /dev/loop1 grubboot.img
By this way we will work our image as an actual block device, rather than just a file. I used this for two reasons. First it’s more convenient to handle block device. Second, when making a file system on a file using mkfs it will complaining about it not being a block device, but still works!
3. Make a filesystem on the boot disk and then mount it. You can choose what ever filesystem you want as long as it’s supported by GRUB!
sudo mkfs /dev/loop1 sudo mount /dev/loop1 /tmp/virtualfloppy
4. Once the filesystem is created and mounted we can play with this little floppy as we want. Now it’s time to create a boot folder and add stage1 and stage2 to it. The other thing we need is a configuration file for grub menu. This file basically tells grub what operating systems exists and from where to load it. Of course to forget to copy your kernel as well. Here I chose to name by kernel kernel.bin and put it on the boot folder.
sudo mkdir /tmp/virtualfloppy/boot sudo chmod o+w /tmp/virtualfloppy/boot sudo cp stage1 /tmp/virtualfloppy/boot sudo cp stage2 /tmp/virtualfloppy/boot echo "title MyOS root (fd0) kernel /boot/kernel.bin" > tmp/boot/menu.cfg
5. We are almost done. Right now we have a floppy with a filesystem and all our files, but not the boot sector. And here comes the role of the auxiliary disk we created on the first stage. First boot using the auxiliary by any virtual machine software you like (I use VirtualBox[3]). If everything is working good you will see a grub prompt on the virtual machine. Now unmount the auxiliary.img and mount the grubboot.img. After doing this type the following command on the grub prompt.
install (fd0)/boot/stage1 (fd0) (fd0)/boot/stage2 (fd0)/boot/menu.cfg
6. And we are done. Just reboot from grubboot.img and your kernel will be running. One thing worth to mention here, this is a really long process to create a virtual bootable floppy but it’s worth it, because once you created the floppy you just copy your kernel again and again without needing to repeat anything from the previous steps. The other thing to mention is, I’m using the legacy GRUB here because I don’t really need the new features on the newer versions of grub I just need something that boots my kernel.
And if you need just a floppy that works by copying your kernel into without going through all steps, download this ready made image but without a kernel: bootfloppy.img.tar
[1] http://www.gnu.org/software/grub/manual/multiboot/multiboot.html
[2] Probably you can find these files installed into your linux, but if not you can download them from heregrubstages.tar.
[3] VirtualBox http://www.virtualbox.org/
Leave a Reply