MBR (x86): Difference between revisions

From OSDev Wiki
Jump to navigation Jump to search
(9 intermediate revisions by 6 users not shown)
Line 31: Line 31:


* See the [[Partition Table]] article for the format of each partition table entry field.
* See the [[Partition Table]] article for the format of each partition table entry field.
* It is important to remember that the partition table entries are <b>not</b> aligned on (削除) dword (削除ここまで)boundaries.
* It is important to remember that the partition table entries are <b>not</b> aligned on (追記) 32-bit (追記ここまで)boundaries.
* Naming the partition table entries as "First" through "Fourth" is for convenience only. The partition table entries are <b>not</b> required to be in any kind of order.
* Naming the partition table entries as "First" through "Fourth" is for convenience only. The partition table entries are <b>not</b> required to be in any kind of order.
* <b>Any</b> one of the partitions may be "active".
* <b>Any</b> one of the partitions may be "active".
Line 43: Line 43:
! Description
! Description
|-
|-
| (削除) 0 (削除ここまで)
| (追記) 0x000 (追記ここまで)
| (削除) 436 (to 446, if you need a little extra) (削除ここまで)
| (追記) 440<sup>1</sup> (追記ここまで)
| MBR <b>Bootstrap</b> (flat binary executable code)
| MBR <b>Bootstrap</b> (flat binary executable code)
|-
|-
| (削除) 0x1b4 (削除ここまで)
| (追記) 0x1B8 (追記ここまで)
| (削除) 10 (削除ここまで)
| (追記) 4 (追記ここまで)
| Optional "(削除) unique (削除ここまで)" (削除) disk ID (削除ここまで)<sup>(削除) 1 (削除ここまで)</sup>
| Optional "(追記) Unique Disk ID / Signature (追記ここまで)"<sup>(追記) 2 (追記ここまで)</sup>
|-
|-
| (削除) 0x1be (削除ここまで)
| (追記) 0x1BC (追記ここまで)
| (削除) 64 (削除ここまで)
| (追記) 2 (追記ここまで)
| (削除) MBR (削除ここまで)<(削除) b (削除ここまで)>(削除) Partition Table (削除ここまで)</(削除) b (削除ここまで)>(削除) , with 4 entries (below) (削除ここまで)
| (追記) Optional, reserved 0x0000 (追記ここまで)<(追記) sup (追記ここまで)>(追記) 3 (追記ここまで)</(追記) sup (追記ここまで)>
|-
|-
| (削除) 0x1be (削除ここまで)
| (追記) 0x1BE (追記ここまで)
| 16
| 16
| First partition table entry
| First partition table entry
|-
|-
| (削除) 0x1ce (削除ここまで)
| (追記) 0x1CE (追記ここまで)
| 16
| 16
| Second partition table entry
| Second partition table entry
|-
|-
| (削除) 0x1de (削除ここまで)
| (追記) 0x1DE (追記ここまで)
| 16
| 16
| Third partition table entry
| Third partition table entry
|-
|-
| (削除) 0x1ee (削除ここまで)
| (追記) 0x1EE (追記ここまで)
| 16
| 16
| Fourth partition table entry
| Fourth partition table entry
|-
|-
| (削除) 0x1fe (削除ここまで)
| (追記) 0x1FE (追記ここまで)
| 2
| 2
| (0x55, 0xAA) "Valid bootsector" signature bytes
| (0x55, 0xAA) "Valid bootsector" signature bytes
|}
|}


<sup>1</sup> The (削除) 10 (削除ここまで)byte "(削除) unique disk (削除ここまで)ID" (削除) field was never standardized. It can contain anything -- even (削除ここまで)the (削除) tail end of the bootstrap code (削除ここまで).
<sup>1(追記) </sup> This can be extended to 446 bytes if you omit the next 2 optional fields: Disk ID and reserved. (追記ここまで)
(削除) If there are a few empty bytes left in it, it is nice for the disk partitioning software (that writes this MBR sector in the first place) to (削除ここまで)
(削除) try to put unique values into those empty bytes. (削除ここまで)"Unique" in this case means that the IDs of all the drives attached to a particular system
(追記) <sup>2 (追記ここまで)</sup> The (追記) 4 (追記ここまで)byte "(追記) Unique Disk (追記ここまで)ID" (追記) is used by recent Linux and Windows systems to identify (追記ここまで)the (追記) drive (追記ここまで).
"Unique" in this case means that the IDs of all the drives attached to a particular system
are distinct.
are distinct.
(追記) (追記ここまで)
(追記) <sup>3</sup> The 2 byte reserved is usually 0x0000. 0x5A5A means read-only according to https://neosmart.net/wiki/mbr-boot-process/. (追記ここまで)
(追記) (追記ここまで)
(追記) ==Partition table entry format== (追記ここまで)
(追記) {| {{wikitable}} (追記ここまで)
(追記) !Offset<sup>1</sup> (追記ここまで)
(追記) !Size (bytes) (追記ここまで)
(追記) !Description (追記ここまで)
(追記) |- (追記ここまで)
(追記) |0x00 (追記ここまで)
(追記) |1 (追記ここまで)
(追記) |Drive attributes (bit 7 set = active or bootable) (追記ここまで)
(追記) |- (追記ここまで)
(追記) |0x01 (追記ここまで)
(追記) |3 (追記ここまで)
(追記) |CHS Address of partition start (追記ここまで)
(追記) |- (追記ここまで)
(追記) |0x04 (追記ここまで)
(追記) |1 (追記ここまで)
(追記) |Partition type (追記ここまで)
(追記) |- (追記ここまで)
(追記) |0x05 (追記ここまで)
(追記) |3 (追記ここまで)
(追記) |CHS address of last partition sector (追記ここまで)
(追記) |- (追記ここまで)
(追記) |0x08 (追記ここまで)
(追記) |4 (追記ここまで)
(追記) |LBA of partition start (追記ここまで)
(追記) |- (追記ここまで)
(追記) |0x0C (追記ここまで)
(追記) |4 (追記ここまで)
(追記) |Number of sectors in partition (追記ここまで)
(追記) |} (追記ここまで)
(追記) (追記ここまで)
(追記) <sup>1</sup> Relative to the start of the partition entry. (追記ここまで)


==Traditional MBR==
==Traditional MBR==
Line 100: Line 136:
* jump to 0x7c00 -- transferring control to the DOS bootsector.
* jump to 0x7c00 -- transferring control to the DOS bootsector.


(追記) <!--Commented out because rant (追記ここまで)
It is extremely unfortunate and stupid that this MBR loads only one sector of the booted partition. There is no
It is extremely unfortunate and stupid that this MBR loads only one sector of the booted partition. There is no
additional complication to load more than one sector in the code; but doing so makes writing bootloaders <b>much</b> simpler
additional complication to load more than one sector in the code; but doing so makes writing bootloaders <b>much</b> simpler
if, perhaps, 8 sectors are loaded instead. So it may be wise to always replace this old MBR with a custom MBR that loads
if, perhaps, 8 sectors are loaded instead. So it may be wise to always replace this old MBR with a custom MBR that loads
more than one sector, for your OS. DOS/Windows will still boot correctly if more than one sector is loaded.
more than one sector, for your OS. DOS/Windows will still boot correctly if more than one sector is loaded.
(追記) --> (追記ここまで)


==Dual Booting==
==Dual Booting==
Line 159: Line 197:
It is necessary to build an MBR that is exactly 512 bytes long. How this is done depends on your assembler and linker.
It is necessary to build an MBR that is exactly 512 bytes long. How this is done depends on your assembler and linker.
The last 2 bytes must be the special boot pattern (0x55 followed by 0xAA), and as said above, the bootstrap portion of the
The last 2 bytes must be the special boot pattern (0x55 followed by 0xAA), and as said above, the bootstrap portion of the
MBR must be (削除) less than 447 (削除ここまで)bytes long. You must also (削除) copy (削除ここまで)at least one partition table entry (削除) into (削除ここまで)the Partition Table
MBR must be (追記) at most 446 (追記ここまで)bytes long. You must also (追記) put (追記ここまで)at least one partition table entry (追記) in (追記ここまで)the Partition Table
portion of the MBR.
portion of the MBR (追記) -- otherwise some BIOSes will refuse to boot from the disk. This includes most UEFI firmware in BIOS-compatibility (追記ここまで)
(追記) mode (追記ここまで).


===Initial Environment===
===Initial Environment===
Line 195: Line 234:


==x86 Examples==
==x86 Examples==
(追記) Assuming one knows how to read sectors from disk and has setup a function allowing them to do so, and assuming the inputs to said function are: (追記ここまで)
(追記) * EBX - 32-bit LBA Address (追記ここまで)
(追記) * CX - Sector Count (追記ここまで)
(追記) * ES:DI - Buffer (追記ここまで)
(追記) * BYTE [bootDrive] - Drive Number<br /> (追記ここまで)
(追記) An extremely simple MBR complying to the standard could look like: (追記ここまで)
(追記) <syntaxhighlight lang="asm"> (追記ここまで)
(追記) [bits 16] (追記ここまで)
(追記) [org 0x0600] (追記ここまで)
(追記) (追記ここまで)
(追記) start: (追記ここまで)
(追記) cli ; We do not want to be interrupted (追記ここまで)
(追記) xor ax, ax ; 0 AX (追記ここまで)
(追記) mov ds, ax ; Set Data Segment to 0 (追記ここまで)
(追記) mov es, ax ; Set Extra Segment to 0 (追記ここまで)
(追記) mov ss, ax ; Set Stack Segment to 0 (追記ここまで)
(追記) mov sp, ax ; Set Stack Pointer to 0 (追記ここまで)
(追記) .CopyLower: (追記ここまで)
(追記) mov cx, 0x0100 ; 256 WORDs in MBR (追記ここまで)
(追記) mov si, 0x7C00 ; Current MBR Address (追記ここまで)
(追記) mov di, 0x0600 ; New MBR Address (追記ここまで)
(追記) rep movsw ; Copy MBR (追記ここまで)
(追記) jmp 0:LowStart ; Jump to new Address (追記ここまで)
(追記) (追記ここまで)
(追記) LowStart: (追記ここまで)
(追記) sti ; Start interrupts (追記ここまで)
(追記) mov BYTE [bootDrive], dl ; Save BootDrive (追記ここまで)
(追記) .CheckPartitions: ; Check Partition Table For Bootable Partition (追記ここまで)
(追記) mov bx, PT1 ; Base = Partition Table Entry 1 (追記ここまで)
(追記) mov cx, 4 ; There are 4 Partition Table Entries (追記ここまで)
(追記) .CKPTloop: (追記ここまで)
(追記) mov al, BYTE [bx] ; Get Boot indicator bit flag (追記ここまで)
(追記) test al, 0x80 ; Check For Active Bit (追記ここまで)
(追記) jnz .CKPTFound ; We Found an Active Partition (追記ここまで)
(追記) add bx, 0x10 ; Partition Table Entry is 16 Bytes (追記ここまで)
(追記) dec cx ; Decrement Counter (追記ここまで)
(追記) jnz .CKPTloop ; Loop (追記ここまで)
(追記) jmp ERROR ; ERROR! (追記ここまで)
(追記) .CKPTFound: (追記ここまで)
(追記) mov WORD [PToff], bx ; Save Offset (追記ここまで)
(追記) add bx, 8 ; Increment Base to LBA Address (追記ここまで)
(追記) .ReadVBR: (追記ここまで)
(追記) mov EBX, DWORD [bx] ; Start LBA of Active Partition (追記ここまで)
(追記) mov di, 0x7C00 ; We Are Loading VBR to 0x07C0:0x0000 (追記ここまで)
(追記) mov cx, 1 ; Only one sector (追記ここまで)
(追記) call ReadSectors ; Read Sector (追記ここまで)
(追記) (追記ここまで)
(追記) .jumpToVBR: (追記ここまで)
(追記) cmp WORD [0x7DFE], 0xAA55 ; Check Boot Signature (追記ここまで)
(追記) jne ERROR ; Error if not Boot Signature (追記ここまで)
(追記) mov si, WORD [PToff] ; Set DS:SI to Partition Table Entry (追記ここまで)
(追記) mov dl, BYTE [bootDrive] ; Set DL to Drive Number (追記ここまで)
(追記) jmp 0x7C00 ; Jump To VBR (追記ここまで)
(追記) (追記ここまで)
(追記) times (218 - ($-$$)) nop ; Pad for disk time stamp (追記ここまで)
(追記) (追記ここまで)
(追記) DiskTimeStamp times 8 db 0 ; Disk Time Stamp (追記ここまで)
(追記) (追記ここまで)
(追記) bootDrive db 0 ; Our Drive Number Variable (追記ここまで)
(追記) PToff dw 0 ; Our Partition Table Entry Offset (追記ここまで)
(追記) (追記ここまで)
(追記) times (0x1b4 - ($-$$)) nop ; Pad For MBR Partition Table (追記ここまで)
(追記) (追記ここまで)
(追記) UID times 10 db 0 ; Unique Disk ID (追記ここまで)
(追記) PT1 times 16 db 0 ; First Partition Entry (追記ここまで)
(追記) PT2 times 16 db 0 ; Second Partition Entry (追記ここまで)
(追記) PT3 times 16 db 0 ; Third Partition Entry (追記ここまで)
(追記) PT4 times 16 db 0 ; Fourth Partition Entry (追記ここまで)
(追記) (追記ここまで)
(追記) dw 0xAA55 ; Boot Signature (追記ここまで)
(追記) </syntaxhighlight> (追記ここまで)
(追記) Of course this is an extremely simplified MBR, and is only able to load the [first] active partition. (追記ここまで)


==Comments==
==Comments==
Line 210: Line 321:


[[Category:X86]]
[[Category:X86]]
(追記) [[Category:Booting]] (追記ここまで)
[[Category:Bootloaders]]
[[Category:Bootloaders]]


[[de:Master Boot Record]]
[[de:Master Boot Record]]

Latest revision as of 18:08, 9 July 2023

A Master Boot Record (MBR) is the bootsector of a hard disk. That is, it is what the BIOS loads and runs, when it boots a hard disk. The MBR is the very first sector of the hard disk; it contains an MBR Bootstrap program (described below), and a Partition Table. Devices that emulate a hard disk during system initialization must also contain an MBR, because they must also have Partition Tables -- even if they are not bootable.

The BIOS will only boot an MBR from a device if that device is in the "boot sequence" stored in CMOS, and if the MBR on the device is formatted correctly. On the other hand, if a device is not in the boot sequence (but has a "drive number"), it is still possible for a Real Mode program (such as another MBR or bootloader) to load and boot that device's MBR directly.

MBR Bootstrap

An MBR is loaded by the BIOS at physical address 0x7c00, with DL set to the "drive number" that the MBR was loaded from. The BIOS then jumps to the very beginning of the loaded MBR (0x7c00), because that part of the MBR contains the "bootstrap" executable code.

Typical MBR bootstrap code will do the following:

  • relocate itself away from the 0x7c00 physical address (using a memory copy, and usually a far jump)
  • determine which partition (or hard disk) to boot from (either by looking for the active partition, or by presenting the user with a selection of installed operating systems to choose from)
    • if the user selected an "inactive" partition, then set the selected partition entry to "active", and clear the "active" bits of other partition entries
    • use BIOS INT 13h commands to rewrite the MBR if the partition table entries were modified
  • use BIOS INT 13h commands to load the Volume Boot Record (VBR, the "bootsector" of the bootloader) from the beginning of the selected partition to physical address 0x7c00
  • set DS:SI pointing to the selected partition table entry
  • jump to 0x7c00 (with CS set to 0, and DL set to the "drive number")

Note: it is intended for the value of DL, and the DS:SI pointer to be passed all the way into the kernel, for the kernel's use. This also means that the relocated MBR should not be overwritten during the boot process -- because the DS:SI pointer is aimed at a partition table entry inside that MBR, and needs to remain valid.

MBR Format

Notes:

  • See the Partition Table article for the format of each partition table entry field.
  • It is important to remember that the partition table entries are not aligned on 32-bit boundaries.
  • Naming the partition table entries as "First" through "Fourth" is for convenience only. The partition table entries are not required to be in any kind of order.
  • Any one of the partitions may be "active".
  • There is supposed to be one active partition table entry, at most.
  • Windows seems to verify and require that the partition it boots from be marked "active".
  • Most other operating systems don't seem to care about the "active" bit in the partition table entry.
Offset Size (bytes) Description
0x000 4401 MBR Bootstrap (flat binary executable code)
0x1B8 4 Optional "Unique Disk ID / Signature"2
0x1BC 2 Optional, reserved 0x00003
0x1BE 16 First partition table entry
0x1CE 16 Second partition table entry
0x1DE 16 Third partition table entry
0x1EE 16 Fourth partition table entry
0x1FE 2 (0x55, 0xAA) "Valid bootsector" signature bytes

1 This can be extended to 446 bytes if you omit the next 2 optional fields: Disk ID and reserved.

2 The 4 byte "Unique Disk ID" is used by recent Linux and Windows systems to identify the drive. "Unique" in this case means that the IDs of all the drives attached to a particular system are distinct.

3 The 2 byte reserved is usually 0x0000. 0x5A5A means read-only according to https://neosmart.net/wiki/mbr-boot-process/.

Partition table entry format

Offset1 Size (bytes) Description
0x00 1 Drive attributes (bit 7 set = active or bootable)
0x01 3 CHS Address of partition start
0x04 1 Partition type
0x05 3 CHS address of last partition sector
0x08 4 LBA of partition start
0x0C 4 Number of sectors in partition

1 Relative to the start of the partition entry.

Traditional MBR

The DOS FDISK program was the first to ever use an MBR, so that MBR became the de-facto standard. It also automatically became the standard for the minimum level of functionality of an MBR. It was never changed after it was first introduced.

The whole point of the FDISK program is to manipulate the MBRs of the hard disks attached to a system. When FDISK partitions a blank disk, it writes an MBR to sector 0 of the drive. When FDISK adds a new partition to a disk, it adds an entry into the Partition Table in the MBR. When FDISK makes a partition "active", it sets the "flag" byte in the Partition Table entry to 0x80.

The MBR that FDISK uses is coded to:

  • relocate itself to 0x0000:0x0600
  • examine the byte at offset 0x1be, 0x1ce, 0x1de, and 0x1ee to determine the active partition
  • load only the first sector of the active partition (which is expected to contain a DOS bootsector) to 0x0000:0x7c00 (hence the previous relocation)
  • set SI
  • jump to 0x7c00 -- transferring control to the DOS bootsector.


Dual Booting

A typical system may have several hard disks on it, and each hard disk can have 4 standard partitions (without going into the extra complication of Extended Partitions). Each of those partitions could theoretically hold its own distinct bootable OS, and filesystem.

However, the standard x86 boot sequence will only ever boot the MBR from the "C:" disk (the first disk found during the disk detection phase). And the standard MBR will only allow a single active partition on that disk, and will only ever boot that one partition. This is really completely inadequate.

It is not possible to modify the BIOS/CMOS boot sequence -- but you can change the MBR. So, one solution is to replace the standard MBR with a "custom, Dual Booting" MBR. (For a good example, see John Fine's SMBMBR in the External Links, below.)

A simple dual booting MBR will allow the user to select any partition on the current drive, to boot. A more complicated dual booting MBR will also allow the user to select other hard disks, or even to specifically choose other partitions on other hard disks, to boot.

For one MBR to load and run a different MBR off a different drive is called "chain loading". If all the MBRs are dual booting, then the user can cycle through all the disks, and choose to boot the "correct" partition from the "correct" drive.

A dual booting MBR is a huge improvement over the standard MBR. The only problem is that an MBR bootstrap is limited to a little over 400 bytes of code. Such a tiny program is insufficient to create a "nice" user-friendly dual booting system that has commercial appeal. It is enough space to hack up an interface that is good enough for the person who wrote it.

One way around this size limitation is to note that a bootloader can contain a lot more code than an MBR. So a custom MBR can try to load a "preferred" bootloader (if it can find one on some partition, somewhere) -- and that preferred bootloader can have a very pretty, user-friendly interface that allows the user to select any partition off any drive, to boot.

It is also nice, if there is only one partition on only one drive (ie. there is no choice for a user to make), if the MBR will boot that one partition automatically -- without bothering the user with prompts.

Generic MBRs

As said above, the MBR that is written to the disk by the DOS FDISK program is "the most generic" one. But every disk partitioning app must write some sort of MBR to the disk, and every generic bootloader may well need a custom MBR.

Fortunately, there was a standard for them to conform to (the FDISK MBR), and they all did conform to it. Some of them may be Dual Booting, or have other features -- but they will all end up loading your bootloader at the standard address (0x7c00), with the DL register set to the boot "drive number", and DS:SI pointing at the correct partition table entry of the correct MBR.

Building a Custom MBR Bootstrap program

When the BIOS transfers control to the MBR bootstrap code, the system is in Real mode. The MBR will probably also run entirely in Real mode, so it is important to understand Real mode addressing.

Self-relocation is one of the things C can't do, and most modern C compilers can't create code that is compatible with Real mode, anyway. So an MBR must be written in Assembly.

It is necessary to build an MBR that is exactly 512 bytes long. How this is done depends on your assembler and linker. The last 2 bytes must be the special boot pattern (0x55 followed by 0xAA), and as said above, the bootstrap portion of the MBR must be at most 446 bytes long. You must also put at least one partition table entry in the Partition Table portion of the MBR -- otherwise some BIOSes will refuse to boot from the disk. This includes most UEFI firmware in BIOS-compatibility mode.

Initial Environment

When the BIOS loads and runs an MBR, it is loaded into memory at physical address 0x7c00. This is usually 0x0000:0x7c00 (CS = 0, offset address 0x7c00). However, some BIOSes load to 0x7c0:0x0000 (CS = 0x07c0, offset address 0) -- which resolves to the same physical address, but can cause problems. A good practice is to enforce CS:IP with a far jump near the beginning of your bootstrap code. The MBR will probably need to immediately relocate itself anyway, and that is a good time to enforce CS:IP.

The BIOS passes very little useful information directly to the MBR. In fact, the only important number is the value in DL -- the "drive number". It needs to be passed to all later calls to BIOS function INT 13h, so that byte in DL probably needs to be saved carefully.

The values in all the other registers, and in most of memory, are undefined.

Immediate Priorities

It is important to immediately set up a stack, and also to set the rest of the CPU's segment registers (DS, ES, FS, GS) properly. Setting up a stack involves pointing the SS:SP pair of registers at some memory that is not being used for anything else (and the address must be even). The other segment registers should usually be set to 0.

See the Memory Map (x86) article to understand what memory is available during boot (low memory from 0x500 to 0x7ffff, generally).

In general, you do not want to fragment your available memory, or the memory of each 64K "page", if possible. The MBR needs a stack, and a place to relocate itself to. The MBR will be loading a bootloader at 0x7c00, so it is reasonably convenient for the MBR to relocate itself either to somewhere around the 0x500 to 0x600 address range, or to 0x7a00 (ie. just below 0x7c00). The stack can then point to 0x7c00 (if the MBR is not at 0x7a00), or the stack can be just below the relocated MBR.

Storing an MBR to the disk

To write an MBR to the first sector of a disk, you must use special disk I/O tools, because the MBR (by definition) is not inside any disk partition. The MBR only exists on the "raw device". There are quite a few "disk editing" tools available; some are listed in Disk Image Utilities.

x86 Examples

Assuming one knows how to read sectors from disk and has setup a function allowing them to do so, and assuming the inputs to said function are:

  • EBX - 32-bit LBA Address
  • CX - Sector Count
  • ES:DI - Buffer
  • BYTE [bootDrive] - Drive Number

An extremely simple MBR complying to the standard could look like:

[bits16]
[org0x0600]
start:
cli; We do not want to be interrupted
xorax,ax; 0 AX
movds,ax; Set Data Segment to 0
moves,ax; Set Extra Segment to 0
movss,ax; Set Stack Segment to 0
movsp,ax; Set Stack Pointer to 0
.CopyLower:
movcx,0x0100; 256 WORDs in MBR
movsi,0x7C00; Current MBR Address
movdi,0x0600; New MBR Address
repmovsw; Copy MBR
jmp0:LowStart; Jump to new Address
LowStart:
sti; Start interrupts
movBYTE[bootDrive],dl; Save BootDrive
.CheckPartitions:; Check Partition Table For Bootable Partition
movbx,PT1; Base = Partition Table Entry 1
movcx,4; There are 4 Partition Table Entries
.CKPTloop:
moval,BYTE[bx]; Get Boot indicator bit flag
testal,0x80; Check For Active Bit
jnz.CKPTFound; We Found an Active Partition
addbx,0x10; Partition Table Entry is 16 Bytes
deccx; Decrement Counter
jnz.CKPTloop; Loop
jmpERROR; ERROR!
.CKPTFound:
movWORD[PToff],bx; Save Offset
addbx,8; Increment Base to LBA Address
.ReadVBR:
movEBX,DWORD[bx]; Start LBA of Active Partition
movdi,0x7C00; We Are Loading VBR to 0x07C0:0x0000
movcx,1; Only one sector
callReadSectors; Read Sector
.jumpToVBR:
cmpWORD[0x7DFE],0xAA55; Check Boot Signature
jneERROR; Error if not Boot Signature
movsi,WORD[PToff]; Set DS:SI to Partition Table Entry
movdl,BYTE[bootDrive]; Set DL to Drive Number
jmp0x7C00; Jump To VBR
times(218-($-$$))nop; Pad for disk time stamp
DiskTimeStamptimes8db0; Disk Time Stamp
bootDrivedb0; Our Drive Number Variable
PToffdw0; Our Partition Table Entry Offset
times(0x1b4-($-$$))nop; Pad For MBR Partition Table
UIDtimes10db0; Unique Disk ID
PT1times16db0; First Partition Entry
PT2times16db0; Second Partition Entry
PT3times16db0; Third Partition Entry
PT4times16db0; Fourth Partition Entry
dw0xAA55; Boot Signature

Of course this is an extremely simplified MBR, and is only able to load the [first] active partition.

Comments

See Also

Articles

External Links

Retrieved from "https://wiki.osdev.org/index.php?title=MBR_(x86)&oldid=28022"