OSを自作してみる7 ~キーボード入力2~



今回もキーボード回。。。

※過去回の記事とソースコードは下記から入手できる
https://github.com/Shadow5523/osdev/blob/master/README.md
また、ここで使用するコードはGitHubからダウンロードできる。
https://github.com/Shadow5523/osdev/releases/tag/version0.6.0

前回との変更点は以下の通り。大体キーボード回りを整備した。
・Shift押しながら入力で大文字入力(Caps Lock時は小文字入力)
・Caps Lockの実装
・NumLockの実装
・ScrollLockの実装(当分CUIでやってくのでLEDのみ)
・各種Lock時にLEDが光る
・キーマップを別ファイルに分割

キー配列は前回と同様にUS配列。
Caps LockキーはLinuxやmacOSを基準に採用した。(windowsはデフォルトでShift + Caps LockでCaps LockされるがLinuxやmacOSはCaps LockのみでOK)
このOSを仮想マシンなどで検証している場合、各種Lockキーの入力がホストOS側で拾われてしまい上手く動かない。各仮想マシンソフトウェアでは以下のような動作になる。
キーボードの接続方法はすべてUSB。
・qemu
  Num Lockが何回かボタンを押さないと有効にならない
  Caps LockがWindows側で拾われてしまいちゃんと動作しない
  拡張キーフラグ0xE0が取得できない (qemu設定次第ではできる?)
  LEDは正常に点灯/消灯する
  
・VMWare
  Num Lockの変更はLEDへの設定コマンドでやってるっぽいのでちゃんと実装しなければではうまく動かない
  LEDは正常に点灯/消灯する

実機で検証するとPS/2接続ではないキーボードはLEDが光らない。PS/2エミュレーションはそこまではエミュレートしてくれないようだ。なのでノートPCにUSBキーボードをつなげてCaps Lockキーを押すと、本体側のLEDが点灯する。
 
 
1.include/keyboard.hへ以下を追加する。キーマップ本体は大きさ128のuint8_t配列3つで表す。

また。SET_~_LEDのマクロ定数の所は、実際に0xEDコマンドの後に以下のビットを1をセットすると点灯し0をセットすると消灯する。
ビット0 … Caps_LockのLEDを点灯
ビット1 … Num LockのLEDを点灯
ビット2 … Scroll LockのKEDを点灯

因みに日本語対応キーボードの場合、かな入力モードでLEDを光らせることができる場合がある。その場合はビット4に1をセットする。
 
 
2.続いてキーマップを格納した構造体を記述するファイルを作成する。

.baseの配列が小文字入力時のキーマップ。.shiftの配列はCaps Lock有効時、もしくはShiftキーを押しながら入力したとき大文字入力する為のキーマップ。.numlockはテンキーパッド入力時、もしくはNum Lock有効時に特定のキーが数字入力の変わりのキーになるキーボードがあり、そのためのキーマップ。
 
 
3.keyboard.cを編集する。まずはスキャンコードからデータを取り出しバッファーへ格納する処理を書いていく。

上記の処理はまずスキャンコードを取得しもし0xE0(拡張キーフラグ)であればフラグを有効にする。これはキーパットの’/’のスキャンコードに拡張キーフラグ(0xE0のあとに’/’のスキャンコードが送られてくる)が使用されており、Num Lock無効時、キーパッド側の’/’の入力を受け付けないようにするためフラグをセットする。
その処理のあとにCaps LockキーやNum Lockキー入力時にフラグを有効もしくは無効にセットし、LEDの点灯状態を変化させる。(switch_kb_led関数で操作) その後のバッファーにデータを入力する処理はコードが長くなったので文分割して別の関数の中に放り込んだ。(input_bufdata関数)
 
 
4. 次にキーボードのLEDを点灯したり消灯したりする関数 input_bufdataを記述。

キーボードのステータスレジスタ(0x60)へ0xE0コマンドを送り、LEDの状態を記憶した変数set_ledを書き込む。whileの所はステータスレジスタをポーリングして書き込み準備を整ったのを確認できたらレジスタに書き込みを行っている。ポーリングをせずに連続して書き込むと正常に動作をしない為だ。
 
 
5.バッファーへデータを入力する処理を記述する。

各フラグの状態を確認し、それに合わせたキーマップからデータを取り出しバッファーへ格納していく。
 
 
6.Makefileを編集する。

7.コンパイルでエラー等が無ければOK。VMWareで実行してみて問題なく動作していればOK。見た目は1回目かた全然かわってないなぁ…

Leave a Reply

Your email address will not be published. Required fields are marked *