在实现显卡驱动后,我们下一个必须要访问的硬件就轮到硬盘了。同样的,在保护模式下,所有的BIOS中断例程都无法使用,当然也包括硬盘服务INT 13H。所以我们必须通过直接读写端口来访问硬盘。
硬盘有一个接口标准,叫做ATA/ATAPI。这个标准现在已经发展到第8版,里面甚至包括了串行ATA的内容。但是由于我们的虚拟机不支持如此最新的ATA标准,因此我们只能按照旧标准来操作硬盘。
对于硬盘,最常用的操作就是读扇区和写扇区。我们在LOADER中也只需要实现这两个操作。IDE标准定义了8个寄存器来操作硬盘。PC体系结构将第一个硬盘控制器映射到端口1F0-1F7处,而第二个硬盘控制器则被映射到端口170-177处。这几个寄存器的描述如下(以第一个控制器为例):
1F0 - 数据寄存器。读写数据都必须通过这个寄存器
1F1 - 错误寄存器,每一位代表一类错误。全零表示操作成功。
1F2 - 扇区计数。这里面存放你要操作的扇区数量
1F3 - 扇区LBA地址的0-7位
1F4 - 扇区LBA地址的8-15位
1F5- 扇区LBA地址的16-23位
1F6(低4位) - 扇区LBA地址的24-27位
1F6(第4位) - 0表示选择主盘,1表示选择从盘
1F6(5-7位) - 必须为1
1F7(写)- 命令寄存器
1F7(读)- 状态寄存器
bit 7 = 1 控制器忙
bit 6 = 1 驱动器就绪
bit 5 = 1 设备错误
bit 4 N/A
bit 3 = 1 扇区缓冲区错误
bit 2 = 1 磁盘已被读校验
bit 1 N/A
bit 0 = 1 上一次命令执行失败
当我们要读写扇区时,我们可以向各个寄存器中输入要读写的扇区地址和数量:
然后检查错误寄存器和状态寄存器,确定寄存器没有错误,控制器也不忙。 最后,我们往命令寄存器中发送一条命令(20h为读,30h为写)。这里我们以读为例
操作完成后,控制器会产生一个中断IRQ14。 当然,我们现在还没有初始化中断控制器,所以我们只能不断的检查状态寄存器,直到其不忙,此时就意味着操作完成了。
操作完成后,我们便可以通过1f0端口来读取或写入数据了。
好了硬盘操作便是如此,下一节,我们来讲述RMOSLDR中的硬盘驱动。