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

Linux kernel 绕过I/O调度和linux内核页面缓冲,linux-kernel,linux-device-driver,sata,ata,hard-drive,Linux Kernel,Linux Device Driver,Sata,Ata,Hard Drive,我想要达到的目标是: Developing an linux application in C language, that "exclusively" accesses a PATA/SATA硬盘驱动器(HDD)发送ATA命令(实际上,只有那些 请勿修改访问的HDD上的任何字节-例如读取扇区、识别设备、设置功能, 等等) 所谓“独占”,我的意思是,只要HDD通电(一种自定义硬件,它是一个简单的开关,确保在加载应用程序并希望这样做之前,HDD不会通电),对该HDD的第一个也是唯一的访问就是我的

我想要达到的目标是:

Developing an linux application in C language, that "exclusively" accesses a
PATA/SATA硬盘驱动器(HDD)发送ATA命令(实际上,只有那些 请勿修改访问的HDD上的任何字节-例如读取扇区、识别设备、设置功能, 等等)

所谓“独占”,我的意思是,只要HDD通电(一种自定义硬件,它是一个简单的开关,确保在加载应用程序并希望这样做之前,HDD不会通电),对该HDD的第一个也是唯一的访问就是我的应用程序。IOW除了我的应用程序之外,即使是linux内核(包括SCSI子系统)或任何其他应用程序或进程或人类用户都无法访问该硬盘,除非我的应用程序指示/允许他们这样做

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

现在我面临的问题是:

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

虽然SCSI子系统提供了“sg驱动程序”来直接向硬盘发送命令(-Linux SCSI子系统命令,而不是ATA或SCSI命令-然后由libata转换为实际ATA命令。我在这里吗?),但这是一种I/O方法-您给出I/p并获得O/p,也就是说,您无法控制数据传输协议(如PIO、DMA和ATA状态和错误寄存器等)和设备配置(通过Set Features ATA命令)的过程

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

我的应用程序要求的是对硬盘的独占控制-例如,必须满足以下要求:发出读扇区ATA命令,然后通过读i/o端口或通过“libata”直接从硬盘检索数据本身

我不能做什么

我不打算编写PATA/SATA HBA设备驱动程序,也不打算编写市场上所有可用的HBA,因为它们已经包含在libata内核中

到现在为止我学到了什么

为了完成所需的任务,我可能(也可能不?)需要编写一个块设备驱动程序,该驱动程序直接与VFS层交互(或者是否有任何方法可以绕过VFS,以便我的应用程序可以直接与该块驱动程序通信),不涉及/干扰内核缓冲区或页面缓冲区以及I/o调度程序。 此块驱动程序将直接与libata通信(绕过SCSI子系统上层),libata然后与PATA/SATA HBA驱动程序通信

是否有可能以独立于cpu体系结构的方式编写这样的驱动程序

这是一个可行的方法吗?如果是,则会影响我的应用程序无法访问的其他连接的HDD的I/O性能。就这样。在这种情况下,我的应用程序是否需要通过VFS编写系统调用(或在可能的情况下绕过它),以便与我的块驱动程序通信? 请告诉我这个方法

或者我的块设备驱动程序是否可以直接与为libata编写的PATA/SATA HBA驱动程序通信, 但同样,这种方法会影响我的应用程序无法访问的其他连接的硬盘的I/O性能。就这样。我的应用程序如何与这个块设备驱动程序通信

请开导我

此外,我还想了解我的应用程序的相同场景,但有一个不同点——如果我有SCSI硬盘驱动器及其变体,那么我会使用PATA/SATA驱动器,特别是SAS、光纤通道和USB驱动器。当然,这次我不会使用libata和ATA命令,而是使用SCSI协议命令

您是否建议使用live cd发行版作为我的应用程序主机,该发行版包含PATA/SATA HBA libata驱动程序(不适用于IDE子系统,因为我不会使用它,因为它现在已贬值,因此可能不会更新HBA驱动程序)

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

我希望,我已经就我的问题提供了足够的信息,但如果你想得到更多信息或更多的澄清,请随时提问

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

  • 一个现成的USB到PATA/SATA适配器不能解决我的目的,因为它不允许我的应用程序。或者驱动程序在运行中更改数据传输模式(PIO vs DMA),它不允许我的应用程序。或驱动程序读取ATA寄存器

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

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

    但在这一点上,无论是人力、时间还是金钱,我都不可能实现FPGA解决方案和嵌入式处理器解决方案。因此,我坚持使用纯软件解决方案