カーネルがプロセス自体と同じ仮想アドレス空間にマップされている場合、なぜcopy_from_user()
と が必要なのでしょうか?copy_to_user()
学習目的でいくつかの(おもちゃの)カーネル モジュールを開発した後、すぐにそれに依存してcopy_from_user()
、copy_to_user()
ユーザー空間バッファーとの間でデータをコピーする必要があることに気付きました。そうしないと、無効なアドレスに関連するエラーによってクラッシュが発生します。
しかし、0x1fffff
仮想アドレスがユーザー空間バッファを指している場合、そのアドレスはカーネル内で有効ではないのはなぜでしょうか? カーネルは同じ仮想アドレス空間にあるため、0x1fffff
同じ物理メモリにマップされます。
答え1
アドレス空間マッピングは、一部のアーキテクチャ (すべてではありません!) で同じですが、同じアーキテクチャであっても、保護レベルは同じではありません。copy_from_user
などには、主に次の 3 つの目的があります。
- 読み取りまたは書き込みの対象となるメモリの権限が、ユーザー空間で実行されているプロセスに読み取りまたは書き込みを許可するかどうかをチェックします。これにより、プロセスがカーネルを騙して、プロセスがアクセスできないはずのメモリにアクセスさせることができなくなります。
- 保護違反によってカーネルがクラッシュしないように、特定のエラー処理が可能になります。たとえば、要求されたアドレスが現在マップされていない場合 (ゼロ ページやスワップ アウトされたページなど) などです。
- カーネルが自身の保護に引っかからないようにする。例えば スマップまたはカーネル固有のアドレス空間 (S/390)。
一部のアーキテクチャでは、これらの関数がショートカットを取れるメモリレイアウトが使用されています。例えば物理メモリの直接マッピングを使用しますが、それが当てはまるとは想定できず、いずれにしてもすべての状況に対処できるわけではありません (スワップアウトされたページは物理メモリに存在しません)。