これは私の前のフォローアップ質問です 質問 。
答えに基づくと、システムコールは、プロセスの仮想メモリのカーネル部分にジャンプするときの例です。
システムコール以外の仮想メモリのこの部分を使用する通常のプロセス(カーネル以外)の他の例は何ですか?このカーネル部分に直接ジャンプする関数呼び出しはありますか?
メモリのこのセクションにジャンプすると、プロセスがこの部分にアクセスするために、プロセッサはカーネルモードビットを自動的に1に設定しますか、それともこのビットを設定する必要はありませんか?
このカーネル部分内のすべての実行は、カーネルプロセスへのコンテキスト切り替えを必要とせずに行われますか?
(コメントについてこれらのフォローアップ質問をしたくなかったので、別のスレッドを開きました。)
ユーザーモードで実行されているプロセスは、カーネルのアドレス空間にまったくアクセスできません。プロセッサがカーネルモードに切り替えてカーネルコードを実行する方法はいくつかありますが、それらはすべてカーネルによって設定され、明確に定義されたコンテキストで発生します。システムコールの実行、割り込みへの応答、または障害を処理します。システムコールには、カーネルコードを直接呼び出す必要はありません。これらには、CPUに制御をカーネルに転送し、呼び出しプロセスに代わって番号で識別される特定のシステムコールを実行するように要求する、アーキテクチャ固有のメカニズムが含まれます。 LWNには、これがどのように機能するかを説明する一連の記事があります:システムコールの構造パート1 、 パート2 、および 追加コンテンツ 。
プロセスがカーネルのアドレス空間のメモリにアクセスしようとすると、カーネルモードに切り替わりますが、障害が発生した結果です。その後、カーネルはセグメンテーション違反(SIGSEGV
)でプロセスを強制終了します。
32ビットx86には、isfar呼び出しを使用してカーネルモードに切り替えるメカニズムがあります コールゲート ;しかし、Linuxはそれを使用しません。 (そして、カーネルアドレスを呼び出すのではなく、特別なコードセグメント記述子に依存しています。)
上記を参照してください。カーネルメモリにジャンプすることはできません。上記の状況では、カーネルモードに移行するときに、CPUは移行が許可されていることを確認し、許可されている場合は、使用されているアーキテクチャで適切なメカニズムを使用してカーネルモードに切り替えます。 x86 Linuxでは、これはリング3からリング0に切り替えることを意味します。
カーネルモードへの移行にはプロセスの変更は含まれないため、そうです。これはすべて、コンテキストスイッチなしで行われます(カーネルによってカウントされます)。
1&2。いいえ、ユーザープログラムは単にジャンプ命令を使用してカーネルメモリに入ることができません。そうすることは許可されていません。 CPUは、そのようなジャンプを成功させるために「カーネルビット」を自動的に設定しません...(一部のCPUにはそのような機能があるかもしれませんが、安全なLinuxポートはこの機能を無効にします)
...実際には、許可されていない方法でページにアクセスしているため、カーネルに入ります:-)。これは制御された方法で入力され、システムコールと非常によく似ていますが、「ページフォールト」と呼ばれます。 CPUは、カーネルへのアクセスの詳細を提供します。あなたが説明するアクセスのタイプでは、カーネルはそれをあなたのプログラムのエラーとして扱います:-)。それはあなたのプログラム(SIGSEGV)に致命的な信号を送ります。