I'm working on a FAT12 driver for my OS (you can find the driver here) but I've run into a very strange roadblock, that I don't know is with my code or the driver.
I have a file called long.txt that contains about 1024 bytes of content, and it's meant to test following a chain of clusters. However, the code stops after one cluster, and says the next one is 0xFFF, which is greater than 0xFF8, so EOF.
Here is the snippet of code that causes issues:
int fatReadInternal(fsNode_t *file, uint8_t *buffer, uint32_t length) {
if (file) {
// Calculate and read in the starting physical sector
uint16_t cluster = file->impl;
uint32_t sector = ((cluster - 2) * drive->bpb->sectorsPerCluster) + drive->firstDataSector;
uint8_t *sector_buffer;
ideReadSectors(drive->driveNum, 1, (uint32_t)sector, sector_buffer);
// Copy the sector buffer to the output buffer
memcpy(buffer, sector_buffer, length);
// Locate the File Allocation Table sector
uint32_t fatOffset = cluster + (cluster / 2);
uint32_t fatSector = drive->firstFatSector + (fatOffset / 512);
uint32_t entryOffset = fatOffset % 512;
// Read the FATs
ideReadSectors(drive->driveNum, 1, fatSector, (uint8_t*)FAT);
ideReadSectors(drive->driveNum, 1, fatSector + 1, (uint8_t*)FAT + 512);
// Read entry for the next cluster
uint16_t nextCluster = *(uint16_t*)&FAT[entryOffset];
// Convert the cluster
nextCluster = (cluster & 1) ? nextCluster >> 4 : nextCluster & 0xFFF;
serialPrintf("The current cluster is 0x%x, the next cluster is 0x%x after modification.\n", cluster, nextCluster);
// Test for EOF
if (nextCluster >= 0xFF8) {
return EOF;
}
// Test for file corruption
if (nextCluster == 0) {
return EOF;
}
// Set the next cluster
file->impl = nextCluster;
}
return 0;
}
NOTE: It is meant to be called multiple times.
It outputs that the current cluster is 0xD
and the next cluster read from the disk (not yet converted) is 0xFF0, which (from looking at a hex editor) is correct if entry offset is 0x13 (should also be calculating properly).
The problem is that after conversion this is 0xFFF, last cluster in the chain. The same is true manually calculating and checking a hex editor. I'm genuinely very confused.
The FAT driver can read the first 512 bytes of the file, but then it just returns EOF. I checked in the hex editor to see where the next cluster actually was, and its directly after the first one.
I'm not sure whether this is an issue in my code or something else, but Linux appears to read the file just fine.
Next cluster reading seems fine to me at a first glance. However there are two related obvious issues:
fsRead(size=1)
would not work the way one would expect it works.