大きな宿題にぶつかりました、こんにちは人生

 

コンピューターシステム

大仕事

タイトルプログラミングライフ~Hello's P2P~   

プロフェッショナルコンピューティング学部                

学生番号    120L021215          

クラス   2003010              

学生ミン・ボユ                  

講師鄭貴斌                   

コンピュータ科学技術学部

2021年5月

まとめ

この記事では、hello P2P プロセスと O2O プロセス、および再配置、仮想アドレス、マルチレベル キャッシュ、マルチレベル ページ テーブルなどのさまざまな付随メカニズムを簡単に紹介します。この課題を書くことで、コンピュータ システムについてより深く理解できるようになりました

キーワード:アセンブリ、リンク、ストレージ管理。。                           

目次

第 1 章 概要................................................................................................ ................................................................. ................................... - 4 -

1.1 Hello の概要 ................................................................................... ................................................................... ……………… - 4 -

1.2 環境とツール................................................................................ ................................................................... ................................................... - 4 -

1.3 中間結果................................................................................ ................................................................. ................................................... - 4 -

1.4 この章の概要.................................................................. ................................................................... ................................................... - 4 -

第 2 章 前処理................................................................................................................ ................................................................... ……………… - 5 -

2.1 前処理の概念と機能 .................................................................... ................................................... - 5 -

2.2 Ubuntu でのコマンドの前処理................................................................................................ ................................... - 5 -

2.3 Hello 前処理結果の分析 ................................................................................... ................................................... - 5 -

2.4 この章の概要.................................................................. ................................................................... ................................................... - 5 -

第 3 章 編集................................................................................ ................................................................. ................................... - 6 -

3.1 コンパイルの概念と機能 .................................................................... ...................................................-6 -

3.2 Ubuntu でコンパイルするコマンド.................................................................................................... ...................................................-6-

3.3 Hello コンパイル結果の分析 ................................................................................... ................................... - 6 -

3.4 この章の概要.................................................................. ................................................................... ................................................... - 6 -

第 4 章 編集................................................................................................ ................................................................. ................................... - 7 -

4.1 アセンブリの概念と機能................................................................................................ ...................................................-7 -

4.2 Ubuntu でアセンブルするコマンド ................................................................................................... ...........................................-7-

4.3 再配置可能なターゲット elf フォーマット................................................................................ ................................................... - 7 -

4.4 Hello.o の結果分析 ................................................................................... ........................................... - 7 -

4.5 この章の概要................................................................... ................................................................... ................................................... - 7 -

第 5 章 リンク................................................................................................ ................................................................... ................................... - 8 -

5.1 リンクの概念と機能 .................................................................... ................................................... - 8 -

5.2 Ubuntu でのコマンドのリンク................................................................................................ ................................... - 8 -

5.3 実行可能オブジェクトファイルの形式 hello ................................................................................................... ................................... - 8 -

5.4 Hello の仮想アドレス空間 ................................................................................... ................................................ - 8 -

5.5 リンク再配置プロセスの分析.................................................................................. ................................................... - 8 -

5.6 hello 実行処理 ................................................................... ................................................... - 8 -

5.7 Hello ダイナミックリンク分析................................................................ ................................................... - 8 -

5.8 この章の概要................................................................... ................................................................... ...................................................... - 9 -

第 6 章 hello プロセス管理................................................................................................ ................................................... - 10 -

6.1 プロセスの概念と役割................................................................................... ................................................... - 10 -

6.2 Shell-bash の機能と処理手順を簡単に説明します ................................................... .. - 10 -

6.3 Hello のフォークプロセスの作成プロセス ................................................................................................... ................................... - 10 -

6.4 Hello の execve プロセス................................................................................ ................................................... - 10 -

6.5 Hello プロセスの実行 ................................................................................. ................................................ - 10 -

6.6 Hello の例外と信号処理 ................................................................................................... ................................... - 10 -

6.7 この章の概要.................................................................. ................................................................... ................................................... - 10 -

第 7 章 こんにちはストレージ管理................................................................................................ ................................... - 11 -

7.1 Hello のメモリ アドレス空間 ................................................................................... ................................... - 11 -

7.2 Intel 論理アドレスからリニア アドレスへの変換セグメント管理................................................................................ . - 11 -

7.3 Hello のリニアアドレスから物理アドレスへの変換 - ページ管理 ................................................... - 11 -

7.4 TLB および 4 レベルのページ テーブルによってサポートされる VA から PA への変換 ................................................................... …… - 11 -

7.5 3 レベル キャッシュによってサポートされる物理メモリ アクセス................................................................................ ................................ - 11 -

7.6 hello プロセスがフォークするときのメモリ マッピング................................................................................................ ................................ - 11 -

7.7 hello プロセス実行時のメモリマッピング................................................................................................................ ................................... - 11 -

7.8 ページフォルトおよびページフォルト割り込み処理................................................................................................ ................................... - 11 -

7.9 動的ストレージ割り当て管理.................................................................. ................................................................... .. - 11 -

7.10 この章の概要.................................................................. ................................................................... ................................................... - 12 -

第 8 章 hello IO 管理.................................................................................................. ................................................... - 13 -

8.1 Linux IO デバイス管理方法 ................................................................................... ................................... - 13 -

8.2 Unix IO インターフェースとその機能の簡単な説明................................................................ ................................... - 13 -

8.3 printf の実装分析................................................................................ ................................................................... .. - 13 -

8.4 getchar の実装分析................................................................................ ................................................................... .. - 13 -

8.5 この章の概要.................................................................. ................................................................... ................................................... - 13 -

結論は................................................ ................................................................. ................................................... - 14 -

付録................................................. ................................................................... ................................................................... - 15 -

参考資料................................................................................ . ................................................................... ................................................... - 16 -

第1章概要

1.1 Hello の概要

Hello の告白に基づいて、コンピュータ システムの用語を使用して、Hello の P2P、020 のプロセス全体を簡単に説明します。

 まず、ドキュメントエディタで高級言語(C言語)でhello.cを書き、gccでコンパイルし、hello.i、hello.s、hello.oの段階を経て、最終的にリロケータブルになります。 hello.o の実行可能プログラムを作成し、静的または動的ライブラリを ld でリンクして、最終的に完全なプログラムを形成します。プログラムが開かれると、bash シェルは最初に子プロセスをフォークし、次に execve() 関数を使用して子プロセスにプログラムを実行させ、プロセスを形成します。上記はP2Pです。

プロセスになるには、プログラムを仮想アドレス空間にロードし、コード セグメントのコードの実行を開始する必要があります。このとき、CPUは実行ファイルhelloにタイムスライスを割り当て、論理制御フローを実行し、命令フェッチ、デコード、実行、メモリ操作、ライトバックなどの動作を順次実行します。さらに、実行プロセス中に、ストレージ管理と MMU は、L1、L2、L3 の 3 レベル キャッシュとマルチレベル ページ テーブルを通じてディスクまたはメモリから必要なデータを取得し、コード命令に従って出力します。 I/O システム。プログラムが終了すると、bash は sigchld ハンドラーを呼び出して、子プロセスをリサイクルし、メモリを解放し、実行中のプログラムに関連するデータ構造を削除します。最初から、最終的にリサイクルされるまでは、Hello の O2O です。

ソフトウェア: virtualbox、vim テキスト エディタ、bashshell、edb

1.3 中間結果

Hello.i:前処理されたファイル

Hello.s: コンパイル後、アセンブリコードで記述されたファイル

Hello.o: アセンブリ後の、マシンコードで書かれたファイル

こんにちは: リンクされた実行可能ファイル

1.4 この章の概要

この記事の冒頭として、こんにちはの生活を簡単に紹介します。

第2章前処理

2.1前処理の概念と役割

前処理とは一般に、プログラムのソースコードをターゲットコードに変換する際に、バイナリコードを生成する前の処理を指します。通常、プログラムのソース コード テキストはプリプロセッサによって処理され、その結果がコンパイラ コアによってさらにコンパイルされます。このプロセスはプログラムのソース コードを解析しませんが、ソース コードを特定の単位 (C/C++ 用語では) 言語機能 (C/C++ マクロ呼び出しなど) をサポートするために使用される前処理トークン (前処理トークン) に分割または処理します。 )。

2.2 Ubuntu でのコマンドの前処理

gcc -E hello.c -o hello.i

2.3 Hello前処理結果の解析

インクルード ライブラリを追加します: stdio.h unistd.h stdlib.h

コメント省略

2.4 この章の概要

この章では、前処理の概念と役割を紹介し、参照のために hello.i にリダイレクトします。

第3章 編集

3.1 コンパイルの概念と機能

Hello.i は依然として C 言語で書かれており、コンピューターでは実行できないため、低レベル言語に変換する必要があります。そのため、コンパイルして .i を .s に変換し、低レベルのアセンブリ言語にする必要があります。 。

3.2 Ubuntu でコンパイルするコマンド

gcc -S hello.i -o hello.s

3.3 Hello のコンパイル結果の分析

3.3.1 : 関係演算

movl %edi、-20(%rbp)

cmpl $4, -20(%rbp)

これら 2 つのステップは if(argc!=4) に対応し、edi の値は argc の値と正確に一致します。

3.3.2 : 機能

リーク .LC0(%rip)、%rdi

      puts@PLT に電話をかける

      movl $1、%edi

      exit@PLT に電話する

      rdi は、printf("Usage: Hello 学生番号、名前、秒!\n"); に対応する put() のパラメータとして使用されます。

      edi は exit(1) に対応する exit のパラメータとして使用されます。

3.3.3 : 割り当て

.L2:

      movl $0, -4(%rbp)

      for(i=0;i<8;i++) で i を 0 に代入する操作に相当します。

3.3.4 : 関係演算、ジャンプ

      .L3:

      cmpl $7, -4(%rbp)

             for(i=0;i<8;i++) の i と 8 を比較する演算に相当します。

3.3.5 : 機能

      movq -32(%rbp)、%rax

      追加 $16、%rax

      movq (%rax)、%rdx

      movq -32(%rbp)、%rax

      $8 を追加、%rax

      movq (%rax)、%rax

      movq %rax、%rsi

              リーク .LC1(%rip)、%rdi

              上記のコードは以下に対応します

      printf("Hello %s %s\n",argv[1],argv[2]);argv は char ポインタ配列で、各ビットは 8 バイトを占め、最初の movq -32(%rbp), %rax; addq $16, %rax は rax の内容を argv[2] のアドレスにするので、movq (%rax), %rdx は rax の内容を取り出して rdx に送ることを意味します このとき、rdx の内容は argv[ 2]、同様に、rsi の内容は argv[1]、rdi の内容は "Hello %s %s\n" です。これら 3 つは後続の呼び出し printf@PLT のパラメータとして実行されます。

3.3.6 : 関数の操作

      movq -32(%rbp)、%rax

      追加 $24、%rax

      movq (%rax)、%rax

      movq %rax、%rdi

      atoi@PLT に電話してください

      rdi は argv[3] で、パラメータとして atio() に渡され、整数に変換されて送信のために eax に格納されます。

3.3.7 : 機能

      movl %eax、%edi

      スリープ@PLTに電話をかける

      rdi を入力として、sleep() を実行します。

3.3.8 : 算術演算

      addl $1, -4(%rbp)

      i++ に対応します。

3.3.9 : 機能

      getchar@PLT を呼び出す

      getchar(); を実行します。

3.3.10

      movl $0、%eax

      つまり、戻り値 0 です。

3.4 この章の概要

コンピューターが実行できるようにするために、hello.iはさらにhello.sに変換され、さらに低レベルのアセンブリ言語に変換されます。

第4章編集

4.1 アセンブリの概念と機能

概念: アセンブリ言語ファイルをアセンブルしてターゲット ファイルを生成します。各ソース ファイルはターゲット ファイルに対応します。つまり、アセンブリ言語コードをマシンコードに変換することは、as アセンブラーによって行われる作業です。

機能: コンピューターが読み取ることができるマシンコードを生成します。

4.2 Ubuntu でアセンブルするコマンド

gcc -c hello.s -o hello.o

4.3 再配置可能なターゲット elf フォーマット

上の図の .rela.text セクションには、再配置情報が正確に格納されます。offset は、再配置される必要があるコード セグメントの先頭からのオフセットを表します。情報の上位 4 バイトは、.symtab 内のシンボルのインデックスを表します。 4バイトは再配置の種類を示し、typeは再配置の種類を示し、例えば上記のR-X86_64_PC32は相対アドレッシング、addendは加数を示します。

4.4 Hello.oの結果分析

機械語とアセンブリ言語はほとんど1対1に対応しており、rbpからの変数の相対位置と関数の参照方法が異なるだけです。

ブランチ転送: 機械語では特定のアドレスに直接ジャンプしますが、アセンブリ言語では、たとえば .L1 にジャンプします。

ニモニック。

関数呼び出し: 機械語は呼び出しの次の命令にジャンプします (リンクされていないため、相対アドレスはデフォルトで 0 に設定されており、論理的なリップです)。一方、アセンブリ言語は関数名の後に直接続きます。

グローバル変数の使用: 関数呼び出しと同様に、マシン語では依然として rip+相対オフセット アドレスが使用されますが、アセンブリ言語では rip+セグメント名が使用されます。

4.5 この章の概要

この章では、リンクされていない機械語とアセンブリ コードの関係と違いを簡単に分析します。

第5章リンク

5.1 リンクの概念と機能

概念: リンカは、各シンボル参照を明確なシンボル定義に関連付け、複数の個別のコード セクションとデータ セクションを 1 つのセクションにマージします。シンボルを .o ファイル内の相対位置から実行可能ファイル内の最終的な絶対メモリ位置に再配置します。これらのシンボルへのすべての参照を新しい位置で更新します。

機能:リンカ(ld)は、 helloのリロケータブルファイルと、関数printfなどの標準Cライブラリで使用されるプリコンパイル済みの別ファイルprintf.oを、 hello実行ファイル用にマージします。

5.2 Ubuntu でリンクされているコマンド

Ld -o hello -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/x86_64-linux-gnu/crt1.o /usr/lib/x86_64-linux-gnu/crti.o hello.o /usr/lib/x86_64-linux-gnu/libc.so /usr/lib/x86_64-linux-gnu/crtn.o

5.3 実行対象ファイルの形式 hello

「名前」列の下にはセグメントのサイズが表示され、「アドレス」列には開始アドレスが表示されます。

下の図はプログラムヘッダーを示しています

5.4 Hello の仮想アドレス空間

データダンプには、文字 .ELF に対応するアドレス 0x400000 が表示されます。これは、プログラム ヘッダーの最初の LOAD セグメントの開始アドレスに対応し、プログラムの実行が開始される場所を示します。

PHDR : プログラムヘッダーテーブル

INTERP : プログラム実行前に呼び出す必要があるインタープリタ

LOAD : プログラムのオブジェクトコードと定数情報

DYNAMIC : ダイナミックリンカーが使用する情報

注: : 補助情報

GNU_EH_FRAME : 例外情報の保存

GNU_STACK : システムスタックを使用するために必要な権限情報

GNU_RELRO : 再配置後の読み取り専用情報の保存場所

5.5 リンク再配置プロセスの分析

objdump -d -r hello は、hello と hello.o の違いを分析し、リンク プロセスを説明します。

hello.o の移転プロジェクトと組み合わせて、hello でどのように移転されるかを分析します。

hello.o と比較すると、再配置する必要がある元の場所が直接仮想アドレスになります。次の hello.o コードは、objdump -d -r hello.o によって取得されます。

こんにちは:

こんにちは。

当然、hello.o の 1c には再配置が必要とマークされており、再配置されていないアドレスはデフォルトですべて 0 になっていますが、Hello ではリンクされているので、仮想アドレスが直接書き込まれます。以下の put() 関数呼び出しにも同じことが当てはまります。

再配置プロセス: 1c は絶対アドレス指定、直接

こんにちは

こんにちは。

タイプは PLT テーブルの再配置で、複数のマッピングの後、PLT[0] が exit() アドレスになります。再配置されていない hello.o のアドレスは、デフォルトではすべて 0 です。

今後の移転についても同様

5.6 hello実行処理

(以下のフォーマットは自分でアレンジして編集時に削除します)

  1. Jmpq *%r12 (つまり、_start の開始アドレス)
  2. Callq *0x2ed2(%rip)
  3. こんにちは!.plt+0x70

注: 3 は、パラメータの数が 4 ではない場合に発生する呼び出しであり、使用法が直接出力されて終了します。

4.callq 0x4010a0 この時点で hello ステートメントが出力されます

5.callq 0x4010c0

6.callq 0x4010e0

7.callq 0x4010b0 は getchar() を実行します

8.callq libc-2.31.so!exit は exit (0) を実行します。

edb を使用して hello を実行し、hello のロードから _start 、main の呼び出し、プログラムの終了までのすべてのプロセスを記述します。呼び出されてジャンプされた各サブルーチンの名前またはプログラム アドレスをリストしてください。

5.7 Hello ダイナミックリンク分析

プログラムが共有ライブラリによって定義された関数を呼び出す場合、コンパイラはその時点で関数のアドレスが何になるかを予測できないため、コンパイル システムは、プロセス アドレスのバインドを最初の時点まで延期する遅延バインディング メソッドを提供します。プロシージャが呼び出されたとき。関数のアドレスはGOTと手続き結合テーブルPLTの連携により解決されます。ロード時に、ダイナミック リンカは、正しい絶対アドレスが含まれるように GOT 内の各エントリを再配置し、PLT 内の各関数が別の関数を呼び出す役割を果たします。次に、edb を観察すると、dl_init の後の .got.plt セクションの変更を見つけることができます。
まず、elf の .got.plt セクションの内容を確認できます (図の白いマークは plt テーブルの最初のアドレスです)。

.dl_init を実行する前に:

dl_init の実行後;

初期化後は元々00だったことがわかります。場所はダイナミック リンク ライブラリの関数アドレスに再配置されます。

5.8 この章の概要

hello プログラムをリンクし、シンボルの解決と再配置を完了して、実行可能プログラムにします。

6章 こんにちはプロセス管理

6.1 プロセスの概念と役割

概念: プロセスとは、特定のデータセット上でコンピュータ内のプログラムを実行するアクティビティであり、システム内のリソース割り当てとスケジューリングの基本単位であり、オペレーティング システム構造の基礎です。

機能: 初期のプロセス指向コンピュータ アーキテクチャでは、プロセスはプログラムの基本的な実行エンティティでしたが、現代のスレッド指向コンピュータ アーキテクチャでは、プロセスはスレッドのコンテナでした。プログラムは命令、データ、およびそれらの構成の記述であり、プロセスはプログラムの実体です。

6.2 Shell-bashの機能と処理の流れを簡単に説明

機能: Shell-bash はコマンド言語インタープリタであり、ユーザーと Linux カーネル間のインターフェイス プログラムであり、シェルにコマンドを入力して Linux カーネルに渡すことができます。

処理の流れ: まず、bash は入力したコマンドが内部コマンドであるかどうかを判断し、内部コマンドである場合はすぐに実行します。そうでない場合は、まず子プロセスをフォークし、子プロセスに指定されたディレクトリにあるプログラム ファイルを開かせ、プログラムを実行します。

6.3 Helloのフォークプロセス作成処理

シェルは fork 関数を使用して子プロセスを作成します。新しく作成された子プロセスは、完全ではありませんが、親プロセスとほぼ同一です。子プロセスは、コードとデータのセグメント、ヒープ、共有スタック、ユーザー スタックを含む、親プロセスのユーザーレベルの仮想アドレス空間の同じコピーを取得します。子プロセスも、親プロセスと同様に、開いているファイル記述子の同一のコピーを取得しますが、それらの PID は異なります。hello プログラムを実行するコマンドを入力すると、シェルはコマンド ラインの解析を開始し、hello が組み込みコマンドではないと判断した後、シェルは fork 関数を呼び出して hello プログラムを実行する子プロセスを作成します。

6.4 Hello の execve プロセス

シェルが fork を使用して子プロセスを作成した後 (setpgid(0,0) を使用して親プロセスとは異なるプロセス グループに配置します)、子プロセスで execve 関数を使用します。execve 関数は、実行可能ファイル hello に含まれるプログラムを現在のプロセスにロードして実行し、現在のプログラムを hello プログラムに置き換えます。hello をロードして実行するには、次の手順が必要です。

1. 既存のユーザーエリアを削除します。現在のプロセスの仮想アドレスのユーザー部分にすでに存在するゾーン構造を削除します。

2. プライベートエリアをマップします。新しいプログラムのコード、データ、BSS、スタック領域の新しい領域構造を作成します。これらの新しい領域はすべてプライベートであり、コピーオンライトです (これらは第 9 章の仮想メモリの内容です)。コード領域とデータ領域は、hello ファイルの .text 領域と .data 領域にマップされます。bss 領域はバイナリ 0 で要求され、サイズが hello に含まれる匿名ファイルにマップされます。スタック領域とヒープ領域にもバイナリのゼロが必要で、初期長はゼロです。

3. 共有エリアをマッピングします。hello プログラムが共有オブジェクトにリンクされている場合、これらのオブジェクトはこのプログラムに動的にリンクされ、ユーザーの仮想アドレス空間内の共有領域にマップされます。

4. プログラムカウンタを設定します。現在のプロセス コンテキストのプログラム カウンターがコード領域のエントリ ポイントを指すように設定します。次回このプロセスがスケジュールされると、このエントリ ポイントから実行が開始されます。

execve はロードが失敗した場合にのみ -1 を返し、それ以外の場合は戻りません。

6.5 ハロープロセスの実行

プロセスコンテキスト情報とプロセスタイムスライスを組み合わせて、プロセススケジューリング、ユーザーモードとコアモードの変換などのプロセスを説明します。

コンテキストの切り替えを通じて、あるプロセスから別のプロセスに制御が流れます。プロセスがその制御フローの一部を実行する各期間は、プロセス タイム スライスと呼ばれます。hello タイムスライスが入ると、hello 内のコードが実行され始め、この時間が経過すると、hello プロセスは CPU などのリソースを占有しなくなりますが、このときのプロセス情報 (例:このときのレジスタ値)をメインメモリに格納し、カーネルに制御を戻し、カーネルは他の処理を実行し、再びハロータイムスライスが来るとレジスタ値をメモリから取り出し、メモリに復元します。最後の実行後の状態を維持し、実行を継続するこれがコンテキストの切り替えです。

同時に、例外の存在を考慮して、ユーザーが手動で ctrl-z を入力すると、hello プロセスが sigtstp シグナルを受信し、カーネルに制御が戻り、例外処理関数が実行されます。

6.6 Hello 例外と信号処理

Ctrl-Z が押されると、プロセスは sigtstp シグナルを受け取り、カーネルに制御を戻し、例外ハンドラーを呼び出します。デフォルトでは、hello プロセスは一時停止されます。このとき、bashshell プロセス waitfg() が停止するため、 fg コマンドを実行すると、bash は子プロセスに sigcont シグナルを送り、bash プロセスが waitfg() を実行することで、hello プロセスがフォアグラウンドで実行されます。

6.7 この章の概要

この章の Hello は、プログラムからプロセスへの質的な飛躍を達成し、このプロセスとそれに伴う例外処理操作を分析しました。

7 章 Hello ストレージ管理

7.1 hello メモリのアドレス空間

論理アドレスとは、プログラムによって生成されるセグメント関連のオフセット アドレスであり、絶対アドレスとも呼ばれます。hello では、セグメント内の各部分のオフセット アドレスです。

リニア アドレス: 論理アドレスから物理アドレスへの変換の間の中間層。CPU のプロテクトモードでは、セグメント化されたコンポーネント内の論理アドレスはセグメント内のオフセットアドレスとなり、セグメントのベースアドレスを加算したものをリニアアドレスと呼びます。つまり、hello の仮想メモリ アドレスです。

仮想アドレス: CPU にページング メカニズムがない場合、リニア アドレスが最終的な物理アドレスとして使用され、ページング メカニズムがある場合、リニア アドレスは仮想アドレスと呼ばれます。この大きなジョブの hello は個人のラップトップのハードウェア環境で実行されており、明らかにページング メカニズムを備えているため、hello プログラムの仮想アドレスはリニア アドレスに相当します。

物理アドレスはメモリユニットの絶対アドレスです。helloプログラムでは仮想メモリアドレスを変換した後のアドレスになります。

7.2 Intel 論理アドレスからリニア アドレスへの変換セグメント管理

論理アドレスはセグメントセレクタとオフセットで構成され、リニアアドレスはセグメント先頭アドレスと論理アドレス内のオフセットで構成されます。このうち、セグメント先頭アドレスはセグメントディスクリプタに格納される。セグメント記述子は、GDT (グローバル記述子テーブル) または LDT (ローカル記述子テーブル) である記述子テーブルに格納されます。変換する場合は、まず GDT 内の hello の LDT のベース アドレスを求めます (ベース アドレスとオフセットを加算したものがリニア アドレスになります)。

7.3 Hello のリニア アドレスから物理アドレスへの変換 - ページ管理

       リニア アドレス (通常は仮想アドレス) は、VPN と VPO の 2 つの部分に分割できます。VPN には、PTEI と PTET の 2 つの部分が含まれます。PTEI は、PTE 内の対応するエントリ グループにインデックスを付け、PTET を使用して比較して、対応するエントリを見つけることができます。エントリにはメモリ参照制限情報と物理ページ番号が含まれており、物理ページ番号と VPO を組み合わせて物理アドレスを形成し、変換を完了できます。

7.4 TLB および 4 レベルのページ テーブルによってサポートされる VA から PA への変換

       MMU (ストレージ管理ユニット) は、まず TLB 内で VPN に対応する PTE を検索し、見つかった場合は PPN を直接取得し、VPO と組み合わせて物理アドレスを形成します。見つからない場合は、PTBR (ページ テーブル ベース アドレス レジスタ) を通じて PTEA を取得し、対応する PTE をメモリ内で見つけて返します。一方で、VPO と組み合わせて物理アドレスを取得し、他方で、PTE を取得します。 、TLB テーブルが更新されます。

      

上図は第 2 階層のページテーブルの例ですが、第 4 階層のページテーブルも同様です。

仮想アドレスの VPN 部分には、第 4 レベルのページ テーブルで PPN が取得され、最終的に PA が取得されるまで、レベルごとにアドレス指定して、各レベルのページ テーブル内のオフセット アドレスが含まれます。

7.5 3 レベル キャッシュによってサポートされる物理メモリ アクセス

MMUから物理アドレスを取得したら、まずL1キャッシュ内を検索し、物理アドレスをグループインデックス、タグ、オフセットに分けてキャッシュ内を検索し、見つかった場合は値を直接CPUに渡し、見つからない場合は次から続行します。次のステップ:メインメモリに達するまで一次キャッシュを検索します

7.6 hello プロセスがフォークするときのメモリ マッピング

まず、現在のプロセスの mm_struct、vm_area_struct、およびページ テーブルの完全なコピーを作成します。両方のプロセスのすべてのページは読み取り専用としてマークされ、両方のプロセスのすべての領域構造 (vm_area_struct) はプライベート コピー オン ライト (COW) としてマークされます。新しいプロセスに戻るとき、新しいプロセスには呼び出しプロセスと同じ仮想メモリがあり、後続の書き込み操作ではコピーオンライト メカニズムを通じて新しいページが作成されます。

7.7 helloプロセス実行時のメモリマッピング

既存のユーザー領域を削除する

新しいゾーン構造を作成する

コードと初期化データは、.text および .data 領域 (ターゲット ファイルによって提供される) にマッピングされます。

匿名ファイルにマップされた .bss とスタック

コード領域のエントリポイントを指すように PC を設定します。

Linux は必要に応じてコード ページとデータ ページを入れ替えます

7.8 ページフォルトとページフォルト割り込み処理

       フォールト: hello プロセスのページ テーブル内のエントリの有効ビットが 0 の場合、ページ フォールトが発生します。つまり、仮想アドレスに対応するデータがメモリにロードされません。

       処理: プロセスがページ フォールトをスローし、制御がカーネルに返されます。カーネルはメモリ内の特定のページを犠牲ページとして使用し、それを読み取るデータと置き換え、特定の PTE が置き換えられたメモリの場所をポイントできるようにします。 、そして hello.process の実行を続けます。

7.9 動的ストレージ割り当て管理

Printf はmalloc を呼び出します。動的メモリ管理の基本的な方法と戦略について簡単に説明してください。

アロケータは、さまざまなサイズのブロックのコレクションとしてヒープを維持します。各ブロックは割り当てられているか、解放されています。アロケータは主に明示的アロケータと暗黙的アロケータに分けられます。

戦略: 明示的なフリー リストと暗黙的なフリー リスト。

暗黙的なフリー リスト: ヘッダーのサイズ フィールドを介した暗黙的な接続。アロケータは、ヒープ内のすべてのブロックを走査することにより、フリー ブロックのセット全体を間接的に走査できます。暗黙的な二重リンクリストは、フットを追加することで実装できます。フリー ブロックを探すときは、最初のアダプテーション、次のアダプテーション、ベスト アダプテーション、分離アダプテーションなどの割り当て戦略を使用できます。フリー ブロックを割り当てるときに、ブロックが大きくてより適切なブロックが見つからない場合は、ブロックを分割できます。 release ブロックは 4 つの状況に応じて隣接する空きブロックにマージする必要があります。

明示的なフリー リンク リスト: 割り当てられたブロックを管理する代わりに、特定のデータ構造を通じてフリー ブロックを管理および割り当てます。

7.10 この章の概要

       この章では、Hello プロセスのストレージ管理プロセスの分析に焦点を当てます。

8 章 hello IO 管理

8.1 LinuxのIOデバイス管理方法

機器のモデリング: ドキュメント

1. 通常のファイル: 任意のデータを含むファイル。

2. ディレクトリ: 一連のリンクを含むファイル。各リンクはファイル名をファイルにマッピングします。

3. ソケット: ネットワーク経由で別のプロセスと通信するために使用されるファイル

4. 名前付きチャンネル

5. シンボリックリンク

6. キャラクターデバイスとブロックデバイス

デバイス管理: unix io​​ インターフェイス

1. ファイルを開いたり閉じたりする

2. ファイルの読み取りと書き込み

3. 現在のファイルの場所を変更します

8.2 Unix IO インターフェースとその機能の簡単な説明

Linux がデバイスをファイルにマップする方法により、 Unixカーネルはシンプルで低レベルのアプリケーション インターフェイスを導入できます。

以下の関数と同様に、これらはシステム コールです。

1.ファイルを開きます。int open(char *filename, int flags, mode_t mode);

負でない小さい整数、つまり記述子を返します。記述子を使用してファイルを識別します。各プロセスには、標準入力 ( 0 )、標準出力 ( 1 )、および標準エラー ( 2 ) の 3 つのファイルが開かれています。戻り値: 成功した場合は新しいファイル記述子、エラーが発生した場合は-1

flags:プロセスがファイルにアクセスする方法

以下のオプションが含まれます

O_RDONLY:読み取り専用    O_WRONLY:書き込み専用    O_RDWR:読み取りおよび書き込み

O_CREAT:ファイルが存在しない場合は作成します。

O_TRUNC : ファイルがすでに存在する場合は切り詰めます

O_APPEND:書き込み操作ごとに、k をファイルの末尾に設定します。

注: 1 つ以上のビット マスクまたは

mode:新しいファイルのアクセス許可ビットを指定します。

2. 現在のファイルの場所を変更します。ファイルの先頭からのバイトオフセット。システム カーネルは、開いているファイルごとに 0 から始まるファイル位置 k を維持します。アプリケーションはシークを実行し、現在位置 k を設定し、lseek 関数を呼び出して現在のファイル位置を明示的に変更します。

3. ファイルの読み取りと書き込み。

読み取り操作: ファイルから n バイトをメモリにコピーします。現在のファイル位置 k から開始して、k を k+n まで増やします。サイズが m バイトのファイルの場合、k>=m の場合、読み取り操作によりEOF 条件。

書き込み操作: n バイトをメモリからファイルにコピーし、k は k+n に更新されます

ssize_t read(int fd, void *buf, size_t n);

戻り値: 成功した場合は読み取られたバイト数、EOF の場合は 0、エラーが発生した場合は -1。

ssize_t write(int fd, const void *buf, size_t n);

戻り値: 成功した場合は書き込まれたバイト数、エラーが発生した場合は -1

4. ファイルを閉じる: カーネルは、ファイルが開かれたときに作成されたデータ構造を解放し、記述子を記述子プールに復元します。プロセスは、close 関数を呼び出して、開いているファイルを閉じます。すでに閉じられている記述子を閉じるとエラーになります。

int close(int fd); 戻り値: 成功した場合は 0、エラーが発生した場合は -1。

8.3 printfの実装解析

int printf(const char *fmt, ...)

{

int i;

char buf[256];

    va_list arg = (va_list)((char*)(&fmt) + 4);

    i = vsprintf(buf, fmt, arg);

    write(buf, i);

    私を返します。

}

たとえば、printf ( "hello %c",a )を考えてみましょう。

Buf には出力する文字列が格納されます。fmt"hello %c"文字列の最初のアドレスです。この場合、argはaのポインタです。

int vsprintf(char *buf, const char *fmt, va_​​list args)

   {

    char* p;

    char tmp[256];

    va_list p_next_arg = args;

  

    for (p=buf;*fmt;fmt++) {

    if (*fmt != '%') {

    *p++ = *fmt;

    続く;

    }

  

    fmt++;

  

    スイッチ (*fmt) {

    ケース「x」:

    itoa(tmp, *((int*)p_next_arg));

    strcpy(p, tmp);

    p_next_arg += 4;

    p += strlen(tmp);

    壊す;

    ケース:

    壊す;

    デフォルト:

    壊す;

    }

    }

  

    戻り値 (p - buf);

   }

fmtの内容を1 文字ずつ読み取ります。 %が見つからない場合はbufを最初のアドレスとしてfmtの文字をデータ セグメントにコピーし (進行状況を追跡するポインタとしてpを使用します)、 fmtポインタは前に進みます。 %が見つかった場合は、変数を特定の形式で出力するには、現在のpポインターが指すargから内容をコピーし、 fmt が前の移動を継続することを意味します。文字列が読み取られたことを示す\0が見つかるまで上記の操作をループします。このとき、p は出力する文字列の末尾を指し、bufは先頭にあるため、減算して返されるiは長さになります文字列の。最後に、bufを先頭としたアドレスの文字列を標準出力領域にi文字として書き込みます。write関数、trap: syscallを設定し、システムに制御を与えます。キャラクタディスプレイドライバサブルーチン:ASCIIからフォントライブラリへ、表示vram (各ポイントのRGBを保存)色の情報)。

ディスプレイチップは、リフレッシュ周波数に従って 1 行ずつvramを読み取り、各ポイント ( RGB成分)を信号線を介して LCD に送信します。

8.4 getchar の実装分析

非同期例外 - キーボード割り込み処理: キーボード割り込み処理サブルーチン。キー スキャン コードを受け入れ、それを ASCII コードに変換し、システムのキーボード バッファに保存します。bb ポインタを使用して char 型データを取得し、bb ポインタが buf の先頭アドレスを直接指すようにし、最後に read の戻り値を確認します。read エラーが発生した場合は、n=-1 が返され、最終的に EOF が返されます。それ以外の場合は成功を意味し、bb が返されます。

8.5 この章の概要

       最初はシステムコールを伴う hello の io 操作の詳細な調査

結論は

コンピューター システムの言語で、hello が実行するプロセスを段階的に要約してください。

コンピュータ システムの設計と実装に対する深い理解、新しい設計と実装方法などの革新的なアイデア。

Hello は最初は C 言語で書かれており、前処理、コンパイル、アセンブリを経て、01 という文字列の形式のマシンコードになります。他のライブラリ (printf など) の関数の呼び出しは、正確な仮想アドレスが分からないと実行できません。 。したがって、再度リンクすると実行可能プログラムになります。

bash シェルで hello ファイルを開くと、bash はまず子プロセスをフォークしてからファイルを実行するため、hello はプロセスになります。

Hello プログラムの実行に必要なコードとデータはストレージ管理ユニットを経由する必要があり、精巧なマルチレベル キャッシュ、マルチレベル ページ テーブル、仮想アドレス メカニズム、および TLB が相互に連携して、データの読み取りを高速かつ正確に行い、データを保存します。空間!

付録

Hello.i: 前処理されたファイル

Hello.s: コンパイル後、アセンブリコードで記述されたファイル

Hello.o: アセンブリ後の、マシンコードで書かれたファイル

こんにちは: リンクされた実行可能ファイル

参考文献

[1] ランダル E. ブライアント、デビッド R. オハラロン、コンピューター システムの深い理解、Machinery Industry Press

[2] ch06-02 メモリ階層システム、ハルビン、ハルビン工業大学

[3] ch09-1 仮想メモリ、ハルビン、ハルビン工業大学

[4] Luo Ya Jing Feng. Linux ダイナミック リンク GOT および PLT https://www.cnblogs.com/xingyun/archive/2011/12/10/2283149.html

おすすめ

転載: blog.csdn.net/qq_16198739/article/details/124830131