我在哪里可以找到如何直接从汇编中寻址硬盘驱动器(假设我在实模式或环 0 下运行)。例如,假设我想将扇区 100-200 的数据加载到 ram 中的某个位置。我将如何处理特定的硬盘驱动器以及如何告诉驱动器我想要哪些扇区?
问问题
5860 次
2 回答
4
我同意@joev 的观点,即使用 BIOS 调用可能是最容易做的事情,但如果你想自己动手,似乎你会想直接访问硬件。
对于 PATA 控制器(或设置为兼容模式的 SATA),您可以使用 PIO 进行简单的数据访问。OS Dev wiki 在这里有一篇关于它的深度文章:http ://wiki.osdev.org/ATA_PIO_Mode
您可以通过传统 I/O 端口 0x1f0-0x1f7(主要)和 0x170-0x177(次要)访问控制器。以下阅读示例来自 wiki 页面:
- 为“master”发送 0xE0 或为“slave”发送 0xF0,与 LBA 的最高 4 位进行或运算到端口 0x1F6:outb(0x1F6, 0xE0 | (slavebit << 4) | ((LBA >> 24) & 0x0F ))
- 如果愿意,可以向端口 0x1F1 发送一个 NULL 字节(它会被忽略并浪费大量 CPU 时间):outb(0x1F1, 0x00)
- 将扇区计数发送到端口 0x1F2:outb(0x1F2, (unsigned char) count)
- 将 LBA 的低 8 位发送到端口 0x1F3:outb(0x1F3, (unsigned char) LBA))
- 将 LBA 的下 8 位发送到端口 0x1F4:outb(0x1F4, (unsigned char)(LBA >> 8))
- 将 LBA 的下 8 位发送到端口 0x1F5:outb(0x1F5, (unsigned char)(LBA >> 16))
- 向端口 0x1F7 发送“READ SECTORS”命令 (0x20):outb(0x1F7, 0x20)
- 等待 IRQ 或轮询。
- 将 256 个字,一次一个字,从 I/O 端口 0x1F0 传输到您的缓冲区。(在汇编程序中,REP INSW 对此非常有效。)
- 然后循环回等待每个连续扇区的下一个 IRQ(或再次轮询 - 见下一个注释)。
还有更复杂的方式来访问驱动器(MMIO、更复杂的 PIO 模式、DMA 模式等),但这绝对是一个很好的起点。
于 2011-12-19T16:19:50.627 回答
2
当恐龙在地球上漫游时,您执行此操作的方式是使用“INT 13H”BIOS 调用,将 AH 设置为 02H。它甚至可能不适用于 SATA 时代的现代 PC。
在此处查找更多信息。如果您在问题中提供更多详细信息,您可能会得到更好的答案(即,您是否使用某种操作系统,或者这是某种“自己动手”的项目?)
于 2011-12-11T02:16:25.520 回答