簡體   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