繁体   English   中英

使用IOKit制作虚拟IOPCIDevice

[英]Making a virtual IOPCIDevice with IOKit

我设法创建了一个虚拟IOPCIDevice,该虚拟IOPCIDevice附加到IOResources上并且基本上什么都不做。 我可以让现有的驱动程序进行注册并与其匹配。

但是,当涉及到IO处理时,我会遇到一些麻烦。 IOPCIDevice类中描述的功能(例如configRead,ioRead,configWrite,ioWrite)对IO的访问可以由我自己的代码处理。 但是使用内存映射和IODMACommand的驱动程序是问题所在。

我似乎需要管理两件事:IODeviceMemory(在IOPCIDevice中描述)和DMA传输。

我如何创建一个最终指向内存/ RAM的IODeviceMemory,以便当驱动程序尝试与PCI设备通信时,它最终什么也不做,或者只是将数据移至RAM,这样我的用户空间客户端就可以处理此数据并充当仿真器PCI设备?

然后可以将DMA命令也直接定向到我的用户空间客户端,而不会干扰使用IODMACommand的现有驱动程序的源代码。

谢谢!

陷阱内存访问

因此,从理论上讲,要实现所需的功能,您需要分配一个内存区域,将其保护位设置为只读(或者如果要模拟的设备中的读取有副作用,则可能既不读取也不写入),并且然后将所有写操作捕获到您自己的处理程序函数中,然后在其中模拟设备寄存器写操作。

据我所知,您可以使用Mach异常处理在macOS用户空间中执行此类操作。 您需要将要控制的过程中的页面保护错误异常设置为发送到您控制的Mach端口。 在该端口的消息处理程序中,您将:

  • 检查访问权限
  • 如果是设备内存,则将挂起进程的所有线程
  • 将写操作来自的线程切换到单步执行,暂时允许写操作到内存区域
  • 恢复作者线程
  • 捕获单步消息。 您的“设备存储器”现在包含已写入的值。
  • 执行“设备的”副作用。
  • 在编写器线程中关闭单步操作。
  • 恢复所有线程。

正如我所说,我相信这可以在用户空间流程中完成。 这并不容易,您可以从网络上各种晦涩的示例中整理所需的Mach调用。 我曾经有过类似的工作,但是对不起,似乎再也找不到该代码了。

…在内核中

现在,另一个问题是您正在尝试在内核中执行此操作。 我不知道有任何公共KPI可以让您执行如上所述的操作。 您可以在以下地方开始寻找黑客:

  • 您可以很容易地使IOMemoryDescriptor由系统内存支持。 不必担心IODeviceMemory术语:这些只是IOMemoryDescriptor对象; IODeviceMemory类是一个谎言 陷阱访问完全是另一回事。 原则上,您可以使用createMappingInTask()函数的“引用”标志找出特定MD的哪些虚拟内存映射存在,然后在返回的IOMemoryMap上使用NULL支持的内存参数调用redirect()方法。 不幸的是,这只会暂停任何试图访问该映射的线程。 发生这种情况时,您不会收到回调。
  • 您可以深入研究Mach VM内存子系统的内容,该子系统主要位于xnu源的osfmk/vm/目录中。 也许有一种方法可以在那里为VM区域设置自定义故障处理程序。 不过,您可能会不得不使用私有内核API。

为什么?

最后,您为什么要尝试这样做? 退后一步:您最终要尝试做什么? 以这种方式模拟PCI设备似乎并没有结束,所以这真的是唯一实现更大目标的唯一方法吗? 请参阅:XY问题

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM