LINUX KERNEL DEVELOPMENTを読んでいきます。
- いくつかのライブラリコールはシステムコールには見つからない機能を提供します。そして従って、カーネルにコールするのはワンステップで、それ以外の場合は大きな関数になります。例えば、printf()関数を考えましょう。これはデータのフォーマッティングとバッファリングを提供する。つまり、この働きで1ステップの働きは、コンソールにデータを書き込むためにwrite()を起動します。逆に言えば、いくつかのライブラリコールはカーネルによるものと一対一の関係を保っています。例えば、open()ライブラリ関数はopen()システムコールといくつかわずかな部分を付け加えたものを呼び出します。しかし、strcpy()のような他のCのライブラリコールは、カーネルを全く使っていません。アプリケーションがシステムコールを実行した時、カーネルはアプリケーションを代表して実行します。
まず、printf()はライブラリコールで、write()と言うシステムコールを使っています。逆に、逆に、strcpy()と言うライブラリコールは、システムコールを全く使っていません。で、open()やwrite()などのいくつかのライブラリコールは、システムコール、つまり、カーネルによるものと一対一の関係を保っているようです。また、strcpy()などは、カーネルを使っていないので、システムコールを呼び出さないようです。
- さらに言うと、アプリケーションはシステムコールをカーネルスペースで実行するように指示されます。そして、カーネルはプロセスの文脈で走ります。この関係、アプリケーションがシステムコールを経由してカーネルに呼び出すこと、はアプリケーションを正しく働かせるために根源的なことです。
システムコールがアプリケーションとカーネルとのインターフェースなんですね。アプリケーションがカーネルにやってもらいたいことは、システムコールを経由して命令する。で、システムコールは、デバイスドライバを呼び出すこともあるようです。
- カーネルは、システムのハードウェアも制御する。ほとんど全てのアーキテクチャ、Linuxがサポートする全てのシステムを含むものは、割り込みをサポートする。ハードウェアがシステムとコミュニケーションを取りたい時、ハードウェアは、プロセッサに対する割り込みを発行する。そしてそれはカーネルに対する割り込みになるのである。
割り込み出てきましたね。割り込みはソフトウェアによって起動されるのではなく、ハードウェアによって起動されるんですね。これは初めて学んだことだと思います。プロセッサに対する割り込みはカーネルに対する割り込みにもなる。
- 割り込みは番号によって識別され、カーネルはその番号を使って、割り込みを実行または反応するために、特定の割り込みハンドラを使います。例えば、あなたがタイピングしているように、キーボードコントローラはキーボードバッファに新しいデータが入ったことをシステムに伝えるために、割り込みを発行します。カーネルは、入ってきた割り込みの割り込み番号を記録し、正しい割り込みハンドラを実行します。割り込みハンドラはキーボードのデータを分析し、キーボードコントローラに、さらなるデータを受け入れ可能であることを知らせます。
今僕はキーボードをタイピングしてますが、キーボードをタイプするたびに、割り込みが発生するんですね。で、それには番号が付与され、割り込みハンドラとして、発行される。プロセッサに対する割り込みが先なのか、カーネルに対する割り込みが先なのかは、よくわからないですが、おそらくプロセッサに対する割り込みが先だと思います。
- 同期の機能を提供するため、カーネルは割り込みを無効化することができる。全ての割り込みを無効化することもできるし、特定の割り込みを無効化することもできる。Linuxを含む全てのオペレーティングシステムでは、割り込みハンドラはプロセスの文脈では走らない。その代わりに、Linuxを含むたくさんのOSでは、割り込みハンドラはプロセスに関連づけられた特別な割り込み文脈で走る。それは特別な文脈で、割り込みハンドラに早く反応して、割り込みし、終了するためだけに存在する文脈です。
プロセスの文脈、割り込み文脈というのがどういうものかよくわからないですね。割り込み文脈とは、プロセスの文脈とは別の、割り込みハンドラに素早く反応するためにある文脈みたいです。
文脈というのがどういう意味で使われているのかがイマイチ掴めないですね。
全ての割り込みを無効化することができるようですが、それはどういう状況で使うのかなというのはちょっと気になるところです。
ということで、そろそろ疲れてきたのでこんなもので