luxos/Kernel/hal/filesys/fat/fat.c

81 lines
2.4 KiB
C

/*
* fat.c
*
* Created on: Aug 31, 2011
* Author: Tiberiu
*/
#include <fileio.h>
#include <debugio.h>
#include "fat.h"
// Buffer should contain boot sector
uint32 FatDetect (void* buffer)
{
FatBootSector* boot = (FatBootSector*)buffer;
uint32 correct_features = 0;
uint32 total_features = 0;
// Try the asm 'jmp' instruction
if ((boot->bpb.AsmJmp[0] == 0x6B || boot->bpb.AsmJmp[0]==0xEB) && boot->bpb.AsmJmp[2] == 0x90)
correct_features++;
total_features ++;
// Try the OemId. First char is often 'm' or 'M' (mkdosfs or MSDOS??/MSWIN??)
if (boot->bpb.OemId[0] == 'm' || boot->bpb.OemId[0] == 'M') correct_features++;
total_features ++;
// Try the bytes per sector. Most often, it is 512.
if (boot->bpb.BytesPerSector == 512) correct_features++;
total_features ++;
// Try the sectors per cluster. This is always a power of 2.
uint8 sectclust = boot->bpb.SectorsPerCluster;
uint8 count = 0;
while (sectclust) { count += sectclust&1; sectclust>>=1; }
if (count != 1) return 0;
// Number of fats, can be 2 or (rarely) 1. Important feature.
if (boot->bpb.FatsCount == 1 || boot->bpb.FatsCount == 2) correct_features+=2;
total_features+=2;
// This tells us what type of disk this is. Usually values are above 0xf0.
if (boot->bpb.MediaDescriptorType >= 0xF0) correct_features++;
total_features++;
// Calculate number of clusters
uint32 clusters = (boot->bpb.TotalSectors * boot->bpb.SectorsPerCluster);
if (clusters == 0) clusters = (boot->bpb.TotalSectorsLarge * boot->bpb.SectorsPerCluster);
// Calculate fat type
uint32 fat = (clusters < 4085) ? 12 : 16 ;
if (clusters > 65524) fat = 32;
// Try the extended info
if (fat == 32) {
if (boot->ext.fat32.Signature == 0x28 || boot->ext.fat32.Signature == 0x29) correct_features++;
total_features++;
}
else {
if (boot->ext.fat16.Signature == 0x28 || boot->ext.fat16.Signature == 0x29) correct_features++;
total_features++;
}
Log("Fat", "Correct features: %u out of %u. Type should be fat%u.\n", correct_features, total_features, fat);
// See what we have.
if (correct_features > (total_features/2)) return 0; // insuficcient correct features?
return fat; // return FAT type
}
void FatInstall()
{
FileSystem fat12 = {0, "fat12", Fat12Detect, 0,0,0,0,0,0,0,0};
FileSystem fat16 = {0, "fat16", Fat16Detect, 0,0,0,0,0,0,0,0};
FileSystem fat32 = {0, "fat32", Fat32Detect, 0,0,0,0,0,0,0,0};
VfsInstallFs(&fat12); VfsInstallFs(&fat16); VfsInstallFs(&fat32);
}