学習目的のためにゼロから構築されたX86ベースのオペレーティングシステム
int 64を介して行われますオペレーティングシステムを構築するには(GCC、NASMがインストールされていると仮定)、
makeQEMUの下で実行する
make qemu実行するには(Bochs、Bochs-SDLがインストールされていると仮定)、
make runデバッグサポート(GDB)でQEMUの下で実行する
make qemu_gdb(GDBを添付して、必要なコマンドが既に提供されています。
BIOSは16ビットリアルモードでプロセッサを開始し、Grubは32ビット保護モードを開始します。カーネルELF画像には、GRUB仕様に従ってマルチビートヘッダーが付属しています。GRUBが最初の512バイトの画像でこのヘッダーを見つけた場合、ELFを0x100000の場所にロードし、低メモリはBIOSに属し、VGAのような他のハードウェア/IOマッピングに属します。ブートアップコード、 _startエントリポイントのカーネルから実行され、(bssはすでにgrubによって初期化されているゼロです)。
シンプルなfirst-fit戦略メモリアロケーターは、カーネルスペースからメモリを割り当てます。 free中に、隣接するフリーブロックの圧縮も管理します。
ユーザースペースの場合、MALLOC/FREEが提供され、内部で使用されるsbrkシステムコールがシステムの切断を増やします(必要に応じて)。カーネルは必要なページテーブルのセットアップを行い、戻り値システムの破損制限を増やします。
これは、カーネルスペースメモリマッピングとユーザースペースメモリマッピングに分けられます。カーネルスペースマッピングは一定であり、すべてのプロセスアドレス空間の一部であり、クローン化されていないリンクのみがリンクされています。これは、カーネル空間の1つのプロセスからの変更が他のプロセスでも表示される必要があるためです。
ユーザースペースマッピングはexecコールに依存し、すべてのプロセスには独自のカーネルとユーザースタックがあります。
コンテキストスイッチ中、CR3レジスタは現在のプロセスページディレクトリベースアドレスでロードされ、TLB(翻訳LookAsideバッファー)も内部的に無効になります。
ユーザースペースアプリケーションは、標準ELF形式のCPIO形式Archieveであるinitramfsに保存されます。 exec Kernelの発見と解析中にELF画像は、それに応じてページテーブルを設定します。 Initプロセスはshellを開始するだけで、そこに永遠に垂れ下がっています。
スケジューラは、主に2つのケースで現在実行中のプロセスに代わって実行されます。
カーネルモードコード/データセグメントは、それに応じてプログラムされた特権レベルを持つユーザーモードコード/データセグメントとは分離されています。例外から戻っている間、ハードウェアはスタックからCS(コードセグメント)とSS(スタックセグメント)をポップアップして、より低い特権レベルに戻ります。
新しいタスクを作成しながら、このスタックフレームをそれに応じてプログラムします。
/* Task will start in CPL = 3, i.e. user mode */
task -> irqf -> cs = ( SEG_UCODE << 3 ) | DPL_USER ;
task -> irqf -> ds = ( SEG_UDATA << 3 ) | DPL_USER ;
task -> irqf -> eflags = 0x200 ;
task -> irqf -> ss = ( SEG_UDATA << 3 ) | DPL_USER ;X86ハードウェアには、タスクスイッチングのサポートが組み込まれており、基本的には他のセグメンテーションパラメーターとともにユーザースタックからカーネルスタックに切り替えます。このために、すべてのタスクは独自のTSSでセットアップする必要があり、コンテキストの切り替え中に変更されます。ハードウェアタスクの切り替えは使用しませんが、ソフトウェア自体でも同じことをします。いずれにせよ、現在のタスクに有効なカーネルモードSS(スタックセグメント)とESP(スタックポインター)を備えた1つのTSSを少なくとも1つセットアップする必要があります。
ランダムなFAQ
お気軽にフォークして、マージリクエストを送信してください