WDMが美しい
こんにちは、Cleng です。冬の名残のまだ去りやらぬ時候、皆さんいかがお過ごしでしょうか。
突然ですが、皆さん、中国語で「奥数」という言葉の意味はご存知でしょうか。私もつい最近まで知らなかった言葉ですが、「国際数学オリンピック」の略語として使用されているようです。今の中国、特に都市部では、「奥数」の塾がたくさんできて、いい中学校に進学するためにたくさんの小学生が週末に「奥数」の塾に通っています。「奥数」の塾で難しい数学問題の解き方を覚え、地域、市または全国の数学コンテストに挑戦します。上位に入れば、確実にいい学校に入れるようになります。小学生レベルの数学だからたかが知れていると私も思っていましたが、実際いくつかの問題をやってみたら本当に難しかったです。でも、数学の問題って難しければ難しいほど解けたときに達成感を感じ、「数学は美しい」と思うことがありますね。
さて、WDKのBlogですので、数学の話をこれぐらいにして、本題のWindowsのデバイスドライバについてお話したいと思います。
ご存知のように基本的にはカーネルモードドライバは WDM モデルを使っています。このモデルは、Windows NT のドライバモデルに、PnPと電源管理のサポートが追加された形でWindows 2000 でデビューして、そのまま最新バージョンのWindowsでも使用されています。また、PnPと電源管理に関わらないドライバは、Windows NT のドライバモデルをそのまま使用します。Windows NT のドライバモデルの設計が非常に優れていたというのが私の感想です。
WDMドライバはWindowsのカーネルと直接やり取りを行いますので、WDMを理解することは、Windows のカーネルの動きもある程度把握することにもなります。WDMの参考書として、個人的にはWalter Oney著Programming the Microsoft Windows Driver Model, Second Edition をお勧めします。この本のFrist Editionの日本語訳も出版されていますが、やはり英文原著のほうがいいですね。
WDMモデルの習得に当たって以下の項目がポイントになるかなと思います。
. IRP の流れ
. デバイスオブジェクトとデバイススタック
. PnP
. 電源管理
. IRQL
この中に、他のOS/プラットフォームでドライバ作成経験があってこれからWDMを触れる方にとっては、最初IRQLというものになかなか馴染めないかもしれません。IRQLに関する技術文書がたくさんありますので詳細を割愛させていただきますが、IRQLに纏わる落とし穴的なものは以下のようなものがあります。
A. IRQLがDISPATCH_LEVEL以上の場合、ページフォルトを起こしてはいけないし、待ち状態に移行してはいけません。
これが理由で、DISPATCH_LEVEL以上の場合呼び出してはいけない関数がたくさん存在します。WDKのヘルプに各関数のIRQLの制限が記載されていますのでご参照ください。
IRQLを慎重に扱わないと、IRQL_NOT_LESS_OR_EQUALというカッコいい名前のバグチェックになってしまいます。
B. ドライバでのIRQLの操作について、IRQLを上げて、元のレベルに戻すことのみ許されています。
つまり、ドライバがIRQLを元のレベルより低く設定することが許されていません。
AとBは切っても切れない間柄です。Bの制限がなくなると、Aの制限もなくなります。実は、つい最近Aの制限を回避しようとしてIRQLを下げるドライバを見ましたので、注意点としてここに書かせていただきます。皆さん、同じミスをしないように、慎重にIRQLと付き合いましょう。
WDKにはたくさんのドライバのサンプルがあります。中には、src\general\toaster配下の Toasterというドライバ群がありまして、仮想バスと仮想デバイスを制御するドライバのサンプルです。特別なハードウェアがなくても、バスドライバ、ファンクションドライバと各階層のフィルタドライバの動きを確認できるのが、このサンプルの特徴です。本に書かれていることを実際確認してみたいという方は、ぜひToasterサンプルインストールして、いじって見てください。
カーネルモードで動作するモジュールはほとんどのことができてしまうので、一歩間違えるとシステム全体に致命的なダメージを与えてしまいます。WinDbgの使い方も重要ですが、WDMの仕組みを理解するのがもっと重要だと考えています。お時間がありましたら、ぜひWDMの参考書を最初から最後までご覧になって、WDMモデルの美しさを吟味してください。
それでは、また