簡體   English   中英

如何將虛擬內存地址轉換為物理地址?

[英]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_DIRECTMETHOD_OUT_DIRECT臨時為傳遞給DeviceIoControl的調用緩沖區創建MDL。

請注意,虛擬地址空間中的連續頁面在物理地址空間中幾乎不會連續。 希望您的設備能夠處理這個問題。

3.如果我必須自己編寫驅動程序,我該如何進行翻譯? 我使用哪些功能? 是mmGetPhysicalAddress()嗎? 我該如何使用它?

編寫驅動程序要比調用一些API要多得多。 如果您要編寫驅動程序,我建議您從MSDNOSR中盡可能多地閱讀相關資料。 另外,請查看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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM