As of a few weeks ago I was very new to boot loaders. Of course I used them but it was just as a conciquence of installers and that's how a OS set things up. But over the last few weeks I've had to deal with them a lot, booting multiboot compliant operating systems that must be booted over a network. Anyways those tales are for another time but I was starting to work on some kernel development and wanted a quick and easy way to make grub bootable images. I found QEMU to be a great way to do this without requiring another computer, a grub boot disk, etc... In addition to this I am on an AMD_64 system and as of late compiling GRUB Legacy has been a big pain do to many issues, perhaps most significant build failures citing Binutil issues. With that said GRUB Legacy has been placed in a dark shadow like a poor puppy beaten to death. Even though I am new to the world of boot loaders my recent experience has given GRUB Legacy a place in my heart. This could be because it upholds the original multiboot specifications, it's relatively light (once on target), boot scripts are cake to setup and it even includes abilities to PXE boot (it works, I've done it!).
So since I'm on a recent version of Linux (Ubuntu 10.04 64-bit) I can't get GRUB Legacy, referred to simply as grub from now on, to compile. After trying to work around and fix grub I decided my time would be better spent on other matters. I gave up, downloaded Oracle VM Virtual Box and a prebuilt and setup image of Ubuntu 8.04. I can confirm that Ubuntu 8.04 will build Grub 0.97, including pxegrub but you will need to apply a patch first.
Just in case site the above linked patch on linuxmce.org quits working, I've shamelessly reposted it here.
patch -Np1 << EOF --- grub-0.97.orig/netboot/main.c 2004-05-21 00:19:33.000000000 +0200 +++ grub-0.97/netboot/main.c 2007-07-20 02:31:28.000000000 +0200 @@ -54,9 +54,9 @@ static int vendorext_isvalid; static unsigned long netmask; -static struct bootpd_t bootp_data; +struct bootpd_t bootp_data; static unsigned long xid; -static unsigned char *end_of_rfc1533 = NULL; +unsigned char *end_of_rfc1533 = NULL; #ifndef NO_DHCP_SUPPORT #endif /* NO_DHCP_SUPPORT */ EOF
After grub has been patched simply follow the instructions in the INSTALL file, if your looking to do a pxegrub as I mentioned earlier check out /netboot/README.netboot. For a standard grub build, here is how I did it.
# mkdir build && cd build && ../configure --prefix=$HOME/src/grub && make && make install
You should now have a new grub directory at the same level as the source directory.
Somewhere that is conveinent for you, create a boot/grub file structure.
# mkdir -p boot/grub
The -p option tells mkdir to create the needed file structure to create the final directory if it does not already exist.
In the newly created boot/grub directory copy stage1 and stage2 from your grub install directory, grub/lib/grub/i386-pc build directory.
Then in a convienant location outside of the newly created boot directory concatenate the stage files together.
# cat stage1 stage2 > boot.img
By default, concatenate (cat) outputs to standard out so the > redirects the standard output to the file boot.img.
Now we need to create a "blank" disk image, for this example we will be creating a floppy.
# dd if=/dev/zero of=floppy.fdd bs=512 count=2880
Disk Dump (dd) copies a file, or system, as specified. In this case we are copying 512 bytes 2880 times. These numbers are not hard to remember for a floppy if we recall the "erroneous" measure of a 1.44Mb for a 3.5" floppy disk. $512 \times 2 = 1024$ and $\frac{2880}{2}=1440$. $2^10=1024$, a common number in computers and you can now see why a 1.44Mb floppy is now called what it is, even if it isn't really 1.44Mb. Anyways... Input file is defined by if and output file is defined by of. The device "zero" provides as many NULL characters (0x00) that we read/request from it.
If you completed the last step you know have an unformatted floppy image, now lets format it.
# mke2fs floppy.fdd
mke2fs formats a disk, or image, with the ext2 files system.
Now we can mount this image to the files system, make changes to it, and when we unmount it the floppy.fdd file will contain the changes we made to the file. In our case, the changes will be moving the /boot/grub folder and it's contents to it.
# sudo mount -o loop floppy.fdd /media/floppy # cp -r boot /media/floppy # chmod a-w /media/floppy/boot/grub/stage2 # sudo umount /media/floppy
If /media/floppy doesn't exist you might look under /mnt or you can just make the directory under your root mount directory structure as root.
The -o loop option specifies the "loop back" mount point, google it and "man" the mount command if you have questions. The -r option in the copy command copies recursively. chmod a-w makes stage2 read only which is important because the soon to be loaded boot record needs to know exactly on the "physical" disk that file begins so that it can "point" to it.
So we basically have created two "end" files, floppy.fdd and boot.img. We will need both of these to make a truly bootable floppy image that we can actually put on a floppy or use for other purposes. This is where QEMU comes in. See QEMU can boot boot.img directly and since it can also read image files we can also pass it our floppy.fdd file. The whole point of using QEMU is so that we can execute the binary executable in our built version of grub where it has a setup utility that will properly configure a disk to be bootable, it writes the boot sector. If you were doing this on a 32-bit version of linux you could just run it from the boot directory but this can be very dangerous if you don't know what your doing. The danger is that you could accidentally and vary easily write the boot information to your computer's drive and potentially make it where it wouldn't boot without some additional work. Personally I would now feel comfortable executing the grub utility on my active computer, though dangerous, I now know enough about how grub works to not be too worried if I'm careful but I still wouldn't do it hungover. So QEMU offers an alternative for 64-bit users and an added level of protection while simultaneously offering the convenience of making a bootable grub image without a physical computer and an existing grub boot disk. Enough with the talk, if I didn't explain well enough what I was trying to just follow these next few steps and it should set in by the time we're through.
Assuming that you have already installed qemu and can execute it from the command line, execute
# qemu -fda boot.img -fdb floppy.fdd -boot a
Within a second or two of pushing enter you should have a window with a grub prompt. At this prompt try the following,
> find /boot/grub/stage2
If you get a file not found, go back and make sure you did everything correct if you get a (fd1) instead everything is good and your ready to proceed with the next command.
> setup (fd1)
You should see some messages about 4-6 lines long and if there is nothing scary then things went well and you have successfully made a bootable grub floppy image.
So if your on a 32-bit machine you can actually execute grub, ./grub, and that command prompt will come up from your terminal window and you can tell grub to setup a disk but the problem is you don't know what disk it is because grub references disks based off their disk number and partition number so it could be potentially easy to pick the wrong disk and have it damage your boot record.
So if you were to load floppy.fdd in another simulator like AMD's SimNow or if you were to dd to an actual floppy and stick it into a computer and reboot you should arrive at a grub prompt. Now if your wanting a menu, like grub is often seen with, you will need to create a menu.lst file inside the boot/grub folder on the image. You can do this before or after running the grub setup. Just use the mount method, you likely won't mess anything up since we essentially locked the important stage2 file with the chmod a-w command. For more information on writing menu.lst files do some google searching or read the grub documentation. If your searching on the internet you might want to use the keywords "grub legacy" as there is a lot of GRUB2 stuff out their now and that could be confusing for you.
So what other stuff can you do with this grub disk image? Have you ever been interested in writing your own operating system? You might want to check out neuraldk's "kernel" tutorial.
Now we need to create a floppy disk image.
Comments
Post new comment