The Master Boot Record (MBR) is pretty much the same for all operating systems. It's located in the first sector of the hard drive, at cylinder 0, head 0, sector 1. This is the code that runs after the computer has finished checking all its hardware (POST), and control has been passed to the hard drive to load an operating system. It also contains the Partition Table, which defines different sections of the hard drive. Basically, if anything happens to this tiny 512-byte area, your hard drive is toast.
Offset | Description | Size |
000h | Boot code (starts computer) | 446 bytes |
1BEh | First partition entry (see table below) | 16 bytes |
1CEh | Second partition entry | 16 bytes |
1DEh | Third partition entry | 16 bytes |
1EEh | Fourth partition entry | 16 bytes |
1FEh | Boot record signature (55h AAh) | 2 bytes |
Offset | Description | Size |
00h | Partition status (00h = inactive, 80h = active) | 1 byte |
01h | Starting sector of the partition (head) | 1 byte |
02h | Starting sector of the partition (cylinder/sector – see below) | 1 word |
04h | Partition type (see list below) | 1 byte |
05h | Ending sector of the partition (head) | 1 byte |
06h | Ending sector of the partition (cylinder/sector) | 1 word |
08h | Number of sectors from MBR to first sector of the partition | 1 double word |
0Ch | Number of sectors in the partition | 1 double word |
Back in those days, with 10MB hard drives and 8086 processors, code space was extremely precious, so they did what they could to save space. Unfortunately, we have to live with that now, but fortunately, they invented new ways of doing system calls so that the 1024 cylinder limit (2^10) isn't really a problem for newer computers. For older ones, you usually need some kind of disk overlay program to let them see the whole disk.
Well, to get the Sector, you apply an AND mask ($3F). To get the Cylinder, you take the high byte and OR the low byte with an ANDed $C0, then shift left by two. That's not very clear, so I'll just show you the two Pascal programs I wrote for encoding and decoding the Cylinder/Sector. They should be easily readable even if you don't know Pascal.
function CylSecEncode(Cylinder, Sector: Word): Word; begin CylSecEncode := (Low(Cylinder) shl 8) or (High(Cylinder) shl 6) or Sector; end;
Procedure CylSecDecode(var Cylinder, Sector: Byte; const CylSec: Byte); begin Cylinder := HiByte(CylSec) or ((LoByte(CylSec) and $C0) shl 2); Sector := (CylSec and $3F); end;
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Track bits 7 to 0 | Track bits 9 and 8 | Sector bits 5 to 0 |
List of Partition Types (UTF-8)
There are many others, but these are the ones that are Microsoft OS-specific.
Value | Description |
00h | Unknown or none |
01h | 12-bit FAT |
04h | 16-bit FAT (partitions less than 32 MB) |
05h | Extended MS-DOS partition |
06h | 16-bit FAT (partitions greater than 32 MB) |
0Bh | 32-bit FAT (partitions up to 2048 GB) |
0Ch | Same as 0Bh, but with LBA1 extended 13h |
0Eh | Same as 06h, but with LBA1 extended 13h |
0Fh | Same as 05h, but with LBA1 extended 13h |
Read from multiple partitions
While it's less likely to have multiple partitions on a FAT32 formatted drive than on a FAT16, the concept is exactly the same. The first partition is the primary one, and everything else is stored in an extended partition. Reading these extra partitions is a bit more complicated (not much, just a little). The first entry in the partition table indicates where the primary partition is (its size, starting and ending sectors). The second entry in the partition table indicates where the extended partition is (which can contain more than one partition). To read more partitions, you would find where the extended partition starts and read the first sector. It works like an MBR. Where the code would be is blank, and the first entry in the partition table is for the next partition on the drive, with another extended partition created if there are more partitions, and so on. However, all sector references are relative to this new MBR point, making it a virtual drive. In case that's still confusing (and I can see how my explanation might be), let me show you how a drive with three partitions would be set up.
Full Disk MBR
Entry #1 - Points to Partition #1
Entry #2 - Points to the entire extended partition
You read the first sector of that extended partition, and there's another MBR.
Extended Partition's MBR (Master Boot Record)
Entry #1 - Points to Partition #2
Entry #2 - Points to the extended partition's free space following Partition #2
Now all sector references in these entries (especially the one at offset 08h) will be relative to the start of the extended partition, not the disk. However, the CHS (Cylinder, Head, Sector) numbers will still be correct.
You would then read the first sector of that extended partition, and see yet another MBR.
"MBR of Rest of Extended Partition" can be translated as "MBR of the Remaining Part of the Extended Partition." Here, MBR stands for Master Boot Record, an essential part of a hard disk that stores booting information and the partition table. An extended partition is a special type of partition that allows for the creation of multiple logical drives on a hard disk. "Rest of Extended Partition" refers to the unallocated space within the extended partition.
Entry #1 - Partition #3
Since this is the last partition, there is no Entry #2.
If there is another cut, the pattern continues as before until the last one.
All this information is stored in the first sector of each partition.
Offset | Description | Size |
00h | Jump instruction + NOP | 3 bytes |
03h | OEM name (for example, MSWIN4.1) | 8 bytes |
0Bh | Bytes per sector | 1 word |
0Dh | Sectors per cluster | 1 byte |
0Eh | Reserved sectors | 1 word |
10h | Number of FATs | 1 byte |
11h | Maximum root directory entries (not used in FAT32) | 1 word |
13h | Total sectors for volumes < 32 MB (not used in FAT32) | 1 word |
15h | Media descriptor (F8h for hard disks) | 1 byte |
16h | Sectors per FAT (not used in FAT32) | 1 word |
18h | Sectors per track | 1 word |
1Ah | Number of heads | 1 word |
1Ch | Number of hidden sectors in volume | 1 doubleword |
20h | Total sectors in volume | 1 doubleword |
24h | Sectors per FAT | 1 doubleword |
28h | Flags (bits 0-4 indicate active FAT copy) (bit 7 indicates whether FAT mirroring is enabled or disabled) (if FAT mirroring is disabled, then only the FAT information at the copy indicated by bits 0-4 is written) | 1 word |
2Ah | FAT32 drive number (high byte = major version, low byte = minor version) | 1 word |
2Ch | First cluster of root directory | 1 doubleword |
30h | Sector number of file system information sector (see below structure) (relative to beginning of partition) | 1 word |
32h | Sector number of backup boot sector (relative to beginning of partition) | 1 word |
34h | Reserved | 12 bytes |
40h | Volume logical drive number | 1 byte |
41h | Unused (may be high byte of previous entry) | 1 byte |
42h | Extended Boot Signature (29h) | 1 byte |
43h | Volume Serial Number | 1 doubleword |
47h | Volume label | 11 bytes |
52h | FAT name (FAT32) | 8 bytes |
There is usually a second sector on the partition, though I believe it can be moved since it's referenced from the boot sector. I never fully understood this, although I knew where the important fields were.
Offset | Description | Size |
00h | First signature (52h 52h 61h 41h) | Double word |
04h | Unknown, currently (possibly null) | 480 bytes |
1E4h | Signature for the FSInfo sector (72h 72h 41h 61h) | Double word |
1E8h | Number of free clusters (set to -1 if unknown) | Double word |
1ECh | Cluster number of last allocated cluster | Double word |
1F0h | Reserved | 12 bytes |
1FCh | Unknown or null | 2 bytes |
1FEh | Boot record signature (55h AAh) | 2 bytes |
FAT32 File System Layout
Offset | Description |
Partition Start | Boot Sector |
Start + Number of Reserved Sectors | FAT Table |
Start + Number of Reserved Sectors + (FAT Sectors Per Copy * 2) | Data Area (Starting with Cluster #2) |
Clustering
A cluster is a group of sectors on a hard drive that contain information. A 4K cluster contains 8 sectors (512 * 8 = 4096). Each cluster has a place in the FAT table. When you look at an entry in the FAT table, the number tells you whether the cluster contains data, if it's the end of the data, or if there are more clusters after it. All data on the partition begins with Cluster #2. If the FAT entry is 0, then the cluster is empty. If the FAT entry is 0FFFFFFFh, then it is the last entry in the chain.
This is a big gap in my information. I could figure out where the chain ends by looking at a FAT32 drive, but I don't know what indicates a “bad cluster,” or what the largest valid number for data is.
Currently, you can use the following formula to calculate the maximum viable cluster in a zone:
(Sectors in partition - Sectors per FAT * 2 - Reserved Sectors) / Sectors per Cluster
If there's any remainder in that calculation, it just means you have a few extra sectors at the end of the partition – not enough to make another cluster – so you can ignore anything after the decimal point.
Table of Contents
Looking at the file system at a lower level, the other aspect is the directory table, which holds all the file and directory entries. Essentially, there is only one difference between a FAT16 and a FAT32 directory entry: The reserved OS/2 bytes in the short filename structure (offset 20 [14h]) are replaced by the high word of the cluster number (because it is now 4 bytes instead of 2).
File Allocation Table
Footnote
1 - LBA: Logical Block Addressing - Using the extended features of the new BIOS's Int 13h to access data beyond the 8GB limit, or accessing the drive entirely in LBA mode instead of CHS (Cylinder, Head, Sector) mode.
If you accidentally deleted, removed, or formatted data from a FAT32 hard drive, USB, or other storage device, don't panic. Your best bet is to let a Data Recovery Wizard tool assist you! We recommend giving the Data Recovery Wizard a try, as it allows you to effectively recover all lost data from deleted or formatted partitions in just three simple steps. Download it for free now and retrieve all your lost FAT32 data immediately: