Linuxのカーネルの開発に関する世界観(IO・入出力)です。
自分の書いたブログ「わたしの名はフレイ」2020/06/26より。
また、Linuxでは端末を用いた入出力が可能である。
端末のデバイスファイルは、多くの場合/dev/tty0が第一の仮想コンソールである。
Linuxにおいては、標準入力、標準出力、標準エラー出力が多くの場合プロセスに与えられるが、このほかにも、open()で開いたファイルやソケットなどにも文字列を入出力できる。
システムコールについては、open(), close(), write(), read()が、ファイルに対しての読み書きとして使える。
ファイルディスクリプタと呼ばれる整数が、それぞれのストリームの識別に使われる。
しかしながら、多くの場合、システムコールを使うよりも、C言語のstdioというライブラリを使った方が高速であり、また便利である。
システムコールに比べて、stdioはバッファリングを行うため、何度も同じデータにアクセスする時の速度が高速になる。
また、システムコールのread()やwrite()は固定長の読み書きを行うが、stdioは文字単位や行単位の読み書きが可能であり、printf()のようなフォーマット出力と呼ばれる便利な仕組みが存在する。
stdioではファイルディスクリプタを生に触るのではなく、FILE型のポインタと呼ばれるラッパーを使う。
自分の書いたブログ「わたしの名はフレイ」2020/06/26より。
このようなカーネルをどのように開発するか、という問題だが、Linuxカーネルは、基本的にシステムコールを待ち受けるだけのイベント駆動なOSである。
よって、Linuxカーネルは自分からは何もしない。
何かの要求があった時にだけ、働くように作られている。
基本的に、システムコールでファイルにじかにアクセスする時は、OSの識別番号であるファイルディスクリプタを使う。stdioで使うFILE型のポインタはファイルディスクリプタのラッパーで、stdioのバッファリング情報などが含まれている。
以下の書籍が参考になります。
(以下は「オペレーティングシステム―設計と理論およびMINIXによる実装」を参考に執筆しました。)
カーネルにおける入出力ソフトウェアの目的は、「デバイスに依存しない」こと。
たとえば、フロッピーディスクとハードディスクでは、データを取り出したり書き換えたりする際に、まったく別の処理と操作が必要となる。
入出力ソフトウェアがあることで、これを共通化できる。同じ操作によって異なるデバイスを操作することができ、そのデバイスが操作できるかどうかはカーネル(入出力ソフトウェア)が対応しているかどうかだけにかかっている。
OSも参照のこと。
I/O関連の用語には以下のようなものがある。
用語 | 説明 |
---|---|
I/Oバス | I/OデバイスとCPUは、I/Oバスによって接続される。 データバス、アドレスバス、コントロールバスがある。 |
I/Oポート | I/OデバイスはI/Oポートを用いてアクセスする。 アセンブリ言語のin, ins, out, outsという命令でアクセス・読み書きができる。 また、I/Oポートには固有のI/Oアドレスがある。 |
I/Oポートのレジスタ | 制御レジスタ、ステータスレジスタ、入力レジスタ、出力レジスタがある。 |
I/Oインターフェース | I/Oポートとデバイスコントローラを繋ぐインターフェースとして働く。 専用I/Oインターフェースと汎用I/Oインターフェースがある。 |
専用I/Oインターフェース | キーボード、グラフィック、ディスク、バスマウス、ネットワークのインターフェース。 |
汎用I/Oインターフェース | パラレルポート、シリアルポート、USB、PCMCIA、SCSIのインターフェース。 |
デバイスコントローラ | デバイスコントローラは、プロセッサから高レベルなデバイス操作命令を受け取り、 より低レベルなデバイス操作処理(たとえば物理的なディスクの操作)を実現する。 |
デバイスファイル | I/OデバイスはUNIXではファイルとして扱われ、デバイスファイルと呼ばれる。 |
I/O共有メモリ | I/Oデバイスとの間で共有されるメモリのこと。 たとえばモニターに画像を表示するためのフレームバッファなど。 |
これらの仕組みを踏まえた上で、I/Oデバイスを操作するソフトウェアレイヤーであるデバイスドライバを書く。デバイスドライバにはブロック型とキャラクタ型がある。
ブロック型デバイスドライバは複雑で、さまざまなI/O機構(バッファリングやディスクキャッシュを含む)が必要となるが、キャラクタ型デバイスドライバはそれに比べれば簡単である。
(以上は詳解 Linuxカーネル 第2版を参考に執筆しました。)
Linuxカーネル(デバイス)やデバイスファイルを参照のこと。
2024.09.19-20
入出力についてはシステムコール・API(1.ファイル・入出力)やC言語(5.入出力)を参照のこと。