Linux のメモリ管理とアドレス指定の詳細な紹介

Linux のメモリ管理とアドレス指定の詳細な紹介

1. コンセプト

メモリ管理モード

セグメント型: メモリは複数のセグメントに分割され、各セグメントは連続したメモリであり、異なるセグメントは異なる用途に対応します。各セグメントのサイズが均一ではないため、メモリの断片化やメモリスワップの非効率などの問題が発生します。

ページ化: メモリは管理のために複数のメモリ ページに分割されます。たとえば、Linux システムでは、各ページのサイズは4KBです。ページングにより、小さなメモリ断片は発生しません。しかし、メモリの断片化の問題は依然として残っています。

段落ページ形式: 段落形式とページ形式の組み合わせ。

住所種別分類

論理アドレス: プログラムが使用するアドレス、通常はセグメントメモリ管理によってマップされていないアドレスを論理アドレスと呼びます。

リニアアドレス: セグメント化されたメモリ管理によってマップされるアドレスは、リニアアドレス、または仮想アドレスと呼ばれます。

仮想アドレス: セグメント化されたメモリ管理によってマップされたアドレスは、線形アドレス、または仮想アドレスと呼ばれます。

物理アドレス: 物理メモリアドレス

例:

Inetel プロセッサでは、論理アドレスは「セグメント メモリ管理」変換前のアドレスであり、リニア アドレスは「ページ メモリ管理」変換前のアドレスです。

セグメント化されたメモリ管理によってマップされるアドレスはもはや「物理アドレス」ではなく、Intel では「リニア アドレス」(仮想アドレスとも呼ばれる) と呼ばれています。したがって、セグメント化メモリ管理では、まず論理アドレスをリニア アドレスにマッピングし、次にページ化メモリ管理ではリニア アドレスを物理アドレスにマッピングします。

Linux のメモリは主にページ メモリによって管理されますが、セグメント メカニズムも使用されます。 Linux カーネルが現在採用しているアプローチは、セグメント マッピング プロセスを事実上無効にすることです。

Intel の最も初期のプロセッサである 80286 は完全にセグメントベースでしたが、80386 にはセグメントとページの両方の管理機能がありました。

2. ページ管理

x86 アーキテクチャ 32 ビット CPU

セカンダリ ページ テーブル アドレス指定方法では、メモリ ページのサイズは 4 KB、第 1 レベルのページ ディレクトリ テーブルには 1024 個のエントリがあり、第 2 レベルのページ テーブルには 1024 個のエントリがあり、ページ テーブル エントリは 4 バイトです。第 1 レベルのページ ディレクトリ テーブル エントリがすべて割り当てられ、必要に応じて第 2 レベルのページ テーブルが作成されます。 (局所性原理)。

仮想アドレス 32 ビット

10+10+12 は、それぞれレベル 1 ページ テーブル番号、レベル 2 ページ テーブル エントリをインデックスし、物理ベース アドレスのオフセット アドレスを記録します。 PAE メカニズムを使用した後、32 ビット システムでサポートされる最大メモリは 64 GB (アドレスは 32+4=36 ビット) になります。

線形アドレス指定物理アドレスステップ

まず、10 ビットのアドレス指定レベル 1 ページ テーブル番号を使用します。レベル 1 ページ テーブル番号には、レベル 2 ページ テーブルのアドレスが記録されます。

レベル 2 ページ テーブルのアドレスを見つけた後、仮想アドレスの残りの 10 ビットに基づいて、レベル 2 ページ テーブル内のエントリの場所が見つかります。

レベル 2 ページ テーブルのエントリが見つかると、エントリには物理アドレスにマッピングされる仮想アドレスの開始アドレスが記録されます。エントリのサイズは 4 バイト (32 ビット) です。

最終的な物理アドレスは、見つかった物理アドレスの開始アドレスと、仮想アドレスの最後の12ビットをオフセットとして組み合わせて計算されます。

x86 アーキテクチャ 64 ビット CPU

ページテーブルにはさらにレベルがある

グローバル ページ ディレクトリ PGD (ページ グローバル ディレクトリ) 上位ページ ディレクトリ PUD (ページ上位ディレクトリ) 中間ページ ディレクトリ PMD (ページ中間ディレクトリ) ページ テーブル エントリ PTE (ページ テーブル エントリ)

線形アドレス指定物理アドレスステップ

リニアアドレスは48ビット、最大物理アドレスは52ビット、実際の物理メモリアドレスバス幅は40ビットで、1TBの物理メモリをサポートします。x86_64には4レベルのページテーブルがあり、原理はx86システムと同じで、レイヤーごとにアドレス指定されます。CR3レジスタには最上位テーブルの開始物理アドレスが格納されているため、アドレス指定の最初のステップはCR3レジスタの値を取得することです。各PTEエントリのサイズは8バイト、つまり64ビットです。

TLB

CPU チップには、プログラムによって最も頻繁にアクセスされるページ テーブル エントリを格納するためのキャッシュが追加されています。このキャッシュは TL (Translation Lookaside Buffer) です。通常、ページ テーブル キャッシュ、リダイレクト バイパス キャッシュ、高速テーブルなどと呼ばれます。次に、CPU のメモリ管理ユニット MMU がアドレスを検索すると、最初に TLB をチェックします。見つからない場合は、通常のページ テーブルのチェックを続けます。

固有名詞

PDT: ページ ディレクトリ テーブル、マルチレベル ページ テーブル、第 1 レベル ページ テーブル、32 ビット システムには 1024 個のページ ディレクトリがあります
PTT: ページ テーブル エントリ、マルチレベル ページ テーブル、セカンダリ ページ テーブル、32 ビット システムでは各ページ ディレクトリの下に 1024 のページ テーブル エントリがあり、各エントリは 4 バイトです。
PDE: ページテーブルのベースアドレス。PDT内の項目です。
PTE: ページのベースアドレス、PTTの1つ
GDT: グローバル記述子テーブル。論理アドレスを線形アドレスに変換するために使用されます。
LDT: ローカル記述子テーブル。論理アドレスを線形アドレスに変換するために使用されます。

3. 住所区分

32 システムカーネル 1G: 0xC0 00 00 01 - 0xFF FF FF FF
ユーザー 3G: 0x00 00 00 00 - 0xC0 00 00 00
0xC0 00 00 00 == 3G

64 ビット システム:
カーネル 128T: 0xFF FF 80 00 00 00 00 00 - 0xFF FF FF FF FF FF FF FF (高)
0xFF FF 7F FF FF FF FF FF - 0xFF FF FF FF FF FF FF FF (自分で計算してください)

ユーザー 128T: 0x00 00 00 00 00 00 00 00 - 0x00 00 7F FF FF FF FF FF (下位)
0x00 00 80 00 00 00 00 00 00 - 0x00 00 80 00 00 00 00 00 (自分で計算してください)

0x00 00 7F FF FF FF FF FF == 127T
質問: 64 ビット システムの境界線は 128T ですか? 127T ですか?

アクセス権

プロセスがユーザー モードにある場合、ユーザー空間メモリにのみアクセスできます。カーネル モードに入った後にのみ、カーネル空間メモリにアクセスできます。

PAE メカニズム

CPU ビット幅とは、CPU が 1 クロック サイクル内で処理できるバイナリ ビットの数を指します。通常のシナリオでは、32 ビット システム CPU のアドレス バスは 32 ビットです。ただし、PAE メカニズムの導入後は、16 ビット CPU のアドレス バス ビット幅は 20 ビット (物理メモリ 1M)、32 ビット CPU のアドレス バスは 36 ビット (物理メモリ 64GB)、64 ビット CPU のアドレス バス ビット幅は 40 ビット (物理メモリ 1TB) になります。したがって、32 ビット システムは最大 4 GB のメモリ スティックのみをサポートすると単純に言うことはできません。

4. デバッグ

プログラム登録

cs: コードセグメントレジスタ
ds: データセグメントレジスタ
ss: スタックセグメントレジスタ
es: 拡張セグメントレジスタ
fs: 32ビット後のフラグセグメントレジスタ
gs: 32ビット後のグローバルセグメントレジスタ

カーネルクラッシュログの例:

RIP: 0010:[ ] [ ] xxxxxxxxxx+0x69/0x70
RSP: 0018:ffff886241737d98 EFLAGS: 00010246
RAX: ffff880034814d40 RBX: ffff881fc6248740 RCX: 00000000000000200
RDX: 0000000000000000 RSI: 0000000000000286 RDI: ffff881fc6381858
RBP: ffff886241737d98 R08: ffff886241734000 R09: 0000000000000000
R10: ffff880034814d40 R11: 00000000000000200 R12: ffff881fc62487a0
R13: 00000000000000000 R14: 00007fff86cb6260 R15: ffff881fc6381858
FS: 00007f78b59b8720(0000) GS:ffff885ffe3c0000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f690a057180 CR3: 0000006208985000 CR4: 00000000003627e0
DR0: 00000000000000000 DR1: 0000000000000000 DR2: 00000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 00000000000000400

プログラムレジスターの表示

GDB を使用して Linux 32 ビット上の ELF32 実行可能ファイルをデバッグし、info r コマンドを使用してレジスタの状態を確認します。

セグメント レジスタには 0x23 と 0x2b の 2 つのケースがあります。

16進数: 0023
バイナリ: 0000000000100 0 11 - セグメント番号: 4 - テーブルタイプ: GDT - 特権レベル: Ring3
16進数: 002B
バイナリ: 0000000000101 0 11 - セグメント番号: 5 - テーブルタイプ: GDT - 特権レベル: Ring3

セグメント番号: 4ビット目から始まる テーブルタイプ: 3ビット目 特権レベル: 1ビット目と2ビット目

Linux で GDT を直接表示するコマンドやツールが見つからなかったので、ソース コードを調べて答えを見つけました。

これら 2 つの項目によって記述されるセグメントは Windows と同じで、ベース アドレスは 0、サイズは 4 GB です。

Windows と Linux はどちらも、この方法で CPU のセグメント化されたメモリ管理メカニズムをバイパスすることを選択します。

ただし、これは両方のオペレーティング システムに当てはまるものの、セグメント メカニズムが完全に使用されていないことを意味するわけではないことに注意してください。CPU のタスク管理 TSS は引き続き使用する必要があります。誰もがこれを知っておく必要があります。セグメンテーション メカニズムは Linux 64 ビット システムでは歓迎されませんが、オペレーティング システムは引き続き、最初にセグメンテーションを行ってからページングを行うというアドレス指定方法を維持します。

結論

Linux のメモリ管理とアドレス指定に関するこの記事はこれで終わりです。Linux のメモリ管理とアドレス指定の詳細については、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Linuxカーネルのメモリ管理アーキテクチャの詳細な説明
  • Linux のメモリ管理メカニズムの詳細な分析
  • Linux 管理者ガイド (4) -- メモリ管理

<<:  ドラッグ効果を実現するための純粋なCSSコード

>>:  HTML+CSSプロジェクト開発経験概要(推奨)

ブログ    

推薦する

Docker nginx + https サブドメイン設定の詳細なチュートリアル

今日はたまたま友人のサーバーの移転を手伝うことになり、サーバーの基本的な設備の設定を行ったのですが、...

MySQL: MySQL 関数

1. 組み込み関数1. 数学関数ランド()丸め(数値) ceil(数値)階数(数値)ランダム丸め切り...

Vueアイコンセレクターのサンプルコード

出典: http://www.ruoyi.vip/ 'vue' から Vue をイン...

CSS変数var()の使い方を理解する必要があります

Web プロジェクトがどんどん大きくなると、CSS は天文学的な大きさと複雑さを増します。この問題を...

Linux ファイルを分割するための split コマンドの詳細な説明

いくつかの簡単な Linux コマンドを使用すると、ストレージまたは電子メールの添付ファイルのサイズ...

Baidu 入力メソッドが API を公開、自由に移植して使用できると主張

百度入力方式の担当者は、百度入力方式のオープンAPIの最大の利点は操作が便利であることであり、プラッ...

CentOS7にPostgreSQL11をインストールする方法

CentOS 7にPostgreSQL 11をインストールする PostgreSQL: 世界で最も先...

HTML ページ ソース コード レイアウトの概要_Powernode Java Academy

HTML ページ ソース コード レイアウトの概要この紹介では、Google のホームページのソー...

LinuxサーバーにGRUBをインストールする手順

Linux サーバーに GRUB をインストールする方法クラウド移行ツールを使用して、CentOS ...

js の通常形式の日付と時刻に 0 を自動的に追加する 2 つのソリューション

目次背景解決策1アイデア:コード:解決策2アイデア:要約する参照する背景日付と時間をフォーマットする...

同じ IP のアクセス頻度を制限するように nginx を設定する方法

1. nginx.conf の http{} に次のコードを追加します。 limit_conn_zo...

HTMLウェブページのMETAタグのコンテンツを書く際のポイント

META タグは、HTML 言語のヘッダー領域にある補助タグです。作成者、日時、Web ページの説明...

Vue+EChartsは、中国の地図の描画と省の自動回転と強調表示を実現します。

目次成果を達成する完全なコード + 詳細なコメントまとめ成果を達成する完全なコード + 詳細なコメン...

MySql テーブル内の行を削除する実用的な方法

まず、どのフィールドまたはフィールドの組み合わせがデータ行を一意に識別できるかを決定する必要がありま...