これは、オペレーティングシステムと核の根底にある謎に関する理論/法則を取り巻くより理論的および概念的なアイデアを育むのに役立つように見える素晴らしい学習曲線でした。私は推測しました、私はOSSがどのように機能したかについて大丈夫なアイデアを持っていました。ただし、独自のOSを作成することは、読んでいるだけでははるかに明確でした。私自身、正直な意見で。これは、カーネルモードとユーザーモードで混乱したいソフトウェアをよりよく理解する方法でした。
始める前に、カーネルとオペレーティングシステムは32ビットです。私も64ビットで概念を説明しますが、明らかにそれらの1つはロングモードです。
モード
割り込み
記述子
ページング
Intel®64およびIA-32アーキテクチャソフトウェア開発者のマニュアルボリューム3A:Systemプログラミングガイド、パート1の保護モードで詳細をお読みください。第3章 *
割り込みとは何ですか
割り込みは、キーボード、ソリッドステートドライブ、ハードドライバー、マウスやソフトウェアなどのデバイスによって送信されている信号またはデータであると考えることができます。これは、イベントが発生し、現在のことをすぐに停止し、割り込みを送信するものに進む必要があることを伝えます。
たとえば、マウスを移動/クリックすると、マウスコントローラーはCPUの割り込みコントローラーに割り込みを送信します。CPUの注意はすぐにマウス割り込みに移動し、ルーチン(マウスの動きまたはクリック)の実行に進みます。マウスの割り込み後、CPUは割り込みの前に何でも実行し続けるか、信号があった場合に別の割り込みを管理します。
+------------------------+ +------------+
| TYPES OF INTERRUPTS |------------| Exceptions |
+------------------------+ +------------+
/
/
/
+------------+ +------------+
| HARDWARE | | SOFTWARE |
| INTERRUPTS | | INTERRUPTS |
+------------+ +------------+
IRQライン、またはPINベースのIRQ:これらは通常、チップセットで静的にルーティングされます。チップセット上のデバイスからラインは、デバイスから送信された割り込み要求をシリアル化するIRQコントローラーに実行され、レースを防ぐためにCPUに1つずつ送信します。多くの場合、IRQコントローラーは、デバイスの優先度に基づいて、複数のIRQをCPUに一度に送信します。非常によく知られているIRQコントローラーの例は、すべてのIBM-PC互換チップセットに存在するIntel 8259コントローラーチェーンで、2つのコントローラーを一緒に連鎖させ、それぞれがLegacy IBM-PCで合計16の使用可能なIRQシグナリングピンを提供する8つの入力ピンを提供します。
メッセージベースの割り込み:これらは、中断装置、割り込み自体、およびベクトル化情報に関する情報のために予約されたメモリの場所に値を書き込むことによって知らされます。このデバイスには、ファームウェアまたはカーネルソフトウェアによって書き込む場所が割り当てられています。次に、デバイスのバスに固有の仲裁プロトコルを使用して、IRQがデバイスによって生成されます。メッセージベースの割り込み機能を提供するバスの例は、PCIバスです。 wiki.osdev -https://wiki.osdev.org/interrupts
エントリ -エントリは、エントリに関連する地域の限界とアクセス特権とともに、開始する場所のメモリ内の地域を定義します。 OSがシステムで実行されている場合(リング0)またはアプリケーション(リング3)で実行されている場合、プロセッサに伝えるようにアクセス特権。アプリケーションまたはUSERMODEが特定のレジスタ/オペランドやニーモニックにアクセスすることを防ぎます。 CRレジスタとCLI/STIなど。
制限 -セグメント記述子のサイズ
セグメントセレクター -記述子のインデックスを保持するレジスタです
より明確にするために、インデックスはセレクターではありません
セグメント登録が保持していること:
アクセス記述子テーブルにも特権があります。これは、すべてのレジスタのRPL(リクエスト特権レベル)と呼ばれますが、 csはCPL(現在の特権レベル)と呼ばれます。どちらもさまざまな目的を果たしています。これは、IntelまたはAMDのマニュアルで確認できます。
調べるために使用するテーブル。 1つのテーブルはGDTです。もう1つはLDTです。
セレクターの使用を概念的に想像するための非公式のルール:したがって、非公式のルールは次のとおりです。
selector = index + table_to_use + privilege table_to_use + index = descriptor =使用するメモリのセグメントに関するすべての情報
プラス記号は算術操作ではありません
セグメントセレクターレジスタのビットフィールド:
15 3 2 0
+--------------------------------------------------+----+--------+
| Index | TI | RPL |
+--------------------------------------------------+----+--------+
TI = Table Indicator: 0 = GDT, 1 = LDT
The TI specify if the Descriptor were dealing with is a GDT or LDT
IF(TI == 0) THEN
... THE DESCRIPTOR IS A GDT
ELSEIF(TI == 1) THEN
... THE DESCRIPTOR IS A LDT
GDTは、論理アドレスを備えた1:1です。これは、GDTがセレクターで作業する例です。
<---- Selector ----> +----- Segment Selector Register
+-------+----+-----+ v
| Index | TI | RPL | = DS
+-------+----+-----+ GDT LDT
| | +---------------------+ +---------------------+
| +------------>| Null Descriptor | | Null Descriptor |
| +---------------------+ +---------------------+
| | Descriptor 1 | | Descriptor 1 |
| +---------------------+ +---------------------+
| | | | |
| ... ... ... ... ... ... ... ...
| | |
| +---------------------+
+------------------->| Descriptor K |
+---------------------+
| |
... ... ... ...
RPL (Request Privilege Level) describes the privilege for accessing the descriptor
GDTRにすべてのGDTベース(アドレス)と制限(GDTのサイズ)を保存します。 GDTRは、ベースから始まるメモリ内のすべてのGDTエントリを指しています。その後、 lgdtニーモニックがロードされます。
typedef union _gdt_descriptor
{
struct
{
uint64_t limit_low : 16 ;
uint64_t base_low : 16 ;
uint64_t base_middle : 8 ;
uint64_t access : 8 ;
uint64_t granularity : 8 ;
uint64_t base_high : 8 ;
};
} __attribute__((packed)) gdt_entry_t ;
gdt_entry_t gdt_entrys[ 256 ];
/* The GDTR (GDT Register) */
struct gdtr
{
uint16_t limit;
uint32_t base;
} __attribute__((packed)) gdtr;
...
gdtr.base = &gdt_entrys;
gdtr.limit = ( sizeof (gdt_descr) * 256 ) - 1 )
詳細については、AMD64アーキテクチャプログラマーズマニュアル、第2巻、セクション4.7(pg。84-90{+})で読んでください
これを参照し、それ以降。 https://notes.shichao.io/utlk/ch2/#paging-in-hardwareこれは私が持っていた最も楽しいことでした。
X86 OS 4KBページのレガシーページの仮想アドレス:
X86 OS CR4.PAEページング4KBページ付き仮想アドレス:
X86_64(IA-32E)OS CR4.LME/CR4.PAEページング仮想アドレス4KBページ:
•コントロールレジスタCR0のWPフラグとPGフラグ(それぞれビット16とビット31)。
•PSE、PAE、PGE、PCIDE、SMEP、SMAP、およびPKEフラグは、コントロールレジスタCR4のフラグ(ビット4、ビット5、ビット7、ビット20、ビット21、およびビット22)。
•IA32_EFER MSRのLMEフラグとNXEフラグ(それぞれビット8とビット11)。 •EFLAGSレジスタのACフラグ(ビット18)。 Intel®64およびIA-32アーキテクチャソフトウェア開発者のマニュアルボリューム3A:System Programming Guide、パート1。第4章
•IA32_EFER MSRのLMEフラグとNXEフラグ(それぞれビット8とビット11)。 •EFLAGSレジスタのACフラグ(ビット18)。 Intel®64およびIA-32アーキテクチャソフトウェア開発者のマニュアルボリューム3Aの第4章:システムプログラミングガイド、パート1。第4章
CR4.PAEおよび/またはCR4.LMEが1に設定されている場合、PSEは完全に無視されます。
端末は追加されていません
cd smkrnl; make run
このプロジェクトでの私の継続的な努力に関するインスピレーション/サポートの火花と、Kernel/OS開発内の特定の概念を理解するのに役立ちます。 =)