我想要实现的目标:
Developing an linux application in C language, that "exclusively" accesses a
PATA/SATA硬盘驱动器可以发送ATA命令(实际上只有那些不修改访问的HDD上的任何字节的ATA命令,例如:READ_SECTOR,IDENTIFY_DEVICE,SET_FEATURES等)。
“独占”是指只要硬盘被开启(一个自定义的硬件-一个简单的开关,确保只有当应用程序加载并需要时才会将硬盘开启),对该硬盘的第一次和唯一的访问只属于我的应用程序。换句话说,除了我的应用程序外,甚至连Linux内核(包括SCSI子系统)也无法访问该硬盘,也没有其他应用程序、进程或人工用户能够访问该硬盘,除非我的应用程序指示/允许它们这样做。
我的应用程序还有另一个要求: 由于在我们的应用程序中,对HDD的访问是相当关键的(从控制而不是性能方面),因此不希望任何I/O调度程序参与应用程序所做的事务(这个HDD的性能并不是约束因素)。同时,也不希望从HDD读取的数据被内核缓冲区或页面缓冲区缓存。应用程序将仅以512字节的块大小或其倍数进行读取。
现在我面临的问题是: SCSI子系统位于I/O调度程序和内核缓冲区或页面缓冲区缓存之下。
虽然SCSI子系统提供了“sg-driver”来直接发送命令(Linux SCSI子系统命令,不是ATA或SCSI直接命令-然后由libata将其转换为实际的ATA命令。我在这里是正确的吗?)到HDD,但这是一种I/O方法-你提供输入并获取输出,即你对数据传输协议的过程没有控制(例如PIO、DMA和ATA状态和错误寄存器等)和设备配置(通过Set Features ATA命令)。此外,错误报告机制必须健全,并且特定于ATA协议,而不仅仅是Linux SCSI子系统错误代码。换句话说,我的应用程序需要访问PATA/SATA HDD上的ATA错误寄存器和ATA状态寄存器。
我的应用程序要求独占控制HDD-例如发出一个READ_SECTOR ATA命令,然后直接通过读取I/O端口或通过“libata”从HDD本身检索数据,并满足上述要求。
我不能做什么?
我不打算编写PATA/SATA HBA设备驱动程序或市场上可用的每个HBA,因为这些已经包含在libata的内核中。
我现在学到了什么?
为了完成所需的任务,我可能(或可能不需要?)需要编写一个块设备驱动程序,直接与VFS层交互(或是否有任何方法可以绕过VFS,以便我的应用程序可以直接与此块驱动程序通信),而不涉及/干扰内核缓冲区或页面缓冲区和I/O调度程序。这个块驱动程序将直接与libata通信(绕过SCSI子系统上层),然后与PATA/SATA HBA驱动程序通信。
有没有可能以与CPU架构无关的方式编写这样的驱动程序?
这种方法可行吗?如果是,那么这会影响其他连接的未被我的应用程序访问的硬盘驱动器的I/O性能吗?在这种情况下,我需要为我的应用程序编写一个系统调用来与我的块驱动程序通信吗(如果可能的话绕过VFS)?
还是说我的块设备驱动程序可以直接与为libata编写的PATA/SATA HBA驱动程序通信?但是同样地,这种方法会影响其他连接的未被我的应用程序访问的硬盘驱动器的I/O性能吗?另外,我的应用程序如何与这个块设备驱动程序通信?
对于相同的场景,我想知道应用程序的情况,只有一个区别-除了PATA/SATA驱动器之外,如果我有SCSI硬盘及其变体-特别是SAS、光纤通道和USB。当然,这次我不会使用libata和ATA命令,而是使用SCSI协议命令。
您是否想建议一个包含大多数HBA的PATA/SATA HBA libata驱动程序(-不适用于IDE子系统,因为我将不会使用它,因为它已经过时,因此可能不会更新与HBA驱动程序相关的内容)的live cd发行版,作为我的应用程序主机。
简而言之,Linux应用程序访问PATA/SATA或SCSI/SAS/光纤通道HDD的最直接方式是什么?
我希望我已经提供了关于我的问题足够的信息,但如果您需要更多的信息或更多的澄清,请随时提问。
更新1(于2012年6月27日):
通过与Chris的有益讨论和我的研究,我得出了以下结论:
1.预制的USB到PATA/SATA适配器无法解决我的目的,因为它不允许我的应用程序或驱动程序在运行时更改数据传输模式(PIO vs DMA),也不允许我的应用程序或驱动程序读取ATA寄存器。
2.定制的USB到PATA/SATA适配器可能有所帮助,但这将需要实现ATA协议的嵌入式处理器或实现整个ATA协议的FPGA芯片。但是,嵌入式处理器解决方案涉及GPIO,并且对于SATA来说并不好,因为它需要专门的收发器,并且对于PATA和SATA的I/O性能都会成为一个问题。
这样的适配器将通过自定义协议与我的Linux内核驱动程序(或通过libusb)交互,以帮助我的应用程序与嵌入式处理器上的ATA协议进行通信。在FPGA芯片解决方案的情况下,我需要在FPGA本身中实现这个协议以及ATA协议。
但是,就劳动力、时间和金钱而言,在我实现FPGA解决方案和嵌入式处理器解决方案方面是不可行的。所以我只能使用纯软件解决方案。
最后,似乎我可能需要复制并修改所有内容,直到硬件接口层,以满足克里斯的要求。
那么,在VFS层和HBA驱动程序或libata层之间,我应该如何进行?哪些东西需要实现,哪些不需要?
可以有人解决这个问题吗?任何想法吗? 更新2(于2012年1月7日):
我正在努力解决这个问题。在SO上有没有人可以启迪我一下?