How to write MBR code

According to Ralf Brown's interrupt list, here's what happens when you boot your PC:
	Usually, the BIOS will try to read sector 1, head 0, track 0 from drive
	  A: to 0000h:7C00h.  If this fails, and a hard disk is installed, the
	  BIOS will read sector 1, head 0, track 0 of the first hard disk.
	  This sector should contain a master bootstrap loader and a partition
	  table (see #0547).  After loading the master boot sector at
	  0000h:7C00h, the master bootstrap loader is given control.  It will
	  scan the partition table for an active partition, and will then load
	  the operating system's bootstrap loader (contained in the first
	  sector of the active partition) and give it control.
	  
Format of hard disk master boot sector:
Offset	Size	Description	(Table 0547)
 00h 446 BYTEs	Master bootstrap loader code
1BEh 16 BYTEs	partition record for partition 1 (see #0548)
1CEh 16 BYTEs	partition record for partition 2
1DEh 16 BYTEs	partition record for partition 3
1EEh 16 BYTEs	partition record for partition 4
1FEh	WORD	signature, AA55h indicates valid boot block

Okay, so there are 446 bytes of code in a standard MBR which scan the partition table and load the bootstrap loader for an operating system. The bootstrap loader then goes off and loads the operating system.

Here are the steps of exactly what occurs for a standard DOS/Win95 MBR loader (determined by disassembling the MBR):

  1. The BIOS loads the MBR (512 bytes) to 0:7C00
  2. The BIOS executes the MBR (sets CS:IP to 0:7C00)
  3. The DOS MBR code sets SS:SP to 0:7C00 (remember, the stack 'grows' downwards)
  4. The DOS MBR code moves itself to 0:61B and jumps to 0:61B (necessary because of step 6)
  5. The DOS MBR code scans the partition table for an active partition
  6. The DOS MBR code loads the first sector (512 bytes) of the active partition to 0:7C00
  7. The DOS MBR code jumps to 0:7C00 to start executing the operating system bootstrap loader

To install your own MBR code, the simplest thing to do is read the existing MBR to a buffer, copy 446 bytes of instructions to the start of the buffer, and write the buffer back out. This way, the partition table is not destroyed, and you don't have to worry about setting the last two bytes of the sector to 55h, AAh (these two bytes are required otherwise the BIOS will not boot from the hard disk).

However, the problem is how do you then load the bootstrap loader from the first active partition? Easy! You keep the original MBR as well! When you install your own MBR code, you save the original MBR somewhere, for example, sector 2, head 0, track 0. In case you don't know, only the first sector on head 0, track 0 (the MBR) is used (unless you have a virus or some security program installed). The first partition starts at sector 1, head 1, track 0.

Then, when your MBR code is executed, it does whatever it needs to do, then loads the original MBR to 0:7C00 and executes it!

Other points to keep in mind:

I recommend you also read this, which explains how to do the same thing for a drive boot sector (A:, C:, etc).
© ztank
February 1999