我有一个问题,mkfs.fat 使用参数 -F 32 将 FAT32 字段保留为空。我正在创建自己的引导加载程序并尝试从 EFI 分区读取,但不知何故这些值处于空值。 FAT32 字段之前的字段设置正确。为了从磁盘读取,我使用 ATA PIO 模式。
这是我的 BPB 结构:
#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;
我尝试向 mkfs.fat 添加详细参数,看起来一切都很好
更新,也许是我的ata pio模式驱动程序的问题,因为磁盘似乎没有读取整个扇区。 这是我的 ata pio 模式驱动程序的读取功能:
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;
}