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

QEMU的-hda选项含义及自研操作系统访问该模拟硬盘的技术咨询

QEMU -hda选项及自研OS访问模拟硬盘指南

1. -hda选项的含义

-hda是QEMU指定主IDE硬盘设备的启动参数,它会把你指定的镜像文件或物理块设备,模拟成IDE总线(默认)下的第一个主设备。举个实际命令示例:

qemu-system-x86_64 -hda my_disk.img

这条命令会将my_disk.img作为主IDE硬盘挂载到虚拟机中。

2. 自研OS识别设备挂载位置

  • 扫描IDE总线:QEMU默认把-hda模拟为IDE控制器的通道0(Primary)、主设备(Master),对应的I/O端口范围是0x1F0-0x1F7(数据/命令端口)和0x3F6(控制端口)。
  • 检测设备存在:通过读取IDE控制器的状态寄存器(端口0x1F7)判断是否有设备响应,或者执行IDENTIFY DEVICE命令读取设备识别信息,确认这是一个硬盘设备。
  • 记录设备标识:在OS的设备树或驱动链表中标记该设备为IDE主硬盘,后续用这个标识关联存储操作。

3. 访问设备的接口协议

QEMU默认用IDE协议模拟-hda,如果需要用SATA协议,得先调整QEMU启动命令,再在OS中实现对应驱动:

3.1 默认IDE协议访问步骤

IDE采用端口I/O操作,核心流程如下:

  1. 设置扇区数(端口0x1F2)、起始扇区的LBA地址(0x1F3-0x1F6,LBA28模式下用4个字节);
  2. 向命令寄存器(0x1F7)发送读/写命令,比如读命令是0x20;
  3. 轮询状态寄存器(0x1F7)等待操作完成,再从数据端口(0x1F0)读取或写入数据;
  4. 进阶优化:可以处理IDE控制器触发的IRQ14中断,实现异步操作,避免轮询占用CPU。

3.2 SATA协议访问(切换到AHCI控制器)

如果要让-hda对应SATA设备,先修改QEMU启动命令,把IDE换成AHCI控制器:

qemu-system-x86_64 -device ahci,id=ahci0 -drive id=disk0,file=my_disk.img,if=none -device ide-hd,drive=disk0,bus=ahci0.0

然后在自研OS中实现AHCI驱动,步骤如下:

  • AHCI是SATA的主机控制器接口,用内存映射I/O(MMIO)替代传统端口I/O;
  • 通过PCI总线枚举找到AHCI控制器的MMIO基地址(AHCI设备的PCI类代码是0x0106);
  • 初始化AHCI控制器:启用全局中断、设置端口状态;
  • 对目标端口(比如端口0)发送FIS(Frame Information Structure)命令,比如IDENTIFY DEVICE、READ DMA EXT等;
  • 采用DMA方式传输数据,效率比IDE的PIO方式高很多。

4. 实操简化示例(IDE硬盘读扇区)

下面是自研OS中读取IDE硬盘第一个扇区的伪代码实现:

// 读取IDE硬盘第一个扇区的简化代码
void read_ide_sector(uint32_t lba, uint8_t* buf) {
    cli(); // 禁用中断
    // 设置读取扇区数为1
    outb(0x1F2, 1);
    // 写入LBA地址(LBA28模式)
    outb(0x1F3, lba & 0xFF);
    outb(0x1F4, (lba >> 8) & 0xFF);
    outb(0x1F5, (lba >> 16) & 0xFF);
    outb(0x1F6, 0xE0 | ((lba >> 24) & 0x0F)); // 指定主设备+LBA模式
    // 发送读扇区命令
    outb(0x1F7, 0x20);
    // 等待设备就绪
    while (!(inb(0x1F7) & 0x08));
    // 读取512字节数据(insw一次读2字节,循环256次)
    insw(0x1F0, buf, 256);
    sti(); // 恢复中断
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 14:32:33