Offset, sectors | Size, sectors | Block | Comments |
---|---|---|---|
Main Boot Region | |||
0 | 1 | Boot Sector | |
1 | 8 | Extended Boot Sectors | |
9 | 1 | OEM Parameters | |
10 | 1 | Reserved | |
11 | 1 | Boot Checksum | |
Backup Boot Region | |||
12 | 1 | Boot Sector | |
13 | 8 | Extended Boot Sectors | |
21 | 1 | OEM Parameters | |
22 | 1 | Reserved | |
23 | 1 | Boot Checksum | |
FAT Region | |||
24 | FatOffset - 24 | FAT Alignment | Boot Sectors contain FatOffset |
FatOffset | FatLength | First FAT | Boot Sectors contain FatOffset and FatLength |
FatOffset + FatLength | FatLength | Second FAT | For TexFAT only |
Data Region | |||
FatOffset + FatLength * NumberOfFats | ClusterHeapOffset – (FatOffset + FatLength * NumberOfFats) | Cluster Heap Alignment | |
ClusterHeapOffset | ClusterCount * 2^SectorsPerClusterShift | Cluster Heap | |
ClusterHeapOffset + ClusterCount * 2^SectorsPerClusterShift | VolumeLength – (ClusterHeapOffset + ClusterCount * 2^SectorsPerClusterShift) | Excess Space |
Navigate to detailed volume specification using following links:
Offset | Size | Description | Comments |
---|---|---|---|
0 (0x00) | 3 | JumpBoot | 0xEB7690 |
3 (0x03) | 8 | FileSystemName | "EXFAT" |
11 (0x0B) | 53 | MustBeZero | |
64 (0x40) | 8 | PartitionOffset | In sectors; if 0, shall be ignored |
72 (0x48) | 8 | VolumeLength | Size of exFAT volume in sectors |
80 (0x50) | 4 | FatOffset | In sectors |
84 (0x54) | 4 | FatLength | In sectors. May exceed the required space in order to align the second FAT |
88 (0x58) | 4 | ClusterHeapOffset | In sectors |
92 (0x5C) | 4 | ClusterCount | 2^32-11 is the maximum number of clusters could be described |
96 (0x60) | 4 | RootDirectoryCluster | |
100 (0x64) | 4 | VolumeSerialNumber | |
104 (0x68) | 2 | FileSystemRevision | as MAJOR.minor, major revision is high byte, minor is low byte; currently 01.00 |
106 (0x6A) | 2 | VolumeFlags (see below) | |
108 (0x6C) | 1 | BytesPerSectorShift | Power of 2. Minimum 9 (512 bytes per sector), maximum 12 (4096 bytes per sector) |
109 (0x6D) | 1 | SectorsPerCluster Shift | Power of 2. Minimum 0 (1 sector per cluster), maximum 25 – BytesPerSectorShift, so max cluster size is 32 MB |
110 (0x6E) | 1 | NumberOfFats | 2 is for TexFAT only |
111 (0x6F) | 1 | DriveSelect | Extended INT 13h drive number; typically 0x80 |
112 (0x70) | 1 | PercentInUse | 0..100 – percentage of allocated clusters rounded down to the integer 0xFF – percentage is not available |
113 (0x71) | 7 | Reserved | |
120 (0x78) | 390 | BootCode | |
510 (0x1FE) | 2 | BootSignature | 0xAA55 |
512 (0x200) | 2^BytesPerSectorShift - 512 | ExcessSpace | Not used |
Offset | Size | Field |
0 | 1 | ActiveFat 0 - First FAT and Allocation Bitmap are active, 1 - Second . |
1 | 1 | VolumeDirty (0-clean, 1-dirty) |
2 | 1 | MediaFailure (0 – no failures reported or they already marked as BAD clusters) 1- some read/write operations failed) |
3 | 1 | ClearToZero (no meaning) |
4 | 12 | Reserved |
Size | Description | Comments | ||
---|---|---|---|---|
0 (0x00) | 2^BytesPerSectorShift - 4 | ExtendedBootCode | ||
2^BytesPerSectorShift - 4 | 4 | ExtendedBootSignature | 0xAA550000 |
Whole sector is used for boot code except last 4 bytes used for signature in each sector. If Extended Boot Sector is not used, it should be filled with 0x00. Extended signature must be preserved.
Offset | Size | Description | Comments |
---|---|---|---|
0 (0x00) | 48 | Parameters[0] | |
… | … | … | |
432 (0x1B0) | 48 | Parameters[9] | |
480 (0x01E0) | 2^BytesPerSectorShift - 480 | Reserved |
OEM parameters are ignored by Windows but can be used by OEM implementations. OEMs can define their own parameters with unique GUIDs. All unused Parameters fields must be described as unused by GUID_NULL in ParameterType.
This structure must be preserved during exFAT formatting, except in the case of secure wipe.
Offset | Size | Description | Comments |
0x00 | 16 | ParameterType | OEM defined GUID , GUID_NULL indicate that parameter value is not used |
0x10 | 32 | ParameterValue | OEM specific |
#define OEM_FLASH_PARAMETER_GUID 0A0C7E46-3399-4021-90C8-FA6D389C4BA2 struct { GUID OemParameterType; //Value is OEM_FLASH_PARAMETER_GUID UINT32 EraseBlockSize; //Erase block size in bytes UINT32 PageSize; UINT32 NumberOfSpareBlocks; UINT32 tRandomAccess; //Random Access Time in nanoseconds UINT32 tProgram; //Program time in nanoseconds UINT32 tReadCycle; // Serial read cycle time in nanoseconds UINT32 tWriteCycle; // Write Cycle time in nanoseconds UCHAR Reserved[4]; } FlashParameters;
This sector contains a repeating 32-bit checksum of the previous 11 sectors. The checksum calculation excludes VolumeFlags and PercentInUse fields in Boot Sector (bytes 106, 107, 112). The checksum is repeated until the end of the sector. The number of repetitions depends on the size of the sector.
UINT32 BootChecksum(const unsigned char data[], int bytes) { UINT32 checksum = 0; for (int i = 0; i < bytes; i++) { if (i == 106 || i == 107 || i == 112) continue; checksum = (checksum << 31) | (checksum >> 1) + data[i]; } return checksum; }
File Allocation Table (FAT) may contain 1 or 2 FATs, as defined in NumberOfFats field. ActiveFat field in VolumeFlags in the Main Boot Sector determines which FAT is active.
The first cluster is cluster 2, as in FAT32. Each FatEntry represents one cluster
In exFAT, FAT is not used for tracking an allocation; an Allocation Bitmap is used for this purpose. FAT is only used for keeping chains of clusters of fragmented files. If a file is not fragmented, FAT table does not need to be updated. A Stream Extensions Directory Entry should be consulted to determine if the FAT chain is valid or not. If FAT chain is not valid, it does not need to be zeroed.
Offset | Size | Description | Comments |
---|---|---|---|
0 (0x00) | 4 | FatEntry[0] | Media type (should be 0xFFFFFFF8) |
4 (0x04) | 4 | FatEntry[1] | Must be 0xFFFFFFFF |
8 (0x08) | 4 | FatEntry[2] | First cluster |
… | … | … | … |
(ClusterCount + 1) * 4 | 4 | FatEntry[ClusterCount + 1] | Last cluster |
(ClusterCount + 2) * 4 | Remainder of sector | ExcessSpace |
Valid values of FAT entries:
Value 0x00000000 does not mean the cluster is free, it is an undefined value.
The second FAT table (presents only in TexFAT) is located immediately after the first one and has the same size.