在測試各種卡插拔測試的時候,遇到這樣的一個error:
ExFAT: Invalid boot sector checksum. Was 0x12345678, should be 0x87654321.這個error會導致系統彈出提示框
“You need to format the disk in driver J: before you can use it. Do you want to format it?”
於是很好奇什麼是boot sector checksum,是否真的是boot sector checksum錯誤導致這樣的error。
這裏我們只看Classical Generic的版本,參考下圖:
Address | Description |
Size (bytes) |
||
---|---|---|---|---|
Hex | Dec | |||
+000h | +0 | Bootstrap code area | 446 | |
+1BEh | +446 | Partition entry #1 |
Partition table (for primary partitions) |
16 |
+1CEh | +462 | Partition entry #2 | 16 | |
+1DEh | +478 | Partition entry #3 | 16 | |
+1EEh | +494 | Partition entry #4 | 16 | |
+1FEh | +510 | 55h | Boot signature[a] | 2 |
+1FFh | +511 | AAh | ||
Total size: 446 + 4×16 + 2 | 512 |
Offset (bytes) |
Field length |
Description | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
+0h | 1 byte | status / physical drive (bit 7 set: active / bootable, old MBRs only accept 80h), 00h: inactive,01h–7Fh: invalid)[a] | ||||||||||||||||||
+1h | 3 bytes | CHS address of first absolute sector in partition.[b] The format is described by 3 bytes, see the next 3 rows. | ||||||||||||||||||
+1h | 1 byte |
|
||||||||||||||||||
+2h | 1 byte |
|
||||||||||||||||||
+3h | 1 byte |
|
||||||||||||||||||
+4h | 1 byte | Partition type[14] | ||||||||||||||||||
+5h | 3 byte | CHS address of last absolute sector in partition.[b] The format is described by 3 bytes, see the next 3 rows. | ||||||||||||||||||
+5h | 1 byte |
|
||||||||||||||||||
+6h | 1 byte |
|
||||||||||||||||||
+7h | 1 byte |
|
||||||||||||||||||
+8h | 4 bytes | LBA of first absolute sector in the partition[d] | ||||||||||||||||||
+Ch | 4 bytes | Number of sectors in partition[d] | ||||||||||||||||||
Notes:
^ a Originally,
status values other than 00h and80h were invalid, but modern MBRs treat bit 7 as active flag and use this entry to store the physical boot unit (see below). ^ b Starting
Sector fields are limited to 1023+1 cylinders, 255+1 heads, and 63 sectors; Ending Sector fields have the same limitations. ^ c The
range for sector is 1 through 63; the range for cylinder is 0 through 1023; the range for head is 0 through 255 inclusive.[15] ^ d Used by OSes in certain circumstances; in such cases the CHS addresses are ignored.[16] |
從中可以獲取這張卡只有一個partition,他開始的絕對地址是0x2000 sector。接下來就是要從0x2000 sector來解析ExFAT的boot sector了。
ExFat是從FAT12、FAT16、FAT32演變而來,主要增加了一下改進:
支持更大的文件、更大的卷
原生支持unicode文件名
更大的boot空間,支持更多的boot code
更好的速度、性能
對時區的支持
對OEM參數的支持
接下來我們的重點還是首先了解一下ExFAT boot sector的組成,可以參考:http://www.ntfs.com/exfat-volume-layout.htm
Volume Layout
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 |
|
從這個表中可以看到我們所需要找的 boot sector checksum 位於第12個sector,它是對前11個sector所做的checksum。我們可以從上面的鏈接中找到boot sector checksum的計算方法,參考下面:
exFAT Boot Checksum
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.
UNIT32 BootChecksum(constunsignedchardata[], intbytes) { UINT32 checksum = 0; for (inti = 0; i < bytes; i++) { if (i == 106 || i == 107 || i == 112) continue; checksum = (checksum<<31) | (checksum>> 1) + data[i]; } returnchecksum;
有了上面的partition開始地址、boot sector checksum計算方法,我們就可以讀取並check boot sector checksum是否正確。checksum這個sector以4個字節爲計算結果,一直重複這個計算結果。例如:
...
第12個sector開始地址是 11*512 = 5632 = 0x1600
上述的boot sector checksum爲 0x8B165B51
通過手動將這個數字改變,並重新寫入相同的位置,重新認卡,會發現彈出上述的對話框,提示卡需要format,同時在debug log中顯示boot sector checksum error。
以上就是對ExFAT boot sector checksum error所做的實驗。
ExFAT對比FAT32可以參考上述鏈接,主要區別如下:
exFAT vs. FAT32 Comparison
Feature |
FAT32 |
exFAT |
---|---|---|
Maximum Volume Size |
8 TB* |
128 PB |
Maximum File Size |
4 GB |
16 EB |
Maximum Cluster Size |
32 KB ** |
32 MB |
Maximum Cluster Count |
228 |
232 |
Maximum File Name Length |
255 |
255 |
Date/Time resolution |
2 s |
10 ms |
MBR Partition Type Identifier |
0x0B, 0x0C |
0x07 |
* Windows cannot format FAT32 volumes bigger than 32GB, though itsupports larger volumes created by third party implementations; 16 TB is the maximum volume size if formatted with 64KB cluster
** According to Microsoft KB184006 clusters cannot be 64KB or larger, though some third party implementations support up to 64KB.