我成功地创建了一个虚拟IOPCIDevice,它连接到IOResources,基本上什么也不做。我能够让现有的司机注册和匹配它。
然而,当涉及到IO处理时,我遇到了一些麻烦。在configRead类中描述的通过函数(例如ioRead、configWrite、ioWrite)进行的IO访问可以由我自己的代码处理。但是使用内存映射和IODMACommand的驱动程序才是问题所在。
我似乎需要管理两件事:IODeviceMemory(在IOPCIDevice中描述)和DMA传输。
我如何创建最终指向内存/RAM的IODeviceMemory,以便当驱动程序试图与PCI设备通信时,它最终什么也不做,或者只是将数据移动到RAM,这样我的用户空间客户端就可以处理这些数据并充当模拟的PCI设备?
然后,DMA命令也可以定向到我的用户空间客户端,而不会干扰使用IODMACommand的现有驱动程序源代码。
谢谢!
发布于 2017-12-30 12:57:53
捕获内存访问
因此,从理论上讲,要实现您想要的目标,您需要分配一个内存区域,将其保护位设置为只读(如果您正在模拟的设备中的读取有副作用,则可能既不读也不写),然后将任何写入设置到您自己的处理程序函数中,然后模拟设备寄存器写入。
据我所知,您可以在macOS用户空间中使用Mach异常处理来完成这类操作。您需要设置页面保护、故障异常、您控制的进程的异常、发送到您控制的Mach端口。在该端口的消息处理程序中,您可以:
正如我所说的,我相信这可以在用户空间进程中完成。这是不容易的,你可以拼凑马赫调用,你需要从各种模糊的例子在网上使用。我有类似的工作曾经,但似乎找不到代码了,对不起。
…在内核中
现在,另一个问题是在内核中尝试这样做。我不知道有任何公共KPI允许您做我前面描述过的任何事情。您可以在以下地方开始寻找黑客:
IOMemoryDescriptor由系统内存支持。不要担心IODeviceMemory术语:这些只是IOMemoryDescriptor对象; class is a lie。诱捕进入完全是另一回事。原则上,您可以使用对createMappingInTask()函数的“引用”标志查找特定MD的虚拟内存映射,然后使用一个NULL支持内存参数在返回的IOMemoryMap上调用NULL方法。不幸的是,这只会挂起任何试图访问映射的线程。当这种情况发生的时候你不会得到回音。osfmk/vm/目录中。也许有一种方法可以为VM区域设置自定义故障处理程序。不过,您可能不得不使用私有内核API。为什么?
最后,你为什么要这么做?退一步:你到底想用这个做什么?用这种方式模拟PCI设备似乎并不是最终的目的,所以这真的是实现最终目标的唯一途径吗?See: XY problem
https://stackoverflow.com/questions/47936346
复制相似问题