[英]How to translate a virtual memory address to a physical address?
在我的C ++程序中(在Windows上),我正在分配一塊內存,並確保它在物理內存中保持鎖定(未連接和連續)(即使用VirtualAllocEx(),MapUserPhysicalPages()等)。
在我的過程中,我可以得到該塊的VIRTUAL內存地址, 但是我需要找出它的PHYSICAL內存地址,以便將它傳遞給某個外部設備。
1.在USER模式下,有什么方法可以將虛擬地址轉換為程序中的物理地址嗎?
2.如果沒有,我只能在KERNEL模式下找到這個虛擬到物理映射。 我想這意味着我必須寫一個驅動程序才能做到這一點......? 你知道我可以使用的任何現成的驅動程序/ DLL / API,我的應用程序(程序)將與之交互以進行翻譯嗎?
3.如果我必須自己編寫驅動程序,我該如何進行翻譯? 我使用哪些功能? 是mmGetPhysicalAddress()嗎? 我該如何使用它?
4.另外,如果我理解正確,mmGetPhysicalAddress()將返回調用進程上下文中的虛擬基址的物理地址。 但是如果調用進程是驅動程序,並且我正在使用我的應用程序來調用該函數的驅動程序,那么我正在改變上下文,當調用mmGetPhysicalAddress例程時,我不再處於應用程序的上下文中...所以如何翻譯應用程序(用戶模式)內存空間中的虛擬地址,而不是驅動程序?
任何答案,提示和代碼摘錄將不勝感激!
謝謝
在我的C ++程序中(在Windows上),我正在分配一塊內存,並確保它在物理內存中保持鎖定(未連接和連續)(即使用VirtualAllocEx(),MapUserPhysicalPages()等)。
不,你無法確保它保持鎖定狀態。 如果您的流程崩潰或提前退出怎么辦? 如果用戶殺了它怎么辦? 該內存將被重用於其他內容,如果您的設備仍在執行DMA,最終將導致數據丟失/損壞或錯誤檢查(BSOD)。
此外, MapUserPhysicalPages
是Windows AWE(Address Windowing Extensions)的一部分,用於在32位版本的Windows Server上處理超過4 GB的RAM。 我不認為它是用於破解用戶模式DMA。
1.在USER模式下,有什么方法可以將虛擬地址轉換為程序中的物理地址嗎?
有些驅動程序允許您執行此操作,但您無法在Windows上從用戶模式編程DMA,並且仍然具有穩定且安全的系統。 讓作為受限用戶帳戶運行的進程讀/寫物理內存允許該進程擁有系統。 如果這是一次性系統或原型,這可能是可以接受的,但如果您希望其他人(特別是付費客戶)使用您的軟件和您的設備,您應該編寫驅動程序。
2.如果沒有,我只能在KERNEL模式下找到這個虛擬到物理映射。 我想這意味着我必須寫一個驅動程序才能做到這一點......?
這是解決此問題的推薦方法。
你知道我可以使用的任何現成的驅動程序/ DLL / API,我的應用程序(程序)將與之交互以進行翻譯嗎?
您可以使用MDL(內存描述符列表)鎖定任意內存,包括用戶模式進程擁有的內存緩沖區,並將其虛擬地址轉換為物理地址。 您還可以讓Windows通過使用METHOD_IN_DIRECT
或METHOD_OUT_DIRECT
臨時為傳遞給DeviceIoControl
的調用緩沖區創建MDL。
請注意,虛擬地址空間中的連續頁面在物理地址空間中幾乎不會連續。 希望您的設備能夠處理這個問題。
3.如果我必須自己編寫驅動程序,我該如何進行翻譯? 我使用哪些功能? 是mmGetPhysicalAddress()嗎? 我該如何使用它?
編寫驅動程序要比調用一些API要多得多。 如果您要編寫驅動程序,我建議您從MSDN和OSR中盡可能多地閱讀相關資料。 另外,請查看Windows驅動程序工具包中的示例。
4.另外,如果我理解正確,mmGetPhysicalAddress()將返回調用進程上下文中的虛擬基址的物理地址。 但是如果調用進程是驅動程序,並且我正在使用我的應用程序來調用該函數的驅動程序,那么我正在改變上下文,當調用mmGetPhysicalAddress例程時,我不再處於應用程序的上下文中...所以如何翻譯應用程序(用戶模式)內存空間中的虛擬地址,而不是驅動程序?
驅動程序不是進程。 驅動程序可以在任何進程的上下文中運行,也可以在各種提升的上下文(中斷處理程序和DPC)中運行。
1)沒有
2)是的,你必須寫一個驅動程序。 Best可以是虛擬驅動程序,也可以更改特殊外部設備的驅動程序。
3)這在這里變得非常混亂。 MmGetPhysicalAddress
應該是您正在尋找的方法,但我真的不知道物理地址如何映射到bank / chip / etc. 在物理記憶上。
4)你不能使用分頁內存,因為它被重新定位。 您可以在MDL上使用MmProbeAndLockPages
鎖定分頁內存,您可以在從用戶模式調用上下文傳入的內存上構建。 但最好分配非分頁內存並將其交給用戶模式應用程序。
PVOID p = ExAllocatePoolWithTag( NonPagedPool, POOL_TAG );
PHYSICAL_ADDRESS realAddr = MmGetPhysicalAddress( p );
// use realAddr
您無法從用戶空間訪問頁表,它們將映射到內核中。
如果您在內核中,只需檢查CR3的值以找到基頁表地址,然后開始解析。
這個博客系列有一個如何做到這一點的精彩解釋。 您不需要任何OS工具/ API來解析虛擬< - >物理地址。
虛擬地址:f9a10054
1: kd> .formats 0xf9a10054 Binary: 11111001 10100001 00000000 01010100 Page Directory Pointer Index(PDPI) 11 Index into
第1個表(頁面目錄指針表)頁面目錄索引(PDI)
111001 101索引到第2個表(頁面目錄表)頁表索引(PTI)
00001 0000索引到第3表(頁面表)字節索引
0000 01010100 0x054,進入物理內存頁面的偏移量
在他的例子中,他們使用windbg,!dq是物理內存讀取。
您的應用程序中有一個虛擬緩沖區。 正如您所指出的那樣,該范圍的虛擬內存僅在您的應用程序的上下文中可用,並且其中一些可能隨時被分頁。 因此,為了從設備訪問內存(也就是說,執行DMA),您需要將其鎖定並獲取可以傳遞給設備的描述。
通過使用METHOD_IN_DIRECT或METHOD_OUT_DIRECT將IOCTL(通過DeviceControl函數)發送到驅動程序,可以獲得稱為MDL或內存描述符列表的緩沖區的描述。 有關定義IOCTL的討論,請參見以下頁面。
http://msdn.microsoft.com/en-us/library/ms795909.aspx
現在您已在設備的驅動程序中描述了緩沖區,您可以將其鎖定,以便緩沖區在設備可能對其執行的整個時間段內保留在內存中。 在MSDN上查找MmProbeAndLockPages。
您的設備可能會也可能無法讀取或寫入緩沖區中的所有內存。 該設備可能只支持32位DMA,機器可能有超過4GB的RAM。 或者您可能正在處理具有IOMMU,GART或其他地址轉換技術的計算機。 為了適應這種情況,請使用各種DMA API來獲取一組適合您的設備使用的邏輯地址。 在許多情況下,這些邏輯地址將等同於您提出的問題的物理地址,但並非總是如此。
您使用哪種DMA API取決於您的設備是否可以處理分散/收集列表等。 您的驅動程序在其設置代碼中將調用IoGetDmaAdapter並使用它返回的一些函數。
通常,您會對GetScatterGatherList和PutScatterGatherList感興趣。 您提供了一個函數(ExecutionRoutine),它實際上對您的硬件進行編程以進行傳輸。
涉及很多細節。 祝好運。
你真的不應該在usermode中做這樣的事情; 正如克里斯托弗所說的那樣,你需要鎖定頁面,以便在設備使用時mm不會決定將你的后備內存分頁,這最終會破壞隨機內存頁面。
但是如果調用進程是驅動程序,並且我正在使用我的應用程序來調用該函數的驅動程序,那么我正在更改上下文,當調用mmGetPhysicalAddress例程時,我不再處於應用程序的上下文中
驅動程序沒有像用戶模式應用程序那樣的上下文; 如果您通過IOCTL或其他東西調用驅動程序,通常(但不保證!)在調用用戶線程的上下文中。 但實際上,這對你所要求的並不重要,因為內核模式內存(任何高於0x80000000的內容)無論你身在何處都是相同的映射,你最終會在內核端分配內存。 但是,再次寫一個合適的驅動程序 。 使用WDF( http://www.microsoft.com/whdc/driver/wdf/default.mspx ),它將使編寫正確的驅動程序更容易(雖然仍然相當棘手,Windows驅動程序編寫並不容易)
編輯:只是想我會拋出一些書籍參考來幫助你,你絕對應該(即使你不追求寫作驅動程序)閱讀Russinovich和Solomon的Windows Internals( http://www.amazon.com / Microsoft-Windows-Internals-4th-Server / dp / 0735619174 / ref = pd_bbs_sr_2?ie = UTF8&s = books&qid = 1229284688&sr = 8-2 ); 編程Microsoft Windows驅動程序模型也很好( http://www.amazon.com/Programming-Microsoft-Windows-Driver-Second/dp/0735618038/ref=sr_1_1?ie=UTF8&s=books&qid=1229284726&sr=1-1 )
等等,還有更多。 對於在客戶的Vista 64位上運行的特權,您可以花費更多的時間和金錢讓您的內核模式驅動程序讓我的Microsoft退出,
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.