Tutorial – Building a Simple Boot Sector on OS X

A quick Google search on “boot sector tutorial” or “boot loader tutorial” yields slightly less than 1 kazillion matches. Folks, there’s a lot of information out there on how to write a boot sector.

If I ever hope to have a chance at finishing my own OS, I know that I will need to stand on the shoulders of those that have come before me. Some developers choose to reinvent the wheel rather than reuse freely available source code by others, but I’m not one of them. I prefer to take a pragmatic approach – I figure that if I try to write every single line of code without assistance, I’ll finish my operating system in around 156 years. That is, if I don’t go mad first.

That said, I found several good resources on the net that I used to guide me when creating a simple boot sector. And I mean simple – all this thing does is print a message to the screen before entering an infinite loop.

OK – first let me link to a helpful resource that I found and used when running my boot loader test. Robbert Haarman has put up some helpful x86 Development Tutorials on his website. He walks you through the steps to create a simple boot sector and a simple kernel (both written in assembly), and even shows keyboard support and starts getting in to system calls. As he goes, he explains some concepts you’ll need to know along the way. Unfortunately, he wrote these tutorials in 2005 and hasn’t continued on with the series. I enjoyed reading these and found them very helpful, so I wish there were more.

Like I said, for my first project I just wanted to get a simple boot sector to boot on the emulator that I have chosen to target – Q (Qemu on OS X). Q is basically a the QEmu emulator wrapped in a nice Cocoa interface.

First, let me show you the source code for the simple boot sector. I’ve seen variations of this code on countless sites – who knows who wrote it originally.

push word 0b800h
pop es
xor di, di
mov [es:di], word 441h

jmp $

times 510 – ($ – $$) db 0

db 55h
db 0aah

Copy the above code and paste it into a text file named bootsect.asm. I’m not going to go into depth about what each instruction in this code does – the point of this tutorial is to describe the tools and steps necessary to compile a boot sector and get in running on the emulator. We’ll get into the boot sector code at a later date, but at a high level, this code will compile into a binary that is 512 bytes in size. When it runs, it will display a red A in the upper left corner of the screen and then enter an infinite loop. If we see the red A, all is good.

As I mentioned before, I’m using Nasm as my assembler. I was pleased to discover that nasm (v 0.98.40) is already installed on my Mac. Thanks, Apple!

When we’re building a boot sector, we aren’t building a typical executable program – so we want to compile it to a flat binary file. Nasm can output other executable formats, such as ELF, a.out, PE, etc, but for the boot loader, we’re only concerned with flat binaries. This is the default output format for nasm, so you could leave out the target format (the -f flag), but to be explicit, run the following command:

nasm bootsect.asm -f bin -o bootsect.bin

This tells nasm to compile the bootsect.asm file into a flat binary file.

For this exercise, we want to create a disk image that could be written to a 3.5″ floppy disk (remember those?). For creating disk images and reading/writing to files at a low level, we’ll use the dd command. To create a disk image for a 3.5″ floppy disk, enter the following command:

dd if=/dev/zero of=floppy.img bs=512 count=2880

This says – create an output file named floppy.img, containing 2880 blocks, each block having a size of 512 bytes. We’ll fill the image with all zeroes, which we get from reading our input file: /dev/zero.

Now we need to insert our boot sector into our floppy disk image. The boot sector should be placed at the very beginning of the file. Again, we’ll use dd:

dd if=bootsect.bin of=floppy.img conv=notrunc

This says – write the contents of input file bootsect.bin to the start of output file floppy.img. The conv=notrunc tells dd to preserve the existing size of the output file instead of truncating it to the size of the input file.

OK – that’s all we need to do to make our disk image. Nasm and dd make it pretty easy.

Now we need to setup our virtual machine on Q. If you don’t yet have Q, you can grab it from the Q website. Once you’ve installed it, launch Q. To add a virtual machine, click on the big yellow plus button. Then you can name your virtual machine. Since we’re installing a custom OS (as opposed to Windows or Linux), we’ll choose Q Standard Guest as our OS.

Adding a New Virtual Machine to Q

Now we need to configure our machine. Since this is a very simple boot loader, we don’t need to the virtual machine to have networking, a lot of RAM, or even a hard disk drive. All we need is a floppy disk. Here are screenshots from the other steps of the new VM configuration.

General Tab

Advanced Tab

The important tab for our purposes today is the Hardware tab.

Remember, we created a disk image for a 3.5″ floppy, so let’s set up the virtual machine to boot from floppy. Be sure to specify that we want to boot from floppy. For our floppy drive, select “choose imagefile” and select the floppy.img file that we created earlier.

Hardware Tab - set it up to boot from our floppy disk image

Important Tip – Q will only allow you to select image files that have the .img file extension. If you build an image file, but give it an extension that is something other than .img, Q won’t let you pick it. Don’t make the same mistake I did.

OK – now for the moment of truth. Once you’ve got all your settings correct, click on the Update PC button to save them. This will take you back to the Q Control screen, and you’ll see your new VM in the list. To start up your VM, double-click on your machine name or click the play button. If you’ve done everything properly, you’ll see a new window open that looks like this:

Q - Booting our VM from our Floppy Image!

There it is – our red A in the upper left corner of the screen (we wrote over the massages displayed by the emulated BIOS).

Success! Take a few moments and savor the thrill.

Obviously, our boot sector at this point is essentially useless, but we’ve learned how to compile our boot sector assembly code into a binary, place that binary into a floppy disk image file, and boot our virtual PC using that image. Not a bad piece of work.

This is an old article but since it seems to show up in search results:
If anyone else is getting this error when assembling, it’s probably because you copied&pasted the code.
The problem is the dashes on this line:
times 510 – ($ – $$) db 0
They are unicode “EN DASH” (0x2013), not the standard hyphen (0x002D).
Simply delete them and replace them with a normal hyphen/minus.