I have problem that mkfs.fat leave FAT32 fields null with parameter -F 32. I am creating own bootloader and trying to read from EFI partition but somehow these values are at null value. Fields before FAT32 fields are set correctly. To read from disk I use ATA PIO mode.
Here is my BPB structure:
#pragma pack(1)
typedef struct {
uint8_t jmpnop[3];
char OEMIdentifier[8];
uint16_t BytesPerSector;
uint8_t SectorsPerCluster;
uint16_t NumberOfReservedSectors;
uint8_t NumberOfFATs;
uint16_t NumberOfRootDirectories;
uint16_t TotalSectors;
uint8_t Media;
uint16_t Reserved;
uint16_t SectorsPerTrack;
uint16_t NumberOfHeads;
uint32_t HiddenSectors;
uint32_t LargeSectorCount;
} BPB;
typedef struct {
BPB base;
uint32_t SectorsPerFat;
uint16_t Flags;
uint16_t Version;
uint32_t ClusterNumberRootDir;
uint16_t SectorNumberFSInfo;
uint16_t SectorNumberBackupBootSector;
uint8_t Reserved[12];
uint8_t DriveNumber;
uint8_t Reserved2;
uint8_t Signature;
uint32_t VolumeID;
uint8_t VolumeLabel[11];
char SystemIdentifier[8]; //Specs says never trust
} BPB_FAT32;
I tried adding parameter for verbose to mkfs.fat
and it seems it doing everything well.
Update, maybe it will be issue of my ata pio mode driver because it seems that the disk doesn't read the whole sector. Here is my read function of my ata pio mode driver:
uint8_t Read(Disk *d,uint32_t LBA,uint16_t num,uint32_t addr)
{
//check if LBA48 is supported,if yes it will use LBA48 mode otherwise it will use LBA28 mode
if(d->LBA48 == 1)
{
if(d->dev == MASTER_DRIVE)
{
outb(d->bus+DRIVE,0x40);
}
else {
outb(d->bus+DRIVE,0x50);
}
while(((inb(d->bus) >> 7) & 1) != 0);
uint16_t LBAmiddle = (uint16_t)(LBA >> 16) & 0xFFFF;
outw(d->bus+SECTOR_COUNT_REGISTER, num);
outw(d->bus+LBAlo,(uint16_t)LBA & 0xFFFF);
if(LBAmiddle > 0) outw(d->bus+LBAmid,LBAmiddle);
outb(d->bus+COMMAND,READ_LBA48);
}
else {
if(d->dev == MASTER_DRIVE)
{
outb(d->bus+DRIVE,0xE0);
}
else {
outb(d->bus+DRIVE,0xF0);
}
while(((inb(d->bus) >> 7) & 1) != 0);
outw(d->bus+SECTOR_COUNT_REGISTER, num);
outb(d->bus+LBAlo,(uint8_t)LBA & 0xFF);
outw(d->bus+LBAmid,(uint8_t)(LBA << 8) & 0xFF);
outw(d->bus+LBAhi, (uint8_t)(LBA << 16) & 0xFF);
outb(d->bus+COMMAND,READ_LBA28);
}
//wait until drive is ready to send data and check for error
ATAsleep(d->bus);
if(error == 1)
{
return inb(d->bus+ERROR_REGISTER);
}
//return the data
//the driver count that the user has drive with 512 bytes sector size
uint16_t *data = (uint16_t*)addr;
for(int i = 0; i < (256*num);i++)
{
data[i] = inw(d->bus+DATA_REGISTER);
}
return 0;
}