You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用mkfs.fat -F32创建分区后FAT32 BPB字段为空问题

自制Bootloader读取FAT32分区BPB异常问题修复

核心问题定位

你的问题根源是ATA PIO驱动的LBA地址写入逻辑错误,导致读取扇区的地址偏移错误,无法正确获取FAT32专属BPB字段;同时LBA48模式的地址写入不完整,进一步加剧了读取异常。

具体修复方案

1. 修复LBA28模式地址写入错误

原LBA28分支中,错误使用outw操作8位寄存器,且移位取位逻辑完全错误:

// 错误代码
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);

修复后:

// 正确写入LBA28的8位分段地址
outb(d->bus+LBAlo, (uint8_t)(LBA & 0xFF));          // LBA低8位([7:0])
outb(d->bus+LBAmid, (uint8_t)((LBA >> 8) & 0xFF));  // LBA中8位([15:8])
outb(d->bus+LBAhi, (uint8_t)((LBA >> 16) & 0xFF));  // LBA高8位([23:16])

注意:LBAmid和LBAhi是8位寄存器,必须用outb而非outw,同时要正确提取对应位段。

2. 补全LBA48模式地址写入

原LBA48分支仅写入了低32位地址,遗漏了高16位,导致超过32位的LBA地址解析错误:

// 修复后的LBA48地址写入逻辑
if(d->LBA48 == 1)
{
    outb(d->bus+DRIVE, d->dev == MASTER_DRIVE ? 0x40 : 0x50);
    while(((inb(d->bus) >> 7) & 1) != 0);
    
    outw(d->bus+SECTOR_COUNT_REGISTER, num);             // 16位扇区计数
    outw(d->bus+LBAlo, (uint16_t)(LBA & 0xFFFF));        // LBA[15:0]
    outw(d->bus+LBAmid, (uint16_t)((LBA >> 16) & 0xFFFF));// LBA[31:16]
    outw(d->bus+LBAhi, (uint16_t)((LBA >> 32) & 0xFFFF));// LBA[47:32]
    
    outb(d->bus+COMMAND, READ_LBA48);
}

移除原代码中多余的if(LBAmiddle > 0)判断,必须完整写入所有3个16位地址段,哪怕值为0。

3. 增强扇区读取的健壮性

在读取数据前,需确保驱动器处于数据就绪状态,避免读取无效数据:

// 读取数据循环添加DRQ状态检查
uint16_t *data = (uint16_t*)addr;
for(int i = 0; i < (256*num);i++)
{
    // 等待驱动器发出数据就绪信号(DRQ位为1)
    while(!(inb(d->bus + 0x07) & 0x08)); 
    data[i] = inw(d->bus+DATA_REGISTER);
}

0x07是ATA状态寄存器地址,0x08是DRQ(数据请求)位的掩码。

4. BPB结构体验证

你的BPB/FAT32 BPB结构体定义正确(已用#pragma pack(1)消除对齐问题),且x86架构为小端字节序,与FAT32的字段存储格式匹配,无需额外修改。

验证步骤

  1. 修复驱动代码后,重新编译Bootloader
  2. 读取EFI分区的引导扇区到内存
  3. 打印BPB_FAT32中的SectorsPerFat、ClusterNumberRootDir等专属字段
  4. 与mkfs.fat -v输出的分区信息对比,确认字段值一致

内容的提问来源于stack exchange,提问作者Honzasko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 13:24:51