2016-08-26 4 views
4

以下は私の簡単なドライバコードの抜粋です。copy_to_userの代わりにユーザー空間アドレスへのアクセスが直接できますか?

int vprobe_ioctl(struct file *filep, unsigned int cmd, void *UserInp) 
{ 
    case IOCTL_GET_MAX_PORTS: 

     *(int*)UserInp = TotalPorts; 

    #if ENABLED_DEBUG 
     printk("Available port :%u \n ", TotalPorts); 
    #endif 
     break; 
} 

私は、ユーザ空間のメモリに書き込み中に使用されるべき機能copy_to_userについて認識していませんでした。コードはユーザーのアドレスに直接アクセスします。しかし、私は開発システム(x86_64アーキテクチャ)でカーネルクラッシュを起こしていません。それは期待どおりに動作します。

しかし、他のx86_64マシンに.koファイルを挿入するとカーネルがクラッシュすることがあります。だから、私はcopy_to_userと直接アクセスを置き換え、それは動作します。

誰でも説明してください。

i)ユーザーアドレスの直接アクセスはどのように機能しますか。

ii)一部のシステムではカーネルクラッシュが発生するのはなぜですか?他のシステムではうまく機能します。カーネルがユーザープロセスの仮想アドレスに直接アクセスする可能性があるため、システム間にカーネル構成の不一致がありますか?

注:私が使用しているシステムはすべて、同じOSとカーネルを持っています。キックスタートを通じて同じイメージが生成されました。 - 相違の可能性はありません。

ありがとうございます。

+1

ほとんど[重複](http://stackoverflow.com/questions/12666493/why-do-you-have-to-use-copy-to-user-copy-from-user-to-access-user -space-from)。単一のintの場合にはより良いかもしれない 'put_user()'もあります。 –

+0

@RomanKhimovあなたが言った質問から、私は 'copy_to_user'がそのアドレスがユーザ空間に属するかどうかをチェックすることを理解します。私の疑いは、直接アクセスがどのように働くかです。また、なぜ一部のシステムでは直接アクセスが機能し、同じOSとカーネルを持つ他のシステムでは動作しません。 – Karthik

答えて

1

クラッシュを見るのは興味深いでしょう。今私が言っているのは、記憶の仕組みに関する私の知識に基づく仮定です。 ユーザ空間のメモリは仮想です。特定のプロセスアドレスXがある物理メモリに配置されていることを意味します。この物理メモリは、現在プロセスに割り当てられているメモリページです。ユーザーにコピーすると、最初に与えられたメモリが実際にプロセスやその他のセキュリティチェックに属しているかどうかがチェックされます。それにはマッピングの問題があります。

カーネルメモリには、仮想アドレスを物理アドレスにマップする必要がある独自のアドレス空間があります。カーネルはmmuの助けを借りています(これはアーキテクチャごとに異なります)。 x86では、カーネル仮想とユーザー仮想間のマッピングは1:1です(ここでは別の問題があります)。他のシステムでは、これは常に真実ではありません。

+0

// x86では、カーネル仮想とユーザ仮想の間のマッピングは1:1 //だから、カーネル仮想アドレスとユーザ仮想は同じであると言っているので、ユーザ仮想をカーネルで直接使うことができます。私は正しい?しかし、使用しているシステムはすべて、同じOSイメージを持つx86システムです。 – Karthik

関連する問題