質問

カーネルの設計に取り組んでいますが、ページングに関していくつか質問があります。

これまでの基本的な考え方は次のとおりです。各プログラムは4Gのメモリを取得します(プログラムが呼び出すことができるカーネル関数用に予約した部分を除く)。そのため、OSは、プログラムが操作中に使用する必要があるメモリ内のページを読み込むための何らかの方法を見つける必要があります。

今、無限のメモリとプロセッサ時間があると仮定すると、存在しない(またはスワップアウトされた)ページのページフォールトを使用して、プログラムが書き込みまたは読み取りを行うページをロード/割り当てできましたOSがそれらをすばやく割り当てたり、交換したりすることができます。しかし、実際には、このプロセスを最適化する必要があります。これにより、プログラムが常にすべてのメモリを消費することがなくなります。

だから、私の質問は、OSが一般的にどのようにこれを行っているのでしょうか?私の最初の考えは、プログラムがページを設定/解放するために呼び出す関数を作成し、それを独自にメモリ管理することですが、プログラムは一般的にこれを行いますか、コンパイラは自由に統治していると仮定しますか?また、かなり大きなメモリセグメントを割り当てる必要がある状況をコンパイラはどのように処理しますか? Xページを順番に提供しようとする関数を提供する必要がありますか?

これは明らかに言語固有の質問ではありませんが、私は標準Cに偏っていて、C ++には長けているので、コード例はそのまたはアセンブリのいずれかにしたいです。 (アセンブリは必要ないはずです。可能な限り多くのCコードで動作するようにし、最後のステップとして最適化するつもりです。)

同様に答えが簡単な別のこと:プログラムが呼び出す必要のあるカーネル関数を一般にどのように扱うのですか?プログラムが呼び出すことができる最も基本的な機能/プロセス固有のメモリを含むメモリの設定領域(仮想空間の終わりに向かって考えていた)を持っているだけでいいですか?そこからの私の考えは、プログラムが何か重要なことをする必要があるときに、カーネル関数に非常に豪華なことをさせ、ページをスワップアウトすることです(したがって、プログラムは自分のスペースに敏感なカーネル関数を見ることができません)が、私は本当にそうではありませんこの時点でセキュリティに焦点を当てています。

だから、具体的なものよりも一般的なデザインのアイデアのほうが心配だと思います。カーネルを(なんとかして)GCCと完全に互換性を持たせたいので、通常のプログラムが必要とするすべてを提供することを確認する必要があります。

アドバイスありがとうございます。

役に立ちましたか?

解決

これらすべての質問の良い出発点は、Unixがどのようにそれを行うかを見ることです。有名な引用にあるように、「UNIXを理解していない人は、UNIXを再発明する運命にあります。」

まず、カーネル関数の呼び出しについて。プログラムはおそらく「ユーザーモード」で実行されている可能性が高いため、単にプログラムが呼び出すことができる場所に関数を用意するだけでは十分ではありません。 (IA-32のリング3)および「カーネルモード」でカーネルを実行する必要があります。 (通常はIA-32で0を鳴らします)特権操作を行います。どういうわけか両方のモード間の移行を行う必要があり、これは非常にアーキテクチャ固有です。

IA-32では、従来の方法はIDTでゲートをソフトウェア割り込みとともに使用することです(Linuxはint 0x80を使用します)。新しいプロセッサには、他の(より高速な)方法があり、使用可能なプロセッサは、CPUがAMD製かIntel製か、および特定のCPUモデルによって異なります。このバリエーションに対応するため、最近のLinuxカーネルは、すべてのプロセスのアドレス空間の上部にあるカーネルによってマップされたコードのページを使用します。そのため、最近のLinuxでは、システムコールを行うには、このページで関数を呼び出します。この関数は、カーネルモードに切り替えるために必要なことをすべて行います(カーネルには、そのページの複数のコピーがあり、使用するコピーを選択しますプロセッサの機能に応じてブート時に)。

今、メモリ管理。これは巨大な主題です。あなたはそれについての大きな本を書くことができ、主題を徹底することはできません。

メモリには少なくとも 2つのビューがあることを忘れないでください:物理ビュー(ページの実際の順序、ハードウェアメモリサブシステムと多くの場合は外部周辺機器に表示)および論理ビュー(CPUで実行されているプログラムが表示するページの順序)。両方を混同することは非常に簡単です。 物理ページを割り当て、プログラムまたはカーネルアドレス空間の論理アドレスに割り当てます。 1つの物理ページに複数の論理アドレスを設定し、さまざまなプロセスのさまざまな論理アドレスにマッピングできます。

カーネルメモリ(カーネル用に予約済み)は、通常、すべてのプロセスのアドレススペースの先頭にマップされます。ただし、カーネルモードでのみアクセスできるように設定されています。メモリのその部分を隠すための派手なトリックは必要ありません。ハードウェアはアクセスをブロックするすべての作業を行います(IA-32では、ページフラグまたはセグメント制限によって行われます)。

プログラムは、いくつかの方法でアドレス空間の残りの部分にメモリを割り当てます。

  • メモリの一部は、カーネルのプログラムローダーによって割り当てられます。これには、プログラムコード(または「テキスト」)、プログラム初期化データ(「データ」)、プログラム初期化されていないデータ(「bss」、ゼロで埋められた)、スタック、およびいくつかのオッズとエンドが含まれます。ロードする実行可能ファイルのヘッダーから、どれだけ割り当てるか、どこに、何を初期コンテンツにするか、どの保護フラグを使用するか、その他いくつかのことを読み取ります。
  • 従来、Unixには、メモリの領域が拡大および縮小することがあります(その上限は brk()システムコールを介して変更できます)。これは伝統的にヒープによって使用されます(Cライブラリのメモリアロケーター、 malloc()はインターフェイスの1つであり、ヒープを担当します)。
  • 多くの場合、カーネルにファイルをアドレス空間の領域にマッピングするように依頼できます。その領域に対する読み取りと書き込みは、(ページングマジックを介して)バッキングファイルに送られます。これは通常、 mmap()と呼ばれます。匿名の mmap を使用すると、ファイルにバッキングされていないアドレス空間の新しい領域を割り当てることができますが、それ以外は同じように動作します。カーネルのプログラムローダーは、多くの場合 mmap を使用してプログラムコードの一部を割り当てます(たとえば、プログラムコードは実行可能ファイル自体によってバックアップできます)。

いかなる方法でも割り当てられていないアドレス空間のアクセス領域(

他のヒント

この質問に対する答えは、アーキテクチャに大きく依存しています。 x86について話していると仮定します。 x86では、カーネルは通常、一連のシステムコールを提供します。これは、カーネルへの事前定義されたエントリポイントです。ユーザーコードはこれらの特定のポイントでのみカーネルに入ることができるため、カーネルはユーザーコードとのやり取りを慎重に制御できます。

x86には、システムコールを実装する方法が2つあります。割り込みを使用する方法と、sysenter / sysexit命令を使用する方法です。割り込みにより、カーネルは割り込み記述子テーブル(IDT)をセットアップします。これは、カーネルへの可能なエントリポイントを定義します。その後、ユーザーコードは int 命令を使用してソフト割り込みを生成し、カーネルを呼び出します。割り込みはハードウェアによって生成することもできます(いわゆるハード割り込み)。これらの割り込みは通常、ソフト割り込みとは区別されるべきですが、そうである必要はありません。

割り込みの処理が遅いため、sysenterおよびsysexit命令は、システムコールを実行する高速な方法です。私はそれらを使用することにあまり詳しくないので、あなたの状況にとって彼らがより良い選択であるかどうかについてコメントすることはできません。

どちらを使用する場合でも、システムコールインターフェイスを定義する必要があります。割り込みを生成するとスタックがカーネルスタックに切り替わるので、システムコールの引数をスタックではなくレジスタで渡すことをお勧めします。これは、システムコールを行うためにユーザーモードエンドと、システムコールの引数を収集してレジスタを保存するカーネルエンドの両方で、ほぼ確実にいくつかのアセンブリ言語スタブを記述する必要があることを意味します。

すべての準備が整ったら、ページフォールトの処理について考え始めることができます。ページフォールトは事実上別の種類の割り込みです。ユーザーコードがページテーブルエントリのない仮想アドレスにアクセスしようとすると、割り込み14が生成され、エラーアドレスとしてフォールトアドレスも取得されます。カーネルはこの情報を取得してから、ディスクから欠落しているページを読み込み、ページテーブルマッピングを追加し、ユーザーコードにジャンプして戻ることを決定できます。

MITオペレーティングシステムの資料をご覧になることを強くお勧めしますクラス。参照セクションをご覧ください。たくさんの良いものがあります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top