2011-01-27 9 views
0

32ビットXPから64ビットWin7以降のさまざまなWindowsバージョンの特定のハードウェアI/Oアドレスへのインタフェース方法を検討しています。さまざまなバージョンのWindowsでさまざまなレベルの機能を公開したさまざまなソリューションがあるようですが、私自身のカーネルドライバを作成する可能性を理解しようとしています。最も基本的なカーネルI/O R/W機能は、READ_PORT_UCHARやWRITE_PORT_UCHAR(およびそれらのワードとロングの派生語)などの直接I/O操作のようです。私は理解していない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ポートは何ですか?一般的には、自分が所有していないポートでパーティーをするのは本当に悪い考えです。所有しているドライバ、O/S、またはBIOSを使ってポートへのアクセスを同期させる方法がないからです(SMI BIOSが自分が所有していると思うポートと通信を開始するようにしてください)。

提供されているコードスニペットも非常に悪い考えであり、焼く必要があります。基本的には、カーネルの仮想アドレスをデバイスレジスタ(MmMapIoSpace)にマッピングし、そのデバイスレジスタをユーザーモード(MmMapLockedPages)にマッピングする作業を行うだけです。

1)あなたは、メモリのキャッシュ属性を知らないことができますので、ランダムにMmNonCachedは、I/Oポートと同じシステム

2)を掛けることができる指定:それは2つの明白な問題があります。デバイスのレジスタに任意にアクセスするだけです。それらを所有しているドライバと正しく同期することはできません。したがって、最終的にシステムをボルケーピングすることになります。

-scott

+0

ありがとう、それは私が欲しかった情報でした。実際に私はハードウェアを所有しています - 実際のI/Oアドレスは列挙後に得られ、カードドライバは私のものです。私はユーザーモードからI/Oを行うための高速な方法を探していただけです。 –

+0

ああ。あなたがデバイスを所有している場合は、ドライバを作成して、ユーザーモードからIOCTLを送信することができます。 WindowsドライバキットのPortIoサンプルを参照してください – snoone

+0

ありがとうございます。私は見てみましょう。 –

関連する問題