So I took on a new challenge, understanding how to develop your own Master Boot Record (MBR). So how do you start to develop your own bootloader? The first answer that came into mind was the setup of a development environment. No development environment , no bootloader. Actually that’s my thought on every new coding project I undertake. In this blog post I’m going to explain the steps I went through and why I finally choose for a somewhat rather basic development environment. Anyways let’s get started.
p.s. Happy New Year
p.s.2. HACK THE PLANET!!!
First of all I needed to understand the details of the stuff I was about to dive into. So before even thinking about how to setup a development environment I had to look up some info about the subjects I was going to be dealing with, some of them where a nice refreshment read while other where new and interesting:
- Boot Process
- Bios Interrupts
- Harddisk Geometry
- Intel 64 and IA-32 Architectures Software Developer’s Manual (intel website)
- Volume 1: Basic Architecture
Now that’s a lot of material to read, all of it necessary if you don’t know it, specially the details of it.So now that we have a good understanding of the material we will be working with we can start on the process of building the development environment. There are several requirement that I deem necessary before I consider it a development environment myself, although I recommend everyone to define their own requirement.
- Ease of source deployment & testing
- Ease of debugging
- It’s got to be cheap
I found three ways(there are probably a zillion ways) that meet my requirements of setting up a development environment for bootloader development.
The first one
Seems to be the easiest, also because you have the possibility to write it in C++, is explained on the following link:
Now that’s a pretty easy and straightforward way of performing bootloader development. It also shows you how to mix assembly and c++. I think it’s a great way of setting up your development environment, it doesn’t meet my requirements though, because as far as I know vmware does not support debugging of the boot process. So you are kind of in the dark when testing our code. It does however follow a very nice way to develop your bootloader in a structured and high-level way.
The Second one
Now this one is actually a new IDA Pro feature, so it has the debugging and disassembling power of IDA, explained over here:
Intermediately it becomes clear this method uses BOCHS as an emulator instead of vmware. Now this is sexy stuff, IDA seems to integrate in a very nice and good way with BOCHS. So you can just write your bootloader code, put it on the virtual disk and then just start debugging it with IDA. Sexy huh? It also becomes clear (the last screenshot) that the bootloader is developed directly in assembly. The only downside is that you have to pay a fair amount of money for IDA(worth every penny though!). Since I’m just playing around and learning about bootloader development this method also doesn’t meet my requirements.
The Third and final one
During my search I realized a few extra things:
- I want to understand as much as possible about bootloader development
- I want to stay as low level as possible
So I then decided to go the ‘old skool’ way. Do all the steps manually and just write some scripts to put it all together in a semi-automated process. The decisions to do it all manually was because you then encounter problems and interesting stuff you usually don’t encounter when you have some application doing stuff for you.Here is my development environment:
- Notetpad++ to code the assembly in (link)
- Bochs for the emulation (link)
- A visual debugger for BOCHS (link)
- Python to copy the bootloader to the virtual hard disk(borrowed from the IDA Pro blog entry)
- A BAT file to glue it all together
I downloaded BOCHS and used the shipped mini-linux(called dlxlinux) example to start my experimenting. Copied it all over to a new folder called ‘bootloader’ and added the following line to the file bochsrc.bxrc:
display_library: win32, options=”windebug”
I then downloaded the visual debugger and put it in the bootloader folder. Then I copied the python code from the IDA Pro blog entry and modified it so it only read the first 512bytes. I’m to lazy to put it on pastebin this time, so you’ll have to fix the indentation yourself.
#!/usr/bin/env python # DiabloHorn MBR Development Environment #copied from: http://hexblog.com/2009/09/develop_your_master_boot_recor.html , hope they don't mind. #Adjusted the read function to only read 512bytes import sys if __name__ == "__main__": """ Write the MBR code into the disk image """ # open image file f = open(sys.argv, "r+b") if not f: print "Could not open image file!" sys.exit(0) # open MBR file f2 = open(sys.argv, "rb") if not f2: print "Could not open mbr file!" sys.exit(0) # read whole MBR file mbr = f2.read(512) f2.close() # update image file f.write(mbr) f.close()
The last part was the BAT file to glue it all together. The bat file would compile my assembly source, remove the old compilation and copy the new compilation to the virtual hard disk, then start the visual BOCHS debugger(which implicitly starts BOCHS). So the glue looks like this:
nasm readtc.asm -o bl.img
writembr.py bl.img hd.img
bochs -q -f bochsrc.bxrc
So now I was ready to start developing bootloader stuff. All I needed to do now was, write some code and put it in a file called readtc.asm , then just run the bat file and it would pop up the visual debugger, ready to either debug my code or just hit run and watch the result on the BOCHS screen:
Debugger just started:
Decided to run the code instead of debugging:
The only remaining question is what code should I put inside my assembly file? Lucky for us there are tons of tutorials on how to start writing your first Hello World! bootloader.
That’s it for now, enjoy and keep spreading knowledge!