Hard drive won't boot?

Lost partitions?

Let us help!

MBR & Boot Sector Repair

Master Boot Record

Following the Power On Self Test (POST) and possibly other housekeeping functions the BIOS startup code on a PC compatible computer calls the interrupt 19 Bootstrap Loader.

The Loader reads the initial sector (LBA 0) of the boot drive to memory at 0:7C00h, and checks for the system sector signature (55AAh) at offset 1FEh. If the signature is found, the loader jumps to 0:7C00h, and program execution continues from that point.

If the boot drive is a hard disk or a device, such as a flash drive, emulating a hard disk, then this sector will be a Master Boot Record.

[Note: if the Bootstrap Loader cannot access the boot drive, or if the
signature is not found, it moves on to the next device in the boot priority
list and repeats the process. If no valid boot sector is found on the
system, the Loader issues an error message, usually something on the order
of "No Operating System," dependent on the BIOS version involved.]

There are a great many different examples of MBR code, depending on the
operating system and version that install the MBR. Also, there are many
custom MBRs which perform such functions as boot sector virus detection or
multi-booting.

All MBRs, however, have a similar structure: a small bootstrap program at
the beginning (though the bootstrap code my spill off onto additional disk
sectors) followed by a "partition table," which consists of four 16 byte
partition records.

Partition Record Layout
     
00h Byte Active flag. Will be = 80h if partition is bootable, otherwise should = 0.
01h Byte Starting head number (0 to 254)
02h Word Starting cylinder (0 to 1023) & sector (1 to 63) number
04h Byte Partition type
05h Byte Ending head number (0 to 254)
06h Word Ending cylinder (0 to 1023) & sector (1 to 63) number
08h Dword Offset to start of partition
0Ch Dword Total number of sectors in partition
This article examines the MBR installed by the FDISK.EXE program delivered with MSDOS version 7.1.

Hex/ASCII Dump of Master Boot Record

Like all more or less "standard" MBRs, this one does just three rather simple things: relocates itself in memory (necessary because it will copy the active partition's boot sector to the same memory location (0:7C00h) it initially occupies), scans the partition table to locate the active partition, then copies the active partition's boot sector to memory and jumps to it.

It also reports error occurances. There are five possible errors:

Error

Indication

Corrupt partition table (value other that 0 or 80h found the active byte of a partition record) Hangs in loop (no message printed to screen)
No active partition Calls ROM BASIC
Invalid partition table (more than one active partition) Prints "Invalid Partition Table" to screen, hangs
Active partition boot sector not found Prints "Missing operating system" to screen, hangs
Error reading active partition boot sector Prints "Error loading operating" to screen, hangs

The occurance of any of these errors or (more commonly) the "Operating system not found" error, which indicates the MBR is corrupted, will require the intervention of partition recovery expertise in order to correct the problem.

For readers with an interest in the technical details of the Master Boot Record, a disassembly follows:

RELOCATION: The MBR's loader code begins by setting up a stack
at 0:7c00, then the MBR (except for the relocation code at
0:7c00 - 0:7c1a) is relocated to 0:061b, and operation resumes
at the new location.
7C00    xor ax,ax               ;zero ax
7C02    mov ss,ax               ;ss = 0
7C04    mov sp,07c00            ;stack @ 0:7c00
7C07    sti                     ;enable interrupts
7C08    push ax                 ;zero on stack
7C09    pop es                  ;es = 0
7C0A    push ax                 ;zero on stack
7C0B    pop ds                  ;ds = 0
7C0C    cld                     ;clear direction
7C0D    mov si,07c1b            ;source index = 7c1b
7C10    mov di,061b             ;dest index = 61b
7C13    push ax                 ;segment for retf = 0
7C14    push di                 ;offset for retf = 61b
7C15    mov cx,01e5             ;1e5 bytes to move
7C18    rep movsb               ;relocate the MBR
7C1A    retf                    ;jump to relocated MBR
SCAN PARTITION TABLE: the source index register (si) is set to
point to the "active flag" byte of the first partition record
(at offset 7BEh) in the MBR's partition table. The loader code
loops, checking the active flag of each record. 
       
061B    mov si,07be             ;point si to first partition active flag
061E    mov cl,4                ;4 partition records to examine
0620    cmp b[si],ch            ;compare active flag to zero
0622    jl 062d                 ;jump if bit 7 of active flag set
If jl tests true here, we have an active partition.
0624    jne 061b                ;hang computer in loop (bad flag)
Otherwise, the value of the must be zero, else the partition record
is corrupt. In that case the code goes into a loop and hangs the
system. 
0626    add si,010              ;point to next record
0629    loop 0620               ;test next record
062B    int 018                 ;call ROM BASIC if no active partition
If no active partition is found in the partition table, a call is
made to ROM BASIC. This will normally result in "No ROM BASIC" being
displayed on the screen with the sytem hung.
062D    mov dx,w[si]            ;drive & head numbers to dx
We have found an active partition. The drive (80h) and head (usually 1)
are loaded in the dx register. Now check to be sure that the remaining
active flags are set to zero.
062F    mov bp,si               ;bp points to active partition entry
0631    add si,010              ;point to next entry
0634    dec cx                  ;decrement loop counter
0635    je 064d                 ;jump if finished
Finished testing active flags. Now go and read the active partition
boot sector to memory.
0637    cmp b[si],ch            ;active byte = 0?
0639    je 0631                 ;if so, check next entry
If we get here, a spurious (non-zero) active flag was found. The
MBR code now displays "Invalid Partition Table" and hangs.
Print error message:
063B    mov si,0710             ;si points to error msg string
063E    dec si                  ;adjust
063F    lodsb                   ;get next character in al
0640    cmp al,0                ;end of string?
0642    je 063e                 ;if so, hang
0644    mov bx,7                ;color white on black
0647    mov ah,0e               ;print character function
0649    int 010                 ;print the char
064B    jmp 063f                ;print next char
READ BOOT SECTOR:
Now we are ready to read the active partition's boot sector to
memory. First, we need to determine whether to use CHS addressing
or the BIOS interrupt 13 LBA extensions. The LBA extensions are
used for partition types 0ch (FAT32 LBA), 0eh (FAT16 LBA).
064D    mov w[bp+025],ax        ;ax is = 0 here
0650    xchg ax,si              ;si = 0
0651    mov al,b[bp+4]          ;al = partition type
0654    mov ah,6                ;ah = 6
0656    cmp al,0e               ;partition type 0e?
0658    je 066b                 ;if so, jump
065A    mov ah,0b               ;ah = 0b
065C    cmp al,0c               ;partition type 0c?
065E    je 0665                 ;if so, jump
0660    cmp al,ah               ;partition type 0b?
0662    jne 068f                ;jump if not
0664    inc ax                  ;resets zero flag
0665    mov b[bp+025],6         ;marker
0669    jne 068f                ;jump
if the partition type is 0c or 0e, then we need to check if the int 13
BIOS extensions are supported.
066B    mov bx,055aa            ;per int 13 ah = 41
066E    push ax                 ;save ax on stack
066F    mov ah,041              ;this function is an installation
                                ; check for the int 13 BIOS extension
0671    int 013                 ;BIOS disk i/o
0673    pop ax                  ;restore ax
0674    jb 068c                 ;jump if error occurred
0676    cmp bx,0aa55            ;extensions supported?
067A    jne 068c                ;jump if not
067C    test cl,1               ;disk access functions supported?
067F    je 068c                 ;jump if not
0681    mov ah,al               ;partition type to ah
0683    mov b[bp+024],dl        ;drive no.
0686    mov w[06a1],01eeb       ;patch code with jump to 06c1
068C    mov b[bp+4],ah          ;overwrite partition type
We will enter here, skipping the BIOS extensions tests, if the
partition type is other than 0c or 0e.
068F    mov di,0a               ;di=0a
0692    mov ax,0201             ;int 13 read 1 sector
0695    mov bx,sp               ;stack pointer to bx
0697    xor cx,cx               ;zero cx
0699    cmp di,5                ;compare
069C    jg 06a1                 ;jump if di > 5
069E    mov cx,w[bp+025]        ;will be 0 or 6
If the BIOS Interrupt 13 extensions are in use, this instruction
will have been overwritten with jmp 06c1. If CHS addressing
is in use, on the other hand, we will proceed as follows.
06A1    add cx,w[bp+2]          ;start cyl/sector of partition
06A4    int 013                 ;read sector to 0:7c00
06A6    jb 06d1                 ;jump if error occurred
06A8    mov si,0746             ;pointer to error message
Message is "Missing operating system"
06AB    cmp w[07dfe],0aa55      ;system signature present?
06B1    je 070d                 ;jump if so
06B3    sub di,5                ;else decrement di
06B6    jg 0692                 ; and try again
06B8    test si                 ;si = 0?
06BA    jne 063f                ;go print error msg if not
06BC    mov si,0727             ;pointer to error msg
Message will be "Error loading operating system"
06BF    jmp 064b                ;go print message
06C1    cbw                     ;ah = 0
06C2    xchg ax,cx              ;cx = 1, ax = 0
06C3    push dx                 ;save dx
06C4    cwd                     ;dx = 0
06C5    add ax,w[bp+8]          ;move "relative sectors"
06C8    adc dx,w[bp+0a]         ; to ax/dx
06CB    call 06e0               ;read the sector
06CE    pop dx                  ;restore dx
06CF    jmp 06a6                ;test for error & system sig
Error handler for int 13 reads:
06D1    dec di                  ;decrement retry counter
06D2    je 06b8                 ;if zero go print error msg
06D4    xor ax,ax               ;zero ax
06D6    int 013                 ;reset disk drive
06D8    jmp 0692                ;retry read
06DA    db... (6 bytes)         ;Windows inserts a drive identifier here
06E0    push si                 ;save si
06E1    xor si,si               ;zero si 
06E3    push si                 ;LBA of 
06E4    push si                 ; first block
06E5    push dx                 ; to read -    
06E6    push ax                 ; qword   
06E7    push es                 ;disk i/o
06E8    push bx                 ; buffer
06E9    push cx                 ;blocks to transfer
06EA    mov si,010              ;si = 10
06ED    push si                 ;save on stack
06EE    mov si,sp               ;si = sp
06F0    push ax                 ;save registers
06F1    push dx                 ;    .
06F2    mov ax,04200            ;extd int 13 read
06F5    mov dl,b[bp+024]        ;drive no.
06F8    int 013                 ;read
06FA    pop dx                  ;restore registers
06FB    pop ax                  ;    .
06FC    lea sp,[si+010]         ;adjust stack pointer
06FF    jb 070b                 ;jump if error occurred
0701    inc ax                  ;increment ax
0702    jne 0705                ;jump if not zero
0704    inc dx                  ;increment dx
0705    add bh,2                ;add 200h to buffer offset
0708    loop 0701               ;
070A    clc                     ;clear carry
070B    pop si                  ;restore si
070C    ret                     ;return
070D    jmp 0783h
070F    db 'Invalid partition table',0
0727    db 'Error loading operating system',0
0746    db 'Missing operating system',0
075F    db...                   ;unused area
0783    mov di,sp               ;stack pointer to di
0785    push ds                 ;seg for retf
0786    push di                 ;offst for retf
0787    mov si,bp               ;si points to active partition record
0789    retf                    ;jump to DBR boot code
0790    db...                   ;unused area
07BE                            ;partition table goes here
07FE   dw 0AA55                 ;system signature