• 締切済み

LinuxのDMA転送でのメモリ操作について

Linux初心者です。 ユーザモードで動作しているプロセスからデバイスドライバに対してDMA転送要求を行った場合、ドライバでDMAバッファ用のメモリを確保すると思います。 ドライバはDMA転送用バッファとして、GFP_DMA指定でkmallocし、確保されるメモリ領域はZONE_DMAだと思います。 (PCIデバイスドライバの場合は、上記指定は必須ではないみたいですが。) ここで疑問なのですが、カーネルモードでしかアクセスできないZONE_DMA領域を、ユーザモードのプロセスがどのように扱うのでしょうか? ある本で「ユーザモードで動作中でもシステムコールに関してはCPU内でカーネルモードで動作する」というのを見たことがあるのですが、これによってZONE_DMA領域にアクセスできるようになるということでしょうか? ご存知の方がいたら、よろしくお願いします。 また、そもそも質問内容(前提)の間違えなどありましたらご指摘いただきたいです。

みんなの回答

  • noritsuu
  • ベストアンサー率100% (1/1)
回答No.2

kmallocで確保した領域はドライバからはアクセス可能です。 なので、ドライバインターフェースとして、以下の2点の関数を用意する。 ・ユーザにkmalloc領域内のデータを渡す関数 ・ユーザから受け渡されたデータをkmalloc領域内に格納する関数

  • u-kid
  • ベストアンサー率50% (34/67)
回答No.1

カーネル、デバイスドライバの中でもDMAは高度な話題になりますので、まずは一般的なデバイスドライバが、デバイスからand/orデバイスへのデータをどのようにバッファリングしているかを勉強された方がよいかと思います。 文字数などの制限で若干端折った説明になりますが、概ね次のようになります。 デバイスドライバはカーネル空間で動作していますので、バッファもカーネル空間内に置かれます。通常、I/OはCPUの処理速度に比べて、遅いことから、直接ユーザー空間のデータ領域にデータを入れることはせず、カーネル空間にバッファされます。(特に読み込み時)。その後、プロセスが要求するだけのデータが揃ったところで、カーネル空間のデータがユーザー空間にコピーされます。書き出し時もブロックデバイスのように一定のサイズ単位でないといけない物はカーネル空間でバッファリングされます(他にもいろいろな理由でバッファリングが行われます)。 特別な場合に直接ユーザー空間のデータをカーネル空間にマッピングしてI/O処理を行う場合がありますが、例外的な処理になります。 DMAの場合、ほとんどのデバイスが論理アドレスでの転送が出来ないため、直接ユーザー空間にデータを転送することは出来ません。従って、DMAの場合もいったんカーネル空間上のバッファにDMAで転送された後、ユーザー空間にコピーされることになります。 また、ユーザープロセスが直接デバイスに対してDMAで転送を要求することはありません。デバイスドライバが必要に応じてDMA転送を行います。 デバイスドライバを含むカーネルの役割、動作について理解されていないように見受けられますので、DMAの問題に取りかかる前に、基本的なことを勉強されることをお勧めします。

関連するQ&A