2011-01-27 13 views
0

我正在尋找從32位XP到64位Win7及更高版本的各種Windows版本的特定硬件I/O地址的接口方式。在不同的Windows版本下,似乎有不同程度的功能發佈了各種解決方案,我試圖瞭解創建自己的內核驅動程序的可能性。最基本的內核I/O R/W功能似乎是直接I/O操作,如READ_PORT_UCHAR和WRITE_PORT_UCHAR(及其字和長導數)。我也看到the technique below,我不明白,似乎是一些內存映射能力,我沒有經驗,可以找到很少的可讀文檔。有人可以對READ_PORT_UCHAR/WRITE_PORT_UCHAR與我在下面重現的這種映射技術的適用性/兼容性發表評論嗎?尋找內核驅動程序I/O接口功能的解釋

在此先感謝。

case IOCTL_PHYMEM_MAP: 

      if (dwInBufLen==sizeof(PHYMEM_MEM) && dwOutBufLen==sizeof(PVOID)) 
      { 
       PHYSICAL_ADDRESS phyAddr; 
       PVOID pvk, pvu; 

       phyAddr.QuadPart=(ULONGLONG)pMem->pvAddr; 

       //get mapped kernel address 
       pvk=MmMapIoSpace(phyAddr, pMem->dwSize, MmNonCached); 

       if (pvk) 
       { 
        //allocate mdl for the mapped kernel address 
        PMDL pMdl=IoAllocateMdl(pvk, pMem->dwSize, FALSE, FALSE, NULL); 
        if (pMdl) 
        { 
         PMAPINFO pMapInfo; 

         //build mdl and map to user space 
         MmBuildMdlForNonPagedPool(pMdl); 
         pvu=MmMapLockedPages(pMdl, UserMode); 

         //insert mapped infomation to list 
         pMapInfo=(PMAPINFO)ExAllocatePool(\ 
          NonPagedPool, sizeof(MAPINFO)); 
         pMapInfo->pMdl=pMdl; 
         pMapInfo->pvk=pvk; 
         pMapInfo->pvu=pvu; 
         pMapInfo->memSize=pMem->dwSize; 
         PushEntryList(&lstMapInfo, &pMapInfo->link); 

         DebugPrint("Map physical 0x%x to virtual 0x%x, size %u", \ 
          pMem->pvAddr, pvu, pMem->dwSize); 

         RtlCopyMemory(pSysBuf, &pvu, sizeof(PVOID)); 

         irp->IoStatus.Information=sizeof(PVOID); 
        } 
        else 
        { 
         //allocate mdl error, unmap the mapped physical memory 
         MmUnmapIoSpace(pvk, pMem->dwSize); 

         irp->IoStatus.Status=STATUS_INSUFFICIENT_RESOURCES; 
        } 
       } 
       else 
        irp->IoStatus.Status=STATUS_INSUFFICIENT_RESOURCES; 
      } 
      else 
       irp->IoStatus.Status=STATUS_INVALID_PARAMETER; 

      break; 

回答

2

什麼是你要訪問這些I/O端口?一般來說,這是一個非常不好的想法,因爲您無法使用擁有它們的驅動程序,操作系統或BIOS來同步對這些端口的訪問,因此您無法擁有不屬於您的端口的聚會(可以採用SMI並讓BIOS開始與它認爲擁有的端口進行通話)。

提供的代碼片段也是一個非常糟糕的主意,應該被燒燬。基本上,它所做的只是將內核虛擬地址映射到設備寄存器(MmMapIoSpace),然後完成工作,然後將該設備寄存器映射到用戶模式(MmMapLockedPages)。有兩個明顯的問題是:

1)你不知道內存的緩存屬性,所以隨機指定MmNonCached會使系統掛起

2)同與I/O端口,可以只是任意訪問設備的寄存器。你無法正確地將自己與擁有它們的驅動程序同步,所以你註定要最終停止你的系統。

斯科特

+0

謝謝,這是某種信息,我想要的。實際上,我擁有硬件 - 還有其他方法,枚舉後得到實際的I/O地址,並且卡驅動程序是我的。我只是在尋找從用戶模式進行I/O的快速方法。 – 2011-01-27 21:50:14