OS上でキーボードを動かすまでの話
CPU実験も無事終わり、余興の余興をやりたいと思い、かねてからの目標であったキーボードドライバを作ろうと思った。
twoproc
VHDL書けないのでtwoprocについて周りの優秀な人たちが教えてくれた資料やアドバイスをまとめる。
- 参考資料を読む
- twoprocで書かれたコードを読む
参考資料
twoprocで書かれたコード
キーボードコントローラ
とりあえず何となく分かったので、次に普及品であるintel 8042キーボードコントローラについて調べた。
ここのサイトが詳しい。
KBC/Intel 8042 - OS Project Wiki
こんな感じになるのかな
PS/2プロトコル
ここのサイトにPS/2の仕様が記載されているので、まとめる。
PS/2は6-pin Mini-DINという規格で、Data,Clockの2本のシリアルバスで双方向通信を行う。
キーボード→コントローラの通信
DataとClockはどちらもHighの状態から始まる。デバイスが情報を送ろうとするとき最初にClockがHighであるかチェックし、もしLowなら中断する。すなわちKBCは送信したい命令がなければClock <= 'H'を送り続けていればよい。
通信は0xxxxxxxxp1の11bitであり、もしKBCが中断させたい場合はstop bitが送られるまでに100マイクロ秒以上Clock <= '0'を送ればよい。
Clockの立ち上がりでDataは次のbitへ5マイクロ秒以内に切り替える。Dataの切り替えからClockの下がりまで5~25マイクロ秒以内でなければならない。つまりfalling_edgeかClock = '0'でDataを読み込めば良い訳だけど、立ち上がるまでの時間すなわち周波数が10~16.7kHzを幅があるので、falling_edgeの方がいいっぽい。
中断されたとき用にキーボードは16byteの出力バッファを持っているらしい。
コントローラ→キーボードの通信
最初にPS/2デバイスは常にClock信号を生成している。もしKBCがデータを送りたいとき、以下の手順に従う。
- 100マイクロ秒以上Clock <= '0'を送る。
- Data <= '0'を送る。
- Clock <= 'H'を送り、「Request-to-send」状態にする。(start bitの送信)
- デバイスがClockを'0'にするのを待つ。
- 送りたいデータのbitにDataを設定する。
- デバイスがClockを'1'にするのを待つ。
- デバイスがClockを'0'にするのを待つ。
- 5-7を残りの7ビットとパリティビットに関して繰り返す。
- Data <= 'H'を送る。(STOP)
- デバイスがData<='0'にするのを待つ。
- デバイスがClock<='0'にするのを待つ。
- デバイスがData<='H'、Clock<='H'にするのを待つ。(ACK)
ClockがLowの時にKBCはデータを変更し、ClockがHighの時にデバイスがDataを受信する。最初のKBCによるClock<='0'からデバイスによるClock<='0'までの間隔は15ミリ秒未満である必要があり、パケットの送信は2ミリ秒以内になされる必要がある。これを超過した場合、または応答を必要とするコマンドをKBCが送って20ミリ秒以上経っても応答がない場合KBCはTimeoutフラグを立てる必要がある。ACKをKBCが受け取ってからデータを処理するまではClock <= '0'にしておいた方がよい。中断するにはACK来るまで(11ビット目まで)にClock<='0'を100マイクロ秒以上送りつづける。
と、ここまで書いたが授業が始まったので続きはまたこんどで