2018/10/14

デバイスドライバを書いてみよう02 続・デバイスドライバって何?

前回でデバイスドライバの立ち位置や仕組みをなんとなく説明したが、実際にデバイスドライバを書く場合、知りたいのは

  1. ドライバの基本的な書き方、組み込み方
  2. デバイスとデータをやり取りする方法
  3. アプリケーションとデータをやり取りする方法

ではないだろうか。

1は、その前に概念や仕組みを説明をしたいので、もう少し後に説明する。今回は2のデータのやり取りなどをもう少し突っ込んで説明したい。
また、3の概要はすでに説明したが、その詳細も2に関連するので今回でもう少し具体的に説明したい。




PCの仕組み


今更なんだよ、と言われそうだが、デバイスと関連する大事な概念なのでPCの仕組みを簡単に説明する。
前回の説明でもあったように、PCは主にCPUとメモリで構成される。それぞれを詳細に説明すると

  • CPU
    演算ユニット。レジスタという値を保存できる小さな領域を複数持ち、そのレジスタ同士の足したり引いたりなどの演算を行う。
  • メモリ
    データを保存できるユニット。CPUはメモリからデータをレジスタに読み込んだり、あるいはレジスタの情報をメモリに書き込んだりしている。

というのが、ハードウェア畑以外のエンジニアが持っている認識かと思われる。
CPUが読み込んだり書き込んだりする相手はメモリのみと思われがちだが、実際にはI/Oという対象とも読み書きをしている。
I/OはInput/Outputの略で、簡単に言えばキーボードやマウスなど周辺機器デバイスがこれに当たる。

I/Oデバイスとのデータのやり取り


CPUがメモリに読み書きする際にはアドレスを指定するが、I/Oに読み書きする際にもアドレスを指定する。
アドレスが取りうる範囲のことをアドレス空間と言ったりするが、メモリのアドレス空間とI/Oのアドレス空間があるわけだ。
I/Oのアドレス空間は、マウスはこのアドレス、キーボードはこのアドレスを指定して読み書きする、といった感じで利用するのだが、このI/Oアドレス空間がメモリアドレス空間の中に存在する構成がある。
何のこっちゃ、と思うかもしれないが、これが実現すると、CPUはメモリに読み書きするのと同様の命令でI/Oに情報を送受信できる。
概念図は下記のようになる。



それぞれ「I/OマップドI/O」と「メモリマップドI/O」と呼ばれる。CPUのI/Oの取り扱い仕様によってどの方式かが決まるが、どちらも採用されている場合もある。
近年ではメモリも大きくなっているし、CPUの作りもシンプルになるためかメモリマップドI/Oが採用されていることもかなり多い。
メモリの特定のアドレスにデータを書き込むことでデバイスに情報を送信し、そのアドレスを参照することで対応するデバイスの情報を確認する。



例えば、ゲームのコントローラのボタン1が押されているかは、対応しているデバイスレジスタにマップされているメモリの値を調べればいい。
また、ゲームのコントローラのLEDを光らせたい場合は、対応したアドレスの値を1にすることでマップされたデバイス側のレジスタが1になるが、デバイス側では「そのレジスタが1になるとLEDがONになる」という機能が実装してあるためLEDが光る。

アプリケーションとのデータのやり取り


「アプリケーションからデバイスドライバを操作するにはOSのAPIを呼び出す」と前回説明した。OSのAPIをシステムコールとか呼ぶが、I/O関連のシステムコールに関しても、OSがちょっと特殊なインターフェースを提供している場合が多い。
Linuxではアプリケーションからデバイスを操作するインターフェースとして特殊なファイルを用意している。「デバイススペシャルファイル」と呼ばれる「/dev/」以下のファイルなどがそれに当たる。
また何を言ってるんだと思うかもしれないが、仕組みはこうなる。

  • アプリケーションのプログラムにおいて、操作するデバイスのファイルをopenなどで開き、ファイルデスクリプタを取得する。
  • そのファイルデスクリプタに対してwrite APIやread APIを使用する。
  • デバイスの使用が終わったらcloseなどでファイルデスクリプタを閉じる。

つまり、アプリケーションはファイルの読み書きみたいな操作で、デバイスドライバからデータを読み込んだり送信したりする。
このファイルを介してのシステムコールは、Windowsなど他のOSでも採用されている。


今回は、PC-デバイス間のデータ通信や、アプリケーションからのシステムコールに関して説明した。
五月雨式で分かりづらかったかもしれないが、これでなんとなくデバイスの概要を説明できたかと思う。
次回は実際にドライバを書いていきたい。ただ、このシリーズを書こうと思ったのもRaspberryPiのドライバを書いたからであって、そのOSはRaspbianだったわけで、つまりLinuxのドライバを書いていこうと思う。

0 件のコメント:

コメントを投稿