How can I detect if my floppy image is really formated FAT12?
I have all required fields in the boot sector, and my df -T shows:
Code: Select all
Filesystem Type 1K-blocks Used Available Use% Mounted on
/dev/loop0 vfat 1424 34 1390 3% /mnt/disk
Judging from this it's FAT12. What's more the read function works as expected (I think that because I can view files, files in folders, and I can load kernel in stage2 bootloader)
But there's one thing that seems not to be detected: I'm talking about entries in FAT. While parsing them I get the following:
Code: Select all
FAT_ENTRY_No VALUE
0 -> 0x0
1 -> 0x0
2 -> 0x0
3 -> 0x4
4 -> 0xFFFFFF00
5 ->0xFF0
6 -> 0xFFFFF800
...
First of all these values are integer (?!) not short. Next thing is second entry is "empty" which is quite odd.
But again -> when reading those specific sectors on floppy (floppy_read(33)) I get empty 512 bytes. So indeed it's free.
Quite the opposite is happening with entry number 14 -> it also shows 0x0 as a value but reading floppy sector (33 + (14-2)) = 45 I get some data there. Also writing there results in system not booting and bochs showing error about trying to read sector outside floppy boundaries.
Here is the code for getting FAT entries:
Code: Select all
int fat12_find_if_free_cluster(int free_cluster)
{
unsigned char* sector;
/* Calculate FAT entry offset, etc. */
unsigned int FAT_Offset = free_cluster + (free_cluster / 2); //multiply by 1.5 (o3mujemy adres info o nast. klastrze)
unsigned int FAT_Sector = 1 + (FAT_Offset / ROZMIAR_SEKTORA);
unsigned int entryOffset = FAT_Offset % ROZMIAR_SEKTORA;
/* Read fat sectors */
sector = (unsigned char*) floppy_read_sector( FAT_Sector );
memcpy((unsigned char*)FAT, sector, 512);
sector = (unsigned char*) floppy_read_sector ( FAT_Sector + 1 );
memcpy((unsigned char*)FAT + ROZMIAR_SEKTORA, sector, 512);
/* Read where is next cluster of file (if any) */
short nextCluster = *(unsigned short*)&FAT[entryOffset];
short actual_cluster;
if( nextCluster & 0x0001 )
actual_cluster = nextCluster >> 4; //grab high 12 bits
else
actual_cluster = nextCluster & 0x0FFF; //grab low 12 bits
if(actual_cluster == 0) {
actual_cluster = 0xff8;
/* Zapisujemy w FAT */
if(nextCluster & 0x0001) {
nextCluster &= 0x000F;
nextCluster |= (actual_cluster << 4);
} else {
nextCluster &= 0xF000;
nextCluster |= actual_cluster;
}
short* tmp = (short*)&FAT[entryOffset];
*tmp = nextCluster;
floppy_write_sector(FAT_Sector, FAT);
floppy_write_sector(FAT_Sector+1, FAT+ROZMIAR_SEKTORA);
return free_cluster;
}
return -1;
}