3

我正在编写一个有趣的操作系统,我正在尝试编写一个 PATA/IDE 驱动程序来访问磁盘,但是它不起作用。我有这行unsigned char status = port_byte_in(ATAPort + COMMANDPORT);返回 88(十进制)的值。由于这可能表明我做错了什么,并且作为其他人的参考,PATA/IDE 状态代码是什么?

我的驱动程序遵循28 位 PIO PATA/IDE 进程。

编辑-澄清一下,这是port_byte_in功能:

unsigned char port_byte_in(unsigned short port) {
    unsigned char result;
    __asm__("in %%dx, %%al" : "=a" (result) : "d" (port));
    return result;
}

并且ATAPort0x1F0, COMMANDPORT=0x07

4

2 回答 2

1

在您考虑为任何类型的设备编写设备驱动程序之前,您需要查找/下载并阅读该设备的所有相关规范(您不应依赖陌生人的部分异端邪说)。

大多数相关规范是由 T13 工作组创建的 ANSI 标准;可以在此处找到它们的列表:http ://www.t13.org/Standards/Default.aspx?DocumentType=3

不幸的是,它们不是免费的(您应该为副本付费 ANSI,因为从事不再具有商业相关性的东西的无偿业余程序员得到的待遇与制造硬件以营利的公司相同(!))。幸运的是,网络搜索(从 T13 列表中搜索文档的标题)通常会找到与最终标准几乎相同的草稿版本。

有许多(八个?)版本的“AT Attachment”规范(加上您还需要的其他规范)。您所说的寄存器是 IDE/ATA 控制器的状态寄存器,并在这些规范中定义。在不同版本的规范中,状态寄存器位的一些定义已经改变(变成“取决于命令”或“过时”);并且“取决于命令”(对于状态寄存器的第 4 位)听起来像 - 该位的含义取决于您最后给控制器发出的命令。

于 2019-11-13T03:02:42.797 回答
1

布伦丹的回答提出了一些很好的观点。另外,请注意从命令寄存器读取实际上是从状态寄存器读取。命令寄存器是只写的,而从同一地址读取是从状态寄存器读取。然后,如果该寄存器显示控制器忙,第 7 位设置,从状态寄存器读取可能并且可能返回未定义的结果。

返回值 88d (0x58) 是状态寄存器的一个非常常见的返回值。这显示为:01011000b

bit 7 = 0 = not busy
bit 6 = 1 = Drive is ready
bit 5 = x = command specific
bit 4 = x = command specific
bit 3 = 1 = Data Request
bit 2 = 0 = obsolete (command specific)
bit 1 = 0 = obsolete (command specific)
bit 0 = 0 = no error

考虑到这一点,请注意第 3 位已设置。这意味着控制器/驱动器已准备好/期待数据传输,具体取决于发送的命令。

例如,如果您发送了 READ 命令,则该位表示您已准备好从数据寄存器中读取(假设您正在使用 PIO)。如果您正在读取字(16 位值),您应该读取数据寄存器 256 次,该位将被清除。

请注意,如果您一次读取多个扇区,则在读取每个扇区后都会收到一个中断,无论您正在读取多少个扇区,并且将再次为下一个扇区设置 DRQ 位(位 3) .

对于写操作,DRQ 位指示驱动器已准备好进行写操作。即:将一个 16 位字写入 DATA 寄存器。

32 位读取和写入是相同的,尽管您只传输 128 个字而不是 256 个字。

此外,从状态寄存器中读取会清除命令的中断状态,从而向控制器指示可以启动下一个命令。有时这不是本意。因此,控制器有一个 ALT STATUS 寄存器,它返回完全相同的结果而不清除中断状态。您应该从中读取,直到您准备好清除中断。

于 2019-11-16T02:06:29.697 回答