绕过I / O调度和linux内核页面缓冲

时间:2012-06-25 15:21:32

标签: linux-kernel linux-device-driver sata ata hard-drive

我想要完成的任务:

Developing an linux application in C language, that "exclusively" accesses a

PATA / SATA硬盘驱动器(HDD)发送ATA命令(实际上只有那些ATA命令 不要修改访问的硬盘上的任何字节 - 例如。 READ_SECTOR,IDENTIFY_DEVICE,SET_FEATURES, 等)。

"专属",我的意思是只要硬盘开机(自定义硬件 - 一个简单的开关开关,确保硬盘在开启应用程序之前不开机,希望这样做),第一次也是唯一一次只能访问我的应用程序。 IOWs除了我的应用程序,甚至Linux内核(包括SCSI子系统),任何其他应用程序或进程或人类用户都无法访问该硬盘驱动器,除非我的应用程序指示/允许他们这样做。

我的申请还有另一项要求:     由于在我们的应用程序中访问HDD非常关键(在控制而非性能方面),因此不希望任何I / O调度涉及应用程序完成的事务(此HDD上的性能是不是约束。)此外,不希望从HDD读取的数据由内核缓冲区或页面缓冲区缓冲。应用程序将读取512字节的块大小或仅为其倍数。

现在我遇到的问题是:

SCSI子系统位于I / O调度程序和内核缓冲区或页面缓冲区缓存之下(并编写为使用)。

虽然' sg-driver' SCSI子系统提供直接发送命令( - Linux SCSI子系统命令,而不是直接ATA或SCSI命令 - 然后通过libata将其转换为实际的ATA命令。我在这里吗?)到HDD,但那是I / O方法 - 你给i / p并获得o / p,即你无法控制数据传输协议的过程(例如PIO,DMA和ATA状态和错误寄存器等)和设备配置(通过Set功能ATA命令。)。

此外,错误报告机制必须合理,并且特定于ATA协议,而不仅仅是Linux SCSI子系统错误代码。 IOWs我的应用程序需要访问PATA / SATA HDD上的ATA错误寄存器和ATA状态寄存器。

我的应用程序要求的是对HDD的独占控制 - 例如。发出READ_SECTOR ATA cmd然后通过读取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性能。通过这种方式。我的应用程序如何与此块设备驱动程序通信?

请赐教。

此外,我想知道我的应用程序的相同情况,但有一点不同 - 如果我有SCSI硬盘驱动器及其变体 - 特别是SAS,光纤通道和USB,那么将取代PATA / SATA驱动器。当然,这次我不会使用libata和ATA命令,而是使用SCSI协议命令。

你想建议一个live cd发行版作为我的应用程序主机,它包含PATA / SATA HBA libata驱动程序( - 不适用于IDE子系统,因为我不会使用它因为它现在被折旧因此可能不是关于HBA驱动程序的更新。)对于大多数HBA而言。

简而言之,Linux应用程序访问PATA / SATA或SCSI / SAS /光纤通道硬盘的最直接方式是什么。

我希望,我已就我的问题提供了足够的信息,但如果您想获得更多信息或更多说明,请随时提出。

Update1(2012年6月27日)
通过与Chris(见下文)和我的研究的有益讨论,我得出以下结论:

  1. 现成的USB-to-PATA / SATA适配器无法解决我的目的,becoz它不允许我的应用程序。或驱动程序即时更改数据传输模式(PIO与DMA),它不允许我的应用程序。或驱动程序读取ATA寄存器。

  2. 定制的USB-to-PATA / SATA适配器可能有所帮助,但这需要一个需要实现ATA协议的嵌入式处理器,或一个实现整个ATA协议的FPGA芯片。 但嵌入式处理器解决方案涉及GPIO,并不适合SATA,因为它需要专门的收发器,而I / O性能对于PATA和SATA都是一个问题 - 对我的应用来说太慢了。

  3. 这样的适配器将与我的linux内核驱动程序(或通过libusb)通信到我的应用程序。通过自定义协议,帮助我的应用程序通信。和嵌入式处理器上的ATA协议。 在FPGA芯片解决方案的情况下,我需要在FPGA本身以及ATA协议中实现该协议。

    但在这一点上,我在实施FPGA解决方案和嵌入式处理器解决方案方面的劳动力,时间和金钱是不可行的。所以我坚持使用 仅限软件的解决方案

    最后,似乎我可能不得不复制并修改所有内容到硬件接口层,以满足Chris所说的要求。

    那么, 在VFS层和HBA驱动程序或libata层之间,我应该如何继续。需要实施什么,什么不需要?

    有人可以解释这个问题吗?任何想法??

    Update2(2012年1月7日)
    我正在努力解决这个问题。是否有人可以开导我?

1 个答案:

答案 0 :(得分:3)

实际上,如果你想要这种级别的细节控制, 最终将不得不编写你自己的低级驱动程序。

您对避免I / O缓冲和调度的约束可能特别具有挑战性 - 您可能会避免使用DMA,但出于性能原因,现代处理器的I / O会与内部操作分离。也许如果你可以完全禁用所有中断,你至少可以在你做事时给时间戳。您可能希望驱动器拥有自己的接口适配器,当然不能与正在运行的文件系统共享。

从用户空间做事可能需要通过内核中的代理工作 - 你需要在内核端执行时序关键的事情。

一个更简单的解决方案,如果满足您的需求,将使用USB转SATA或PATA适配器。您可以使用modprobe的quirks模式告诉现有内核驱动程序忽略VID / PID,然后通过libusb从用户空间与设备通信。但是,肯定会有延迟。

对于最精细的控制级别,您可能需要将驱动器连接到没有I / O缓冲的嵌入式处理器,甚至可能是FPGA。对于使用PATA的低数据速率,这并不是特别难以做到,SATA可能需要专门的收发器,但可能不属于可能性范围(或者您可以通过其中一个适配器工作)。您可能最终会通过USB或甚至串行端口将此自定义外设连接到PC,并使用它来发出任务并获得结果(如果您进行设置以便PC可以下载设备的固件/比特流,那么会很方便,所以你有灵活性。)