2016-03-28 22 views
7

mmapを使用して、カーネルモード空間をユーザモード空間にマッピングするLinuxの仕組みを理解しようとしています。メモリマップの構造カーネル空間

まずキャラクタデバイスにmmap機能を提供するロード可能カーネルモジュール(LKM)があります。その後、ユーザ空間アプリケーションがデバイスを開き、mmapを呼び出すと、LKMはカーネルモード空間(仮想ハイアドレス)内のLKMのヒープ上にメモリ空間を割り当てます。ユーザ空間側では、データポインタは仮想ローアドレスを指し示す。

次の図は、私がどのようにして記憶の解剖学を想像しているかを示しています。これは正しいですか?

Memory mapping

私はより多くの詳細を追加しようと、質問が明確でない場合は私に知らせてください。


編集:画像はGil Hamiltonに関して編集されました。黒い矢印は現在、物理アドレスを指しています。

+2

はい。それは基本的に正しいです。私は右に指している重い黒い矢でそれを描くだろう。つまり、同じ物理ページを共有しています。カーネルと同じ仮想アドレスを取得せず、何らかの形でカーネルデータ領域を「指す」こともありません。代わりに、それは同じ物理メモリページへのそれ自身の独立したマッピングを得る。 –

+0

多くの場合、Linuxのすべてのスレッドが1GBのカーネルと3GBのユーザースペースに分割された独自の仮想メモリ領域を取得することがあります。この場合:カーネルモジュールのいくつかの部分は、ユーザー空間アプリケーションのカーネル空間部分の中にありますか? – Alex44

+1

はい。そのモデルでは、カーネルの仮想アドレス空間はトップ1GB(x86 32ビットの場合)です。ユーザーモードのスペースは、最下部の3GBです。したがって、彼らは4GBの仮想アドレス空間を共有します。コンテキストスイッチがある場合、新しいページテーブルがインストールされます。上位1GBでは同じマッピングが行われますが、新しいプロセスのユーザーモードでは新しいマッピングがあります。しかし、ユーザモードはトップ1GBにアクセスすることはできません(つまり、メモリにアクセスしようとすると、ページテーブルのアクセス制限のために 'SIGSEGV 'を受信します)。カーネルモード*は技術的にユーザーモード空間に直接アクセスできますが、一般的にはAPI経由で行われます。 –

答えて

0

図面には、いくつかの重要な前提がありません。

カーネルは、ユーザ空間のメモリにアクセスするためにmmap()を必要としません。ユーザープロセスがメモリを持っている場合、それは既に定義によってアドレス空間にマップされています。その意味では、メモリはすでにユーザーとカーネルの間で共有されています。

mmap()は、ユーザーの仮想アドレス空間に新しい領域を作成します。そのため、後でアクセスされた場合に物理領域がアドレス領域に取り込まれる可能性があります。メモリの実際の割り当てとページテーブルエントリの変更は、カーネルによって行われます。

mmap()は、仮想アドレス空間のユーザー半分を管理するためにのみ意味があります。アドレス空間のカーネル半分は完全に異なった形で管理されます。

また、kernel-halfは、システム内のすべてのプロセスで共有されます。各プロセスには専用の仮想アドレス空間がありますが、カーネル半分のページテーブルエントリがすべてのプロセスでまったく同じになるようにページテーブルがプログラムされています。

また、カーネルはユーザ空間のメモリにアクセスするためにmmap()を使用しません。 mmap()は、むしろユーザの仮想アドレス空間における現在のマッピングを変更するためにカーネルによってユーザに提供されるサービスである。

ところで、実際にカーネルには、必要に応じてユーザーメモリにアクセスする方法がいくつかあります。

まず、カーネルは、存在する物理メモリの全体を連続してマッピングする(カーネル空間の一部として)カーネルアドレス空間の専用領域を持っています。 (これはすべての64ビットシステムに当てはまります.32ビットシステムではカーネルはこれを達成するためにオンザフライで '再マップ'しなければなりません)。

第2に、カーネルがシステムコールまたは例外ハードウェア割り込みではなく、有効なプロセスコンテキストを持っているので、カーネルはユーザースペースポインタを直接参照解除して正しい値を得ることができます。

第3に、カーネルが割り込みハンドラなどの借用されたコンテキストで実行中にプロセスのユーザスペースポインタを尊重したい場合、カーネルはvm_area_structツリーを通過してページテーブルを参照することによってプロセスの仮想アドレスをトレースできます。実際の物理ページフレームを見つける。

0

現在のvmaの "struct vm_area_struct"を繰り返してメモリ領域を確認できます。

ページテーブルを歩いて、ユーザスペースに関係しない仮想アドレスのマッピングされた物理アドレスを派生させると、メモリレイアウトがより明確になります。

別に、この図では、このマイナーな修正から、 BSSは、データセグメントに埋め込むされたセグメントが、部分ではない、詳しくはELF仕様を参照して、リンカスクリプト

関連する問題