小智 5
我同意 @joev 的观点,即使用 BIOS 调用可能是最简单的事情,但如果您想自己动手,似乎您需要直接访问硬件。
对于 PATA 控制器(或设置为兼容模式的 SATA),您可以使用 PIO 进行简单的数据访问。OS Dev wiki 有一篇关于它的深入文章:http ://wiki.osdev.org/ATA_PIO_Mode
您可以通过旧版 I/O 端口 0x1f0-0x1f7(主)和 0x170-0x177(辅助)访问控制器。以下读取示例来自 wiki 页面:
- 发送 0xE0 表示“主机”,或 0xF0 表示“从机”,与 LBA 的最高 4 位进行或运算到端口 0x1F6:outb(0x1F6, 0xE0 | (slavebit << 4) | ((LBA >> 24) & 0x0F ))
- 如果您愿意,可以将 NULL 字节发送到端口 0x1F1(它会被忽略并浪费大量 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))
- 发送“READ SECTORS”命令(0x20)到端口0x1F7:outb(0x1F7,0x20)
- 等待 IRQ 或轮询。
- 将 256 个字(一次一个字)从 I/O 端口 0x1F0 传输到缓冲区中。(在汇编程序中,REP INSW 非常适合此目的。)
- 然后循环返回等待每个连续扇区的下一个 IRQ(或再次轮询 - 请参阅下一个注释)。
还有更复杂的方法来访问驱动器(MMIO、更复杂的 PIO 模式、DMA 模式等),但这绝对是一个很好的起点。