Search code examples
filesystemslow-levelfatlow-level-iofat16

Where exactly is the first data sector on a FAT file system?


I don't really understand where the first data sector is supposed to be on a FAT formatted disk (especially for FAT-12 and FAT-16). I already read the Microsoft documentation for FAT systems, which gives two formulas to compute the first data sector on a FAT file system : Number of sectors used by the root directory Formula for the first data sector

However, whenever I use them, they always give me the wrong result, to be more precise, the resulting sector is always one more than what it should be (which I suspect is because of the BPB_BytsPerSec - 1).

To put this into an example, I tried this on a FAT-12 disk image I have, the values relevant for the computations are :

  • Number of bytes per sector : 512
  • Number of sectors per cluster : 1
  • Number of reserved sectors : 1
  • Number of FATs : 2
  • Number of sectors per FAT : 9
  • Number of entries in the root directory : 224

So using this data, the first FAT is at 0x200 and the second one at 0x1400. The root directory must be at 0x2600. The length of the root directory is 224*32 = 7168 = 0x1C00. Therefore, the first directory of the root directory should be at 0x4200 (aka sector 33 since the first sector is sector 0), which is the correct result as I dumped the content of my disk image, and the first directory is indeed at sector 33. Using the formula given by Microsoft, given that the first one rounds up, gives me a number of 15 sectors used by the root directory, so the first data sector should be 1 + 18 + 15 = 34, the first directory should be at 0x4400, which is not correct.

What went wrong, or what did I not understand ? Any help would be kindly appreciated, as I am really confused.


Solution

  • Since I also posted the same question on reddit and it was answered first, I think the least I can do is share the answer here as well (see : https://www.reddit.com/r/filesystems/comments/1br2bar/where_exactly_is_the_first_data_sector_on_a_fat/).

    In short, I was rounding up a formula that was already doing the round up for me, so I was obviously getting one extra sector when doing the computation. Therefore, you should not round up the formula for RootDirSectors, but actually round it down as the round up is done by adding the BPB_BytsPerSec - 1 term.