mkfs.fat leave FAT32 fields in BPB at null value

66 views Asked by At

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;
}
0

There are 0 answers