Shop OBEX P1 Docs P2 Docs Learn Events
FAT (16/32) Convert Cluster to Sector — Parallax Forums

FAT (16/32) Convert Cluster to Sector

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.
/**
 * @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

  • Okay, I've found some websites which provide the same algorithm that I used the first time around, but I'm going to assume that they are in fact wrong, though it probably doesn't come up too often in reality.

    From the Microsoft specification, section 6.7, at the bottom of page 28:
    Determination of the first sector of an allocated cluster
    Section 3.5 describes the computation of RootDirSectors, and FATSz.
    The first sector of the beginning of the data region (cluster #2) is computed as given below:
    FirstDataSector = BPB_ResvdSecCnt + (BPB_NumFATs * FATSz) + RootDirSectors
    
    Given any valid data cluster number N, the sector number of the first sector of that cluster is
    comp uted as follows:
    FirstSectorofCluster = ((N – 2) * BPB_SecPerClus) + FirstDataSector;
    

    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! :D
Sign In or Register to comment.