Personal tools
You are here: Home ブログ 学習経過 キャラクタ型デバイスドライバ
« December 2010 »
Su Mo Tu We Th Fr Sa
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
Recent entries
sysfs tips 02 ohyama 2010-09-09
sysfs tips ohyama 2010-09-02
Haskell で周波数スペクトルを得る ohyama 2010-07-29
Haskell で線形識別関数の学習を行う ohyama 2010-07-19
Haskell で逆行列を求める ohyama 2010-07-16
Recent comments
Re:vim に lisp 機能をつける t.mimori 2010-12-16
Re:Haskell で周波数スペクトルを得る H.OHYAMA 2010-08-01
Re:lkml でお勉強 (その1-1) Hiroyasu OHYAMA 2009-08-21
Re:lkml でお勉強 (その1-1) kosaki 2009-08-20
Re:vim に lisp 機能をつける ohyama 2008-05-08
Categories
学習経過
GNU/Linux
 
Document Actions

キャラクタ型デバイスドライバ

(悲願であった)デバイスドライバが一応の完成をみせたので、書いておく。
今まで、何度か挑んだテーマであったが、知識不足により満足のゆく結果が得られなかった。
今回、sodex さんから頂いた資料(*1)により、大分カーネルとデバイスの関係が自分の中で明瞭となった。なので、再びデバイスドライバの作成を行う。

今回のデバイスドライバは、シンプルであるが、多くのデバイスドライバモデルを無視した実装、つまり、同一バスにおける共有モジュールなどを一切考えていない実装になっている。
実装した範囲において、それぞれカーネル内部でどのような処理を行っているのかを解説する。ソースはこちら。

http://dev.ariel-networks.com/Members/ohyama/stuff/short-tar.gz/download

尚、このデバイスドライバを動作させるにあたり、以下の制限事項が存在する。

・カーネルがパラレルポートドライバをサポートしていない
・パラレルポートの IRQ は 7 番
・パラレルポートとの通信は SPP モード

まずは、I/Oアドレス領域の取得を行っている。
I/Oアドレスは、アドレスラインとデータラインを用いて、入出力を行う点で概念的には RAM へのアクセスと同じであるが、CPU やカーネルにおけるメモリ保護は存在していない(と認識している)。つまり、ここで "取得" と言っているのは、カーネルの resource 構造体における "予約" を行っているにすぎない。予約状況は、/proc/ioports から確認できる。

次に、メジャー番号の動的取得を行っている。
デバイスは、メジャー番号とマイナー番号によって識別される。静的に登録する事ももちろん可能だが、こちらが勝手に決めたメジャー番号が空いている保証は存在しないので、これを動的に取得する。mknod() によってデバイスファイルを作成した時、これらを引数に受け取り、デバイスファイルを作成する(未実装)。

そして次の処理は、キャラクタデバイスの管理構造体である cdev 構造体を初期化する為、cdev_init() を呼び出す。
内部では、cdev オブジェクトの作成、及び kobject の初期化を行っている。 そして、引数で渡された file_operations型 のポインタは、デバイスファイルを作成した場合、ファイルへの読み書きの際にフックされる。具体的には、ファイル書き込み時、vfs_write() において呼び出される。
又、cdev_add() にって対象のデバイスドライバをデバイスドライバモデルにおけるキャラクタ型デバイスに登録される。ここでは、kobj_map() によって、メジャー番号をキーとするハッシュテーブルに登録する。ここでは、メジャー番号毎に、probe 構造体を初期化し、これを kobj_map型 (probe型の配列とロックで定義された構造体) のグローバル変数 cdev_map における probe 配列の対象メジャー番号のエントリのチェーンに追加される。
管理構造体の各エントリである probe 構造体は、衝突されたノード (同じメジャー番号を持つ probe型 オブジェクト) へのポインタ、デバイス番号、範囲、そして cdev型オブジェクト を持つ。

次に、IRQ の予約と、割り込みサービスルーチンの登録を行っている。
request_irq() は、irqaction型 のオブジェクトを作成、初期化し、setup_irq() を呼び出し、指定した IRQ 番号の割り込みディスクリプタを再設定し、request_irq() で作成した irqaction型 のオブジェクトを登録する。
登録されている IRQ の状況は、/proc/interrupts から確認できる。

最後に、マスター割り込みコントローラに対して、IRQ 7 のマスク割り込み許可と、SPPモードで動作するパラレルポートのコントローラに対して割り込み許可を行う。

(*1):パソコンのレガシィI/O活用大全(CQ出版)

 
 
 
・おまけ

パラレルポートコントローラは、ACK 信号の立上りによって、割り込みを発生させる。しかし、実際には反転制御になっているので、~ACK ピンを接地する事で割り込みを発生させる。具体的には、パラレルポートの 10 番ピンがそれに対応しているので、伝導体をパラレルポートの後方 (下位 8 ビットは接地されている) のピンに接続することで、割り込みが発生できる。

さて。今週末は、秋葉原の千石電商で買い物でもをするかな。

Category(s)
学習経過
The URL to Trackback this entry is:
http://dev.ariel-networks.com/Members/ohyama/30ad30e330e930af30bf578b30a430b930e930a4/tbping
Add comment

You can add a comment by filling out the form below. Plain text formatting.

(Required)
(Required)
(Required)
(Required)
(Required)
This helps us prevent automated spamming.
Captcha Image


Copyright(C) 2001 - 2006 Ariel Networks, Inc. All rights reserved.