Windows system >> Windowsの知識 >  >> Linuxシステムチュートリアル >> Linuxチュートリアル >> 原則の概要Linuxのメモリ管理の詳細な知識

原則の概要Linuxのメモリ管理の詳細な知識

  
 物理アドレスマッピング、メモリ割り当て管理カーネル仮想アドレス(主に基づいて、スラブ):

Linuxのメモリ管理は、主に2つの部分に分割されます。図1に示すように、それぞれ、プロセッサとCPUアドレスバスに結合されたチップレベルのアドレス指定可能な記憶手段のための物理アドレス(物理アドレス)の概念、。 &Mdash;—この概念は、最高のこれらの概念によって理解されるであろう、物理アドレスを直接メモリから0としてそのメモリ自体フラナガン、理解されるべき機械に挿入することができるが、ことは言及する価値があります数値のバイト単位空大きなアレイの最大量まで、このアレイは、物理アドレスと呼ばれ、実際には、これは、メモリアドレッシングが当てはまらない、ハードウェア抽象化ソフトウェアにのみ使用可能です。したがって、それは'アドレスバス&'に対応する、単語を好ましいが、直接物理メモリアドレスと物理的対応に、アドレッシングモードの物理メモリの脇考慮も許容可能です。おそらく、形而上学的抽象化の間違った理解をより助長。 (ないマシン上と数に曲を挿入)、メモリ全体で仮想メモリ(仮想メモリ)は抽象的に記述しました。それは次のように&'直接理解されている、関係している物理メモリに対してであり; 0&回、例えば、メモリ;偽'直偽',&'ない0800万メモリアドレスは、上の物理アドレスに大きな配列のためではありません08000000&のndash;要素をアドレス1; 0&回理由は、メモリ管理のタイプを提供
ためモダンオペレーティング・システムの抽象化、すなわち仮想メモリ(仮想メモリ)です。プロセスは、仮想メモリアドレスを使用し、オペレーティングシステム
援助関連のハードウェア、それ'変換'実際の物理アドレスに変換します。 ''、変換が説明したすべての問題への鍵です。この抽象化を使用すると、使用できるプログラムは、アドレス空間の実際の物理アドレスよりもはるかに大きいです。 (東の壁の解体、嘆きの壁、また、このような銀行が行う)、あるいは複数のプロセスが同じアドレスを使用することができます。物理アドレスは、変換後も同じではないので、驚くべきことではありません。プログラムは、外観を逆コンパイルするために接続して、プログラムが関数Aを呼び出すために、例えば、アドレスが割り当てられているため、コネクタを見つけることができた後、コードは、コールAはありませんが、0回呼び出す; 0811111111を、つまり、関数Aアドレスは冷静されています。 'など、A&'せずに、仮想アドレスを変換するという概念は、これは単純に実行可能ではないではありません。一時停止、この問題は、それが勝負朱、何も言います。論理アドレス(論理アドレス)Intelは互換性のために、メモリ管理は保持古代を舞台になります。論理アドレスは、オペランドがアドレスまたは命令を指定し、機械語命令です。上記の例では、我々は、コネクタAは0回を割り当てられていることを言う; 08111111このアドレスは論理アドレスです。 &Mdash;—彼らはインテルのセグメント管理、論理アドレスの要件、&'に反しているかのように、たとえば、申し訳ありません、しかし、指定されたセグメントの相対アドレス内のオフセットセグメント識別子を追加することにより、論理アドレス、つまり、0倍の例では、08111111が、それは[コードセグメント識別子である:0x08111111]のように表される:[フラグメントオフセットセグメント識別子]として表さ、このように、完全&'の数、線形アドレス(リニアアドレス)、または、同様の論理アドレスと仮想アドレス(仮想アドレス)としても知られている論理アドレスが変換前の対応するハードウェアプラットフォーム管理セグメントアドレス、ハードウェアページに対応する線形アドレスである場合、それは、偽のアドレスであります前アドレスメモリを変換します。セグメントに、そのCPUと、(実際には、オフセットセグメントは、このことを理解しなければならない!)論理アドレスを与え、最初の物理アドレスへの仮想アドレスのCPUメモリ空間は、2つの工程を必要と次に、メモリ管理スレッドの論理アドレスへの最初のアドレスのための手段、およびそのページメモリ管理ユニットを使用することは、最終的な物理アドレスに変換されます。直接のリニアアドレスがプロセスに抽象できるためので、2つの変換を行って、確かに非常に面倒で不要です。この冗長性の理由は、Intelは互換性のためだけに完全です。図2に示すように、CPUのメモリ管理段階、論理アドレスは、2つの部分、セグメント識別子から成る線形アドレスに論理アドレスを変換する方法:セグメント内のオフセット。セグメント識別子は、セグメント・セレクタと呼ばれる16ビット長のフィールドです。前記最初の13ビットがインデックス番号です。 3は、いくつかの後のハードウェアの詳細が含まれています。最後の二つは、権限チェックを関連付け、このペーストが含まれていません。インデックス番号、または直接配列添字&mdashとして解釈;—それは常にそれのアレイに対応することは、それがインデックスにそれを詰める何ですか?このようなものは'記述子(セグメント記述)&'は、セクション'、ああ、セグメント記述子がために&'(特定のアドレスセグメントを説明し、取ったとして、単語の理解が、私はそれを考えます切頭&mdash複数に切断ナイフ、仮想メモリ、;—セグメント)。したがって、セグメントと呼ばれる記述、アレイの基、&'の数;'、このディスクリプタテーブルは、直接フロントセグメント識別子によってディスクリプタテーブル13内の特定の記述子を見つけることができます—記述子はもの&mdashの内側にあるかを確認するため、この記述は、セグメントを記述するために、私は抽象セクションを持っては正確ではないことは、それが記述されている方法を正確に、それがどのようにセグメントを理解することですどのようなもの、および以下に示すように、各セグメント記述子は、8バイトで構成されています。あなたはそれを定義するためのデータ構造を使用することができますが、ものは、非常に複雑ですが、私はここに同じ気に、記述ベースのフィールドであり、セグメントの開始位置の線形アドレス。グローバルディスクリプタテーブル(GDT)',いくつかのローカルを、それぞれなどは、自分自身を処理し、彼らはいわゆる&'置く; Intelは意図はいくつかのグローバルセグメント記述子が、それは置い&'ということであるように設計ローカルセクションディスクリプタ・テーブル(LDT)'の。それはまさにときにそれを使用する際にGDT、LDTを使用するには?これは、セグメント・セレクタフィールドT1で表される、= 0、GDTで表される、= 1がLDTで表されます。 GDTアドレスとサイズは、CPU GDTR制御レジスタ内のメモリに格納され、その後、LDTレジスタLDTR。このように同じ早口言葉などの概念がたくさん。これは、より直感的な図であると思われる:まず、完全な論理アドレス[セグメント・セレクタ:セグメントのオフセットアドレス所与、1、T1 = 0又は1のセグメント・セレクタを参照して、GDTに変換することが知られています次いで、対応するレジスタによれば、セグメント、またはLDTのセグメントは、そのアドレスとサイズを取得します。私たちは、の配列を持っています。ベース、すなわちベースアドレスを知っているように、図2に示すように、前部セグメント・セレクタのうち13がアレイであってもよく、対応するセグメント記述子が、発見されました。図3に示すように、ベース+オフセットは、線形アドレスを変換することです。ソフトウェアは懸念しているため簡単に言えば、必要なハードウェア情報は、原則として、変換を完了するためのハードウェアを作ることができ、準備ができて変換する必要があります。 OK、Linuxの実行方法を見てみましょう。図3は、インテルのLinuxの舞台監督は、それが対応しているもののので、2つの変換を必要としませんが、それは非常に冗長である、ああ、ない方法、それを行うために必要なハードウェア、ソフトウェアのみを行うことができ、同じ形式主義を取得。一方、他のいくつかのハードウェアプラットフォーム、二次変換の概念がない、Linuxはまた、統一されたインタフェースを提供するために、高レベルの抽象化を提供する必要があります。だから、Linuxのの舞台監督は、実際には単に'トリック'のみビットハードウェア。 —グローバルGDT、独自のプロセスのLDT&mdashでのIntelの意図によると、すべてのプロセスのが、Linux命令とデータのために対処するために、同じセグメントを使用します。すなわち、ユーザデータセグメント、ユーザコードセグメント、カーネルに対応するカーネル・コード・セグメントのカーネルデータセクション。我々は同じの年末の要約を書いてそうすることは驚くことではありません、それは常に、まあプロフォーマてきました。 /ASM-I386 /segment.hの#define GDT_ENTRY_DEFAULT_USER_CS 14の#define __USER_CS(GDT_ENTRY_DEFAULT_USER_CS * 8 + 3)の#define GDT_ENTRY_DEFAULT_USER_DS 15の#define __USER_DS(GDT_ENTRY_DEFAULT_USER_DS * 8 + 3)の#define GDT_ENTRY_KERNEL_BASE 12の#define GDT_ENTRY_KERNEL_CS(GDT_ENTRY_KERNEL_BASE + 0)#含みます__KERNEL_CS(GDT_ENTRY_KERNEL_CS * 8)の#define GDT_ENTRY_KERNEL_DS(GDT_ENTRY_KERNEL_BASE + 1)の#define __KERNEL_DS(GDT_ENTRY_KERNEL_DS * 8)の数値に前記マクロ置換を定義することであったます。#define __USER_CS 115 [00000000 1110 0 11]の#defineは00000000 [123 __USER_DS 1111 0 11]の#define __KERNEL_CS 96 [00000000 1100 0 00]の#define 104 [00000000 1101 0 00]リアブラケット2で表される4つの16ビット・セグメント・セレクタ・システム、それらのインデックスフィールド値T1である__KERNEL_DS、またこれは__USER_CS指数は14 = T1 = 0 __USER_DSインデックス= 15 T1 = 0 __KERNEL_CS指数= 12 T1 = 0 __KERNEL_DS計算することができます。インデックス= = 0 T1 13 T1は、次にGDTを使用し、0であり、そしてその後GDTの内容を見て、対応する項目12-15(アーチ/I386 /head.S)初期化される:.quad 0x00cf9a000000ffff /* 0回、60カーネル0時間で68のカーネル4GBのデータ; 00000000 * /.quad 0x00cf92000000ffff /* 0回、0回で4GBのコード* /.quad 0x00cffa000000ffff /* 0 00000000&回、0回で73ユーザ4GBのコード; 00000000 * /.quad 0x00cff2000000ffff /* 0x7Bとユーザ4ギガバイト0時間でのデータ; 00000000 * /先に記述テーブルに記述、それらは拡大し、ビット16-31に見出すことができるが、すべて0、すなわち4つのセグメント・ベース・アドレスは、全て0です。このように、セグメント内のオフセットアドレスが与えられると、上述した変換式、セグメント内のオフセット0 +によれば、線形アドレスに変換し、重要な結論は描かれ、&'することができ、Linuxでは、線形アドレスに論理アドレスは常に同じです(同じの一部)、すなわち、論理アドレスの線形アドレスオフセットフィールドの値は常に同じであると言うことではない、同じです。 ! ! ! &Rdquo;などの許可のチェック期間として、あまりにも多くの詳細を、無視します。ああ。 Linuxは、ほとんどの場合は、プロセスがLDT、ワインない限り、シミュレーション、のWindows
プログラム時間を使用していません。

Copyright © Windowsの知識 All Rights Reserved