wince6.0下的實體地址對映和共享

honwsn發表於2010-02-28
wince6.0下,驅動都被放到核心空間下(使用者模式驅動除外)。訪問實體地址受到了限制,即使用者程式再也不能透過來完成實體地址的對映。所以使用者程式訪問實體地址控制外圍暫存器只能透過核心驅動來完成。大體的思路如下:[@more@]

wince6.0提供了兩個升級版的記憶體分配和對映函式,VirtualAllocEx,就是在原版的基礎之上增加了一個程式控制程式碼函式,所以可以在核心驅動中先獲取呼叫者程式的控制程式碼,再用上述的兩個Ex函式,為該程式保留空間和對映實體地址。在驅動中有效是因為使用者程式是該驅動的呼叫者程式)。完成對映之後,就可以在使用者程式中直接改變實體地址的值了。

下面介紹下這個兩個函式的使用。

被對映的實體地址應該向上取整,保證為頁面的起始處。所以被對映的大小也要做相應的增加。sDevPhysAddr是被對映的起始實體地址。dwSize是對映的大小。

SourcePhys = & ~(PAGE_SIZE - 1);

SourceSize = dwSize + (sDevPhysAddr & (PAGE_SIZE - 1));

lpUserAddr=(hDesProcess, 0, SourceSize, MEM_RESERVE,PAGE_NOACCESS);其它的引數,除了程式控制程式碼外與vitrualalloc virtualcopy都是相同的。對於VirtualCopyEx來說

使用者程式的控制程式碼是目標程式控制程式碼,驅動所在的程式控制程式碼是源程式控制程式碼。

由於實體地址向上取整,所以對映完成後的虛擬地址應該做出調整:

=(LPVOID)((ULONG)lpUserAddr+(sDevPhysAddr & (PAGE_SIZE - 1)));

gUserAddr = lpUserAddr;

返回真正所需的地址。

當使用完後,釋放資源如下:

VirtualFreeEx(pvProcess,(PVOID)((ULONG)gUserAddr&~(ULONG)(PAGE_SIZE-1)),0,MEM_RELEASE);

完成上述內容,首先是做個簡單的流模式的核心驅動(見資源中心的FirstSubDll.rar),筆者在應用程式,使用者模式驅動,核心驅動三個環境下VirtualAllocExVitualCopyEx對映實體地址做過測試。只有核心驅動能完成,其他的都是不支援的請求。Wince6.0限制的應用程式對實體地址的訪問,提高系統的安全性,只有核心驅動(被系統信賴的)才能訪問實體地址及外圍裝置暫存器。在驅動中給出IOCTL介面,透過DeviceIoControl完成實體地址對映和資源釋放。應用載入驅動呼叫介面,獲取完成對映的虛擬地址,直接讀寫,可以改變RAM值或某個外圍裝置暫存器的值(如透過GPIO控制某個裝置的電源開關)。

前面提到過的保留好的空間地址,在核心驅動中和使用者程式中都是有效的。透過此點可以讓核心驅動和應用程式共享一段物理RAM。核心程式和使用者程式記憶體共享與複製核心驅動中的資料塊到使用者已分配的儲存空間中相比,可以節省記憶體資源和提高效率。特別是在攝影裝置中,需要大量的儲存,若不再應用和驅動中共享記憶體,就會損失大量的RAM資源。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23410886/viewspace-1031512/,如需轉載,請註明出處,否則將追究法律責任。

相關文章