使用程序集访问硬盘

Mic*_*vey 3 assembly bios

我在哪里可以找到如何直接从程序集寻址硬盘驱动器(假设我在实模式或环 0 下运行)。例如,假设我想将扇区 100-200 中的数据加载到 RAM 中的某个位置。我将如何寻址特定的硬盘驱动器以及如何告诉驱动器我想要哪些扇区?

小智 5

我同意 @joev 的观点,即使用 BIOS 调用可能是最简单的事情,但如果您想自己动手,似乎您需要直接访问硬件。

对于 PATA 控制器(或设置为兼容模式的 SATA),您可以使用 PIO 进行简单的数据访问。OS Dev wiki 有一篇关于它的深入文章:http ://wiki.osdev.org/ATA_PIO_Mode

您可以通过旧版 I/O 端口 0x1f0-0x1f7(主)和 0x170-0x177(辅助)访问控制器。以下读取示例来自 wiki 页面:

  1. 发送 0xE0 表示“主机”,或 0xF0 表示“从机”,与 LBA 的最高 4 位进行或运算到端口 0x1F6:outb(0x1F6, 0xE0 | (slavebit << 4) | ((LBA >> 24) & 0x0F ))
  2. 如果您愿意,可以将 NULL 字节发送到端口 0x1F1(它会被忽略并浪费大量 CPU 时间):outb(0x1F1, 0x00)
  3. 将扇区计数发送到端口 0x1F2:outb(0x1F2, (unsigned char) count)
  4. 将LBA的低8位发送到端口0x1F3:outb(0x1F3, (unsigned char) LBA))
  5. 将 LBA 的接下来 8 位发送到端口 0x1F4:outb(0x1F4, (unsigned char)(LBA >> 8))
  6. 将 LBA 的接下来 8 位发送到端口 0x1F5:outb(0x1F5, (unsigned char)(LBA >> 16))
  7. 发送“READ SECTORS”命令(0x20)到端口0x1F7:outb(0x1F7,0x20)
  8. 等待 IRQ 或轮询。
  9. 将 256 个字(一次一个字)从 I/O 端口 0x1F0 传输到缓冲区中。(在汇编程序中,REP INSW 非常适合此目的。)
  10. 然后循环返回等待每个连续扇区的下一个 IRQ(或再次轮询 - 请参阅下一个注释)。

还有更复杂的方法来访问驱动器(MMIO、更复杂的 PIO 模式、DMA 模式等),但这绝对是一个很好的起点。