2

我想要完成的工作:

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

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

“完全”,我的意思是只要 HDD 通电(一个自定义硬件 - 这是一个简单的开关,确保在加载应用程序并希望这样做之前,HDD 不会通电),第一个并且只有我的应用程序才能访问该 HDD。除了我的应用程序之外的 IOW,甚至 linux 内核(包括 SCSI 子系统)或任何其他应用程序或进程或人类用户都无法访问该 HDD,除非我的应用程序指示/允许他们这样做。

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

现在我面临的问题是:

SCSI 子系统位于 I/O 调度程序和内核缓冲区或页面缓冲区高速缓存下方(并被写入以与之一起工作)。

虽然 SCSI 子系统提供了 'sg-driver' 来直接发送命令(- Linux SCSI 子系统命令,而不是 ATA 或 SCSI 命令直接 - 然后由 libata 转换为实际的 ATA 命令。我在这里吗?) HDD,但这是一种 I/O 方法 - 你给 i/p 并获得 o/p,即你无法控制数据传输协议的过程(例如 PIO、DMA 和 ATA 状态和错误寄存器等)和设备配置(通过设置功能 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,以便我的应用程序可以直接与这个块驱动程序通信) w/o 涉及/弄乱内核缓冲区或页面缓冲区和 I/O 调度程序。此块驱动程序将直接与 libata 通信(绕过 SCSI 子系统上层),然后与 PATA/SATA HBA 驱动程序通信。

是否可以以独立于 cpu 架构的方式编写这样的驱动程序?

这是一种可行的方法吗?如果是,那么它会影响我的应用程序未访问的其他附加硬盘的 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 驱动程序。)对于大多数 HBA。

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

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

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

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

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

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

但此时我实现FPGA解决方案和嵌入式处理器解决方案在人力、时间和金钱方面是不可行的。所以我坚持使用纯软件解决方案

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

因此,在 VFS 层和 HBA 驱动程序或 libata 层之间,我应该如何进行。哪些事情需要实施,哪些不需要?

有人可以阐明这个问题吗?有任何想法吗??

Update2(2012 年 1 月 7 日)
我正在努力解决这个问题。SO上有没有人可以启发我?

4

1 回答 1

3

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

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

从用户空间做事可能需要通过内核中的代理来工作——不过,您需要在内核方面做对时间至关重要的事情。

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

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

于 2012-06-25T19:42:59.437 回答