FAT (16/32) Convert Cluster to Sector
DavidZemon
Posts: 2,973
in Propeller 1
I had the following algorithm for calculating a sector address from a cluster. It worked great during all of my testing when only a single partition had been created on the SD card. However, when I started testing multiple partitions, the algorithm failed. I believe this is because, normally, the root cluster (cluster of the root directory) of a FAT32 partition is cluster 2. However, when I used Ubuntu's GParted to add a second partition to an existing SD card, the root directory of the original partition was moved to cluster 0x73A. This is perfectly legal based on FAT specifications (though I've no idea why GParted did it... nor do I care), but it broke my algorithm.
What's troublesome is that I can't figure out why I wrote the algorithm in this way, or what the correct way would be. I've found that simply subtracting a magical "2" works so I got rid of the if-else-statement and left it at that.
What I would like to know is whether or not it will work for all cases? It also has me wondering where are the two mystery clusters at the start of every FAT filesystem?
And, I'm always interested in the why/how. How did these two mystery clusters come to be at the beginning at the FAT?
/** * @brief Find and return the starting sector's address for a given cluster * * @param[in] tier2 Cluster in FAT filesystem * * @return Returns sector address of the desired cluster */ uint32_t compute_tier1_from_tier2 (uint32_t tier2) const { if (FatFS::FAT_32 == this->m_filesystem) tier2 -= this->m_rootCluster; else tier2 -= 2; tier2 <<= this->m_tier1sPerTier2Shift; tier2 += this->m_firstDataAddr; return tier2; }
What's troublesome is that I can't figure out why I wrote the algorithm in this way, or what the correct way would be. I've found that simply subtracting a magical "2" works so I got rid of the if-else-statement and left it at that.
/** * @brief Find and return the starting sector's address for a given cluster * * @param[in] tier2 Cluster in FAT filesystem * * @return Returns sector address of the desired cluster */ uint32_t compute_tier1_from_tier2 (uint32_t tier2) const { tier2 -= 2; tier2 <<= this->m_tier1sPerTier2Shift; tier2 += this->m_firstDataAddr; return tier2; }
What I would like to know is whether or not it will work for all cases? It also has me wondering where are the two mystery clusters at the start of every FAT filesystem?
And, I'm always interested in the why/how. How did these two mystery clusters come to be at the beginning at the FAT?
Comments
From the Microsoft specification, section 6.7, at the bottom of page 28:
The two is quite magical, and simply hardcoded into the specification. So be it! I've cited it in PropWare's source code so it isn't quite so magical... but with this, PropWare now has functional multi-partition support!