汎用I/Oポート用カーネルドライバ作成中
WindowsのDDKを使って、カーネルモードのI/Oポート用ドライバを作成中です。
ご存知のとおり、WindowsNTや2000、XPは、プログラムから簡単にはI/Oポートにアクセスできない仕組みになっています。
I/Oポートにアクセスするにはカーネルモードのドライバが必要になりますが、ドライバを作ろうとすると、I/Oポートにアクセスする部分はごく僅かなのに、ドライバの初期化だとかいろいろな大変な思いをします。
ところで、どのようなデバイスドライバもI/Oポートにアクセスする部分は、WRITE_PORT_UCHARやREAD_PORT_UCHARといった関数を呼び出しています。
WRITE_PORT_UCHAR関数を使って、プリンタポート(0x378番地)をアクセスしてみると、1.2μ秒かかりました。
#パラレルポートが仮想的なISAバスにつながっている以上、原理的にはこれだけのWAITが必要なのですが、どうやってWAITを発生させているのかわかりません。どういう仕組みなんでしょう。
なお、実際のI/Oアクセスが1μ秒程度なのに、DeviceIOControlやWriteFileといったドライバの呼び出し処理には10μ秒ほどかかってしまうようです。
これでは1バイトごとにDeviceIOControl呼び出しを行うととても時間がかかりますので、I/Oポートを操作する一連の操作手順をまとめた構造体を作り、その構造体を与えることで動作するようにしました。
操作手順データの作成はユーザモードで安全に行い、その実行はカーネルモードで行います。
これで、安全に、無駄な時間のない動作をすることができるようになりました。
次にリリースするMITOUJTAGでは、このドライバが使えるようになるかもしれません。
| 固定リンク
コメント
> #パラレルポートが仮想的なISAバスにつながっている以上、原理的にはこれだけのWAITが必要なのですが、どうやってWAITを発生させているのかわかりません。どういう仕組みなんでしょう。
→そもそもISAバスは16[ビット]/8[MHz]くらいのもので,1クロックが0.125[μsec]です。読み書きには当然複数クロックかかります。なので1.2[μsec]はそれほど大きくないと思います。【改行】
仮想パラレルポートは,インテル用語で言う所のLPC(LowPinCount),あるいはスーパーIOチップ上に居るわけですが,タイミングなどは古いままでPCIやチップセットとのブリッジされているだけと考えるのが良いと思います。そうでないと互換性が保てないと,私は思います。【改行】問題は,LPC側でISAバス的に時間がかったとしても,CPU側は次の仕事をすればいいんじゃないの?という点ですが,これはチップセットのデータシートを読み漁りつつ,各OSがどういう設定でCPUやチップセットを叩いているかを確認しないと明確には分からないと思います。
投稿: ごみためまん | 2005.08.20 11:52
>なお、実際のI/Oアクセスが1μ秒程度なのに、DeviceIOControlやWriteFileといったドライバの呼び出し処理には10μ秒ほどかかってしまうようです。
→
ユーザモードとカーネルモードの遷移にはそれなりに時間がかかるようです。Inside Windows辺りを読めばある程度の答えが得られると思います。【改行】
#古い版を持っているけどまじめに読んでないもので自信なし
【改行】
門外漢ですので全体的に勘違いしているかもしれません。さらに読みづらくて申し訳ないです。
投稿: ごみためまん | 2005.08.20 11:53
コメント有難うございます。
仮想ISAバスにつながっている以上、時間がかかるのは仕方ないのですが、誰がWAITを発生させているかが知りたいのです。
数年前に試したことなので記憶違いがあるかもしれませんが、Linuxではoutb()を実行するとWAITがかからなかったと記憶しています。一方、outb_p()という_pがついた「ポーズ付き」の関数が用意されていて、ソフトウェア的に遅くされていたと思います。Linuxからプリンタポートを叩くときにはoutb_pを使わないとダメだったような記憶があります。
Windowsでは、WRITE_PORT_UCHARを呼んでもアセンブラ命令を直接書いても、約1.2μ秒のWAITがかかります。しかも、アクセスするポートによって若干このWAIT量が変わります。多分、チップセットなんだろうと思います。
投稿: なひたふ | 2005.08.20 12:53
>多分、チップセット →http://www.intel.com/design/chipsets/datashts/307013.htm
あたりのICH7のデータシート(30701301.pdf)などを見ますと,5.5.
LPC
Bridgeのなかに5.5.1.5.SYNCの説明があったりしますが,私にはLPCデバイス側からのウェイト要求を処理するためのものにしか見えません。読解力が足らんですな。http://www.nahitech.com/nahitafu/bbs36.htmlの5のカキコミ拝見しました。outb_p()について長いこと調べておられるんですね。さっきたまたまhttp://hulllug.principalhosting.net/archive/index.php/t-71710.htmlを見つけてチラっと読んでみましたが,Linuxではoutb_pの仕様自体がフラフラしている悪寒を感じました。あと,(Linuxでは)outb_p/inp_pのウェイトはタイマウェイトではなく,シリアライズが主目的のようですね。WindowsではシリアライズIOがデフォルトということでもう少し調べてみます。お邪魔しましたぁ。
投稿: ごみためまん | 2005.08.20 20:17
コメントありがとうございます。
outb_p()については長いこと調べているというよりも、疑問点を解決せずに次へ進んでいるため、ふとしたことから疑問が再燃するといった感じです。シリアライズというヒントをありがとうございます。数年前はLinuxのデバイスドライバの本を読んでも理解できなかったのですが、最近WDMの特訓をしたので今ならLinuxのデバイスドライバも理解できるようになっているかもしれません。機会があれば、もう一度Linuxのoutb_pの謎にチャレンジしてみようと思います。
投稿: なひたふ | 2005.08.22 17:32