Windows system >> Windowsの知識 >  >> Linuxシステムチュートリアル >> Linuxチュートリアル >> Linuxオペレーティングシステムのカーネルのソースコードの解釈

Linuxオペレーティングシステムのカーネルのソースコードの解釈

  
                  カーネルに興味はあるが選択の余地がない多くのLinux愛好家のために、この記事はLinuxの複雑なカーネルメカニズムを説明するよりも、Linuxカーネルソースを理解する方法を紹介することを目的としています。コアソースプログラムのファイル構成:
1。 Linuxカーネルのソースプログラムは通常/usr /src /linuxの下にインストールされており、非常に単純な番号付け規則があります。偶数のコア(2.0.30など)は安定したコア、奇数のコアはすべてです。 (例2.1.42)開発の中核です。この記事は安定版2.2.5のソースコードに基づいており、実装プラットフォームの2番目の部分はRedhat Linux 6.0です。 2。コアのソースのファイルはツリー構造になっており、ソースツリーの一番上に次のようなディレクトリがあります:•Arch:archサブディレクトリにはアーキテクチャに関連するすべてのコアコードが含まれています。 i386はintel cpuおよびその互換アーキテクチャのサブディレクトリです。 PCは一般にこのディレクトリに基づいています;●インクルード:サブディレクトリにはカーネルのコンパイルに必要なヘッダファイルのほとんどが含まれています。プラットフォームに依存しないヘッダファイルはinclude /linuxサブディレクトリにあり、intel cpu関連ヘッダファイルはinclude /asm-i386サブディレクトリにあり、include /scsiディレクトリはscsiデバイスのヘッダファイルディレクトリです。このディレクトリには、コアの初期化コード(注:システムのブートコードではありません)が含まれています。2つのファイルmain.cとVersion.cが含まれています。 Mm:このディレクトリには、ページストレージ管理メモリの割り当てや解放など、CPUアーキテクチャから独立したすべてのメモリ管理コードが含まれ、アーキテクチャ関連のメモリ管理コードはarch /* /mm /など、arch /にあります。 I386 /mm /Fault.c●カーネル:メインのコアコード、このディレクトリのファイルはほとんどのLinuxシステムのカーネル機能を実装し、最も重要なファイルはsched.cです;同様に、アーキテクチャに関連するコードはArch /* /kernel;●Drivers:システム用のすべてのデバイスドライバを配置します;各ドライバはサブディレクトリを占有します:たとえば、/blockはide(ide.c)のようなブロックデバイスドライバです。ファイルシステムを含む可能性のあるすべてのデバイスがどのように初期化されるかを知りたい場合は、drivers /block /genhd.cのdevice_setup()を参照してください。 nfsファイルシステムをインストールするときにネットワークをインストールする必要があるため、ハードディスクを初期化するだけでなくネットワークも初期化します。たとえば、Libはコアライブラリコードを配置し、Net、コアおよびネットワーク関連コードを格納します。 Fs、すべてのファイルシステムコード、さまざまな種類のファイル操作コード、それぞれのサブディレクトリはfatやext2などのファイルシステムをサポートしています;スクリプト、このディレクトリにはコアを設定するためのスクリプトファイルが含まれています。一般的に、各ディレクトリには、.dependファイルとMakefileがありますこれら2つのファイルは、コンパイル時に使用される補助ファイルです。非常に役に立つ;そして、いくつかのディレクトリには、ディレクトリ内のファイルの説明であるReadmeファイルがありますが、これもカーネルソースの理解に役立ちます。実際の戦闘の解釈:あなたのカーネルにシステムコールを追加する
Linuxカーネルのソースコードは非常に合理的かつ科学的なツリー構造で構成されていますが、関数関連ファイルは同じサブディレクトリに置かれます。読みやすさしかし、Linuxカーネルのソースコードは非常に大きくて非常に複雑で、非常に合理的なファイル編成方法でも、異なるディレクトリのファイル間にはまだ多くの関連付けがあります。関連ファイル、およびこれらのファイルが同じサブディレクトリにない可能性があります。システムが非常に複雑で文書間のリンクが複雑であることが、多くの人がそれを恐れている主な理由かもしれません。もちろん、この厄介な仕事の見返りも非常に魅力的です。あなたは(以下のシステムによって導かれるように)コンピュータに関する多くの基礎知識を学ぶことができるだけでなく、全体の操作も学ぶことができます。システムアーキテクチャの微妙さと特定の詳細問題を解くときのアルゴリズムの巧妙さ、そしてさらに重要なことに、ソースコードを分析する過程で、あなたは少しでも専門的になるでしょう。コードの10分の1を分析した後は、プロのプログラマーがどんなコードを書いているのか、アマチュアがどんなコードを書いているのか深く理解するでしょう。読者がこの機能をよりよく理解できるようにするために、以下はカーネル分析の具体的な例を示しています。カーネル解析法分析例を次に示します。 A、オペレーティングプラットフォーム:
ハードウェア:cpu intel Pentium II;ソフトウェア:Redhat Linux 6.0;カーネルバージョン2.2.5 B、関連するカーネルソースコード分析:
1 。システムの起動と初期化:Linuxシステムを起動するにはいくつかの方法があります。一般にLilo、Loadinブート、Linuxブートストラップ(bootsect-loader)があり、後者はソースプログラムarch /i386 /boot /bootsectに対応します。 S、それはスペースのためにここで分析されていないリアルモードのアセンブラです;どの起動方法に関係なく、最後にarch /i386 /Kernel /setup.Sにジャンプしても、setup.Sは主にランタイムモードです。システムが保護モードに入る準備としての初期化;その後、システムはarch /i386 /kernel /head.Sを実行します(アーカイブされたカーネルは最初にarch /i386 /boot /compressed /head.Sを実行する必要があります)。 Sで定義され、トラップと割り込みのすべてのエントリアドレスを保持する256項目のidtテーブル(Interrupt Descriptor Table)の作成を担当するアセンブリプログラムsetup_idt;これにはシステムコールマスタ制御system_callのエントリアドレスが含まれます。もちろん、これに加えて、head.Sはまだ他の初期化作業をしなければなりません。システムの初期化後に実行される最初のカーネルプログラム、asmlinkage void __init start_kernel(void)は、/usr /src /linux /init /main.cでusr /src /linux /arch /i386 /kernel /trapsを呼び出すことによって定義されます。 c __init trap_init(void)の関数は、各トラップおよび割り込みサービスルーチンのエントリアドレスをidtテーブルに設定します。ここで、システムコールマスタプログラムsystem_calは割り込みサービスルーチンの1つで、void __init trap_init(void)関数は次のように渡します。マクロset_system_gate(SYSCALL_VECTOR、& system_call)を呼び出し、システムコールマスタのエントリを割り込み0x80でハングさせます; SYSCALL_VECTORは/usr/src/linux/arch/i386/kernel/irq.hで定義されています。定数0x80、system_callは割り込みマスタ制御プログラムのエントリアドレス、割り込みマスタプログラムは/usr/src/linux/arch/i386/kernel/entry.Sのアセンブリ言語で定義されています3.割り込みマスタ制御プログラムは、主に責任があります。システムコールを実行する前にプロセッサの状態を保存し、現在のコールが正当かどうかをチェックし、システムコールベクトルに従って、sys_call_tableテーブルに格納されている対応するシステムサービスルーチンにプロセッサをジャンプさせます。回復ハンドラの状態は、システムサービスルーチンから戻った後にユーザープログラムに返され、システムコールベクトルは/usr/src/linux/include/asm-386/unistd.hに定義され、sys_call_tableテーブルは/usr /src /に定義されます。 linux /arch /i386 /kernel /entry.Sでは、システムコールのユーザープログラミングインタフェースも/usr/src/linux/include/asm-386/unistd.hで定義されています。このシステムコールは、dosシステムのint 21h割り込みサービスにも似ており、0x80割り込みを一般的なエントリとして受け取り、sys_call_tableテーブルに格納されているさまざまな割り込みサービスルーチンのエントリアドレスに移動してさまざまな割り込みサービスを形成します。ソースコードの分析によると、システムコールを追加するには、sys_call_tableテーブルにエントリを追加し、システムサービスルーチンのエントリアドレスを保存してから、カーネルを再コンパイルする必要があります。 。このバージョンのLinuxカーネルソースでは、システムコールに関連するソースファイルに次のものが含まれています。arch /i386 /boot /bootsect.S arch /i386 /Kernel /setup.S arch /i386 /boot /compressed /head.S arch /i386 /kernel /head.S init /main.c arch /i386 /kernel /traps.c arch /i386 /kernel /entry.S arch /i386 /kernel /irq.h include /asm-386 /unistd.hもちろん、これは関係する主なファイルのほんの一部です。実際、システムコールを増やすには、実際には/asm-386 /unistd.hとarch /i386 /kernel /entryしか含まれていないファイルを修正する必要があります。2

Copyright © Windowsの知識 All Rights Reserved