wince6.0下物理地址映射,寄存器訪問介紹

wince6.0下,驅動都被放到內核空間下(用戶模式驅動除外)。用戶進程訪問物理地址受到了限制,即用戶進程再也不能通過vitrualalloc virtualcopy來完成物理地址的映射。所以用戶進程訪問物理地址控制外圍寄存器只能通過內核驅動來完成。大體的思路如下:[@more@]

wince6.0提供了兩個升級版的內存分配和映射函數,VirtualAllocExVirtualCopyEx,就是在原版的基礎之上增加了一個進程句柄函數,所以可以在內核驅動中先獲取調用者進程的句柄,再用上述的兩個Ex函數,爲該進程保留空間和映射物理地址。保留好的空間地址,在內核驅動中和用戶進程中都是有效的。(在驅動中有效是因爲用戶進程是該驅動的調用者進程)。完成映射之後,就可以在用戶進程中直接改變物理地址的值了。

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

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

SourcePhys = sDevPhysAddr & ~(PAGE_SIZE - 1);

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

lpUserAddr=VirtualAllocEx(hDesProcess, 0, SourceSize, MEM_RESERVE,PAGE_NOACCESS);其它的參數,除了進程句柄外與vitrualalloc virtualcopy都是相同的。對於VirtualCopyEx來說

用戶進程的句柄是目標進程句柄,驅動所在的進程句柄是源進程句柄。

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

lpUserAddr=(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資源。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章