SSブログ
ドライバ開発 ブログトップ
前の10件 | 次の10件

HDDのメンテナンス [ドライバ開発]

http://gigazine.net/index.php?/news/comments/20101205_checkdisk
GIGAZINEでナイスなツールを紹介しているのかと思ったが、
単にWindowsに標準で入っているCHKDSKのフロントエンド

というか、Windowsのスキャンディスクが糞すぎる。
何をやってるのかがさっぱりわからないし、困ったときには役に立たないし、ログも出ない。
一方でWindowsの数GBの中にはCHKDSKというコマンドも入っているわけで
MSの右手と左手の意思の疎通の出来なさ具合には本当に辟易する。

ちょっと前に知り合いがXPが起動しないと泣きつかれたのだが、
別のPCにつないで「CHKDSK /F」をしたら復旧した。
それぐらいCHKDSKは優秀なツールなのだが、
Linux使ってるとWindowsのコマンドプロンプトはもうちょっとどうにかならんかといつも思う。
かといってCygwinはなあ・・・ツールだけ欲しいのであって、環境は下手に弄ってほしくない。

パソコンのパーツの中ではHDDが一番壊れやすいので普段から異常に気がつくことが重要。

日常編

・不良セクタの有無
 ゴルゴ13ルール(後述)に従えば、1セクタでも見つかったら新しいHDDを用意して廃棄が正解。
 ではその有無の確認は何でやればいいかというと、CrystalDiskInfoを常駐させる。
・温度
 20度を基準として10度上がるごとに寿命が半分になる。
 経験上、HDDは50度以上での運用は突然死率が高い。
 CrystalDiskInfoで確認できる。
 HDDによってはサイレントモードなどにすることで多少温度を下げることができるが、エアフローを良くするのが一番。ノートは最初から窒息してるのでHDDには劣悪な環境。
・音
 HDDから普段聞き慣れない音がしたら速攻で別のHDDへのバックアップ及び移行をお勧めする。

異常が出たら

・直ちに使用をやめる
 根性で何回も起動できるかチャレンジしてはいけない。止めを刺す事になる。
・データをコピー。
 知り合いに頼んでもいいから、とにかくこれをやる。不良セクタが発見され、復旧されれば大抵は治るが直ちにデータはサルベージする。その際、できればLinuxでデータをコピーする。
 この間SSDの書き込み限界試験のレポートでもあったが、Windowsはどんなときでも書き込みモードでディスクを使おうとするが、死にそうなディスクに書きこもうものなら即死である。
 Linuxでリードオンリーモードでマウントしコピーするのが良い。幸いLiveCDという便利なものがあるので、これを使えば知り合いに頼む必要もない。必要なのはバックアップ用のHDDのみである。
・CHKDSKをかけてみる
 この際、HDD的に不良セクタが見つからなかった場合は、HDD以外の部分で不具合があった可能性が高いので、復旧して問題なければそのまま使用しても構わない。
 逆に不良セクタが見つかったらゴルゴ13ルールで廃棄すること。死んでもいいデータの一時保管用なら問題ない。

ちなみにゴルゴ13ルールとはこれ
http://golgo.blog.ocn.ne.jp/blog13/2006/11/153_b736.html

不発弾回避のためにゴルゴが採用している弾丸のチェックシステム。そのシステムとは100発の弾丸を1ユニットとし80発を試射、不発弾がなければ残り20発を使用するというもの。万一80発中に不発弾があればその100発1ユニットは破棄し、次の1ユニットを試すという。


本来なら、HDDを100個買って~となるが、それだと金がいくらあってもたりないので、弾をセクタにおきかえて、「全セクタのうち1つでも不良セクタがあったら廃棄」をゴルゴ13ルールと勝手に命名している。

Twitterまとめ投稿のテスト(うざいかも) 2010/11/28 [ドライバ開発]


WDK 7リリース [ドライバ開発]

Windows Driver Kit (WDK) 7.0.0
http://www.microsoft.com/japan/whdc/DevTools/WDK/WDKpkg.mspx
8月6日にリリースされてました。

WDFも1.9にバージョンアップ
Vista/2008Server/Windows7に対応しつつも、XPをまだ捨てて無いので
さくっとインストールすべし。

ddkbuild 7.3 R27
http://www.osronline.com/article.cfm?article=43

システムの環境変数にWLHBASEを作成してインストール後のフォルダを指定すればOK。
詳しくはddkbuild.cmdの頭のほうに書いてある

ドライバのテストの自動化はWLKでできる
WLK 1.4
http://www.microsoft.com/japan/whdc/DevTools/WDK/WDKpkg.mspx
デバイスタイプによっては、ごく基本的な試験しかしないので、あまり役に立たないかもしれないが
この試験が通らないことには安定性とは程遠い。


今回のリリースでは、PREfastの出力が、かなり強化されたのは大きい。
知らない人も多いと思うが、
PREfastはWDKについている静的解析ツールで、ソースコードの怪しい部分をチェックしてくれる。

たとえば

int size = 100; BYTE *p = (BYTE *)ExAllocateMemoryWithTag(size,NonPagedPool); ZeroMemory( p,size );


こんな感じでソースコードを書いてあると
pのNULLチェックがしてないよ!
って警告を出してくれる。
ほとんど関係ない場所なら使う前に

int size = 100; BYTE *p = (BYTE *)ExAllocateMemoryWithTag(size,NonPagedPool); ASSERT(p); ZeroMemory( p,size );


とでも書いておけば警告は消える。

でも、一番使えると思ったのは、コールバックなどMSが指定した書式の関数を実装する場合だ。
よくコピペで戻り値を間違えていても警告すら出ないことが多い。
戻り値がVOID型なのにNTSTATUSと書いてしまっていたりとか。
警告どおりに宣言を記述するとそういう間違いを前もって消すことができる。

今は仮想化を使えばOSのリカバリも簡単にできるが
仮想化が使えないドライバの開発も多い。
そういうときに前もってエラーをチェックしておくことで
BSOD率をぐっと下げることができるこういうツールは非常にありがたい。
しかもタダ。

ただ、PREfastはコンパイル時間が異常に長くなるので
普段の実装はPREfast無し。ある程度実装が終ったらPREfastあり。
とするのが良いと思う。

続きを読む


SCSIミニポートとIRP_MJ_DEVICE_CONTROL [ドライバ開発]

SCSI miniportドライバは一般的なWDMドライバではない。Windows自身のScsiClassDriverから呼び出される一部分として機能している。

SCSIMiniportの開発でネックになるのは、WDMドライバ系の本に書いてあるレジストリルーチンなどが使えない。

WDMドライバがユーザーモードアプリケーションとやりとりする場合には以下のようにするのが普通だ

・AddDeviceでIoCreateDeviceおよびIoCreateSymbolicLinkでレガシインターフェイスやデバイスインターフェイスを作成する(\\Device\DeviceDriverNameなど)。
・ユーザーモードアプリケーションで上記に作成したものをCreateFileのファイル名部分に指定して開く
・DeviceIoControl APIを利用してデータを送受信する。
 ドライバがIRP_MJ_READまたはIRP_MJ_WRITEを実装しれていれば、ReadFile/WriteFileなどのファイル操作APIでも代用できる。
・CloseFileでハンドルを閉じて終了

ところが、ミニポートドライバの場合、HW_INITIALIZE構造体に設定するが、上記のような、外部とやりとりするためのインターフェイスがない。

そのため外部から何かを送るときに、うまく受け渡すことができず、結局レジストリで渡すとことにした。
しかし、SCSIミニポートにはレジストリを操作するAPIがないため、好きなときに読んだり、動的に反映させることができずにいた。

ところが、HwInitializeあたりからたどっていたら・・・

SRB_FUNCTION_IO_CONTROL
The request is an I/O control request, originating in a user-mode application with a dedicated HBA. The SRB DataBuffer points to an SRB_IO_CONTROL header followed by the data area. The value in DataBuffer can be used by the driver, regardless of the value of MapBuffers. Only the SRB Function, SrbFlags, TimeOutValue, DataBuffer, and DataTransferLength members are valid, along with the SrbExtension member if the miniport driver requested SRB extensions when it initialized. If a miniport driver controls an application-dedicated HBA so it supports this request, the miniport driver should execute the request and notify the OS-specific port driver when the SRB has completed, using the normal mechanism of calls to ScsiPortNotification with RequestComplete and NextRequest.

ユーザーモードアプリケーションのIOコントロールリクエストが来るとある。

つまりSCSIMINIPORTの場合には、ミニポートドライバ自身がデバイスインターフェイスを作成しなくても、なんらかの方法でIRP_MJ_DEVICE_CONTROLを出せれば、要求を処理できるのであった。

ただ、問題は列挙で、ドライバの場合だと上位のドライバが下位のドライバに対して投げればよいが
アプリケーションからの場合だとSCSIClassDriverが決めた名前経由でアクセスしないとだめだろう。
今回はドライバからのアクセスしか必要がなかったので試してないが、いずれ試してみようと思う。

String buffers and IRQL [ドライバ開発]

String buffers and IRQL
http://blogs.msdn.com/doronh/archive/2006/03/03/543140.aspx

嘘訳
RtlString関数のほとんどはPASSIVE_LEVELでしか使えないと、WDKのドキュメントには書いてある。
これがRtlだけではなくCRTもそうではないのは、いくつか理由がある。

*Rtl関数はPAGEableと宣言されている。そのため関数は自分自身でさえも実行できない。
*UNICODE_STRING内のバッファはスタックベースではないなら普通はPagedPoolから確保される。
*NLSのような文字変換テーブルはPAGEableである

NonPagedPoolからバッファを確保するように作ることによって2つ目の弾丸をovercomeできるだろう。
しかし、そうしたとしてもsurrounding infrastructureのために、まったく助けにならない。
You can overcome the 2nd bullet by making sure your buffer allocations come from NonPagedPool, but that doesn't help you very much because the surrounding infrastructure.

しかし、ちょっと待って欲しい。ここにDISPATCH_LEVEL以上でも動くstrlenとsprintfを使ったサンプルがある。
ドライバの中でもっとも一般的に使われる関数はDbgPrintの機能を実装するのに使われる。

which is invoked like this PRINT(2, ("Number of instances %d\n", DevExt->NumInstances")); and this actually works.
以下のサンプルはPRINT(2, ("Number of instances %d\n", DevExt->NumInstances"));とのようにinvokedされ、そして問題なく動く。なぜだろうか?
なぜならformat stringに%sおよびそれに類するformat specifiersが含まれていないからである。
もし、%sを使おうとすると、aforementioned tableをヒットし、潜在的にpaged out pool(とbugcheck)をヒットすることになる
何が起きるのか? PASSIVE_LEVELより高いIRQLでは、デバッグ出力に文字(%sなど)を渡してはいけない。当然、なぜ高いIRQLで文字列を取り扱う必要があるのか良く考えなければならない。
比較やそれに似た操作はしないことを希望する?。
また、文字を使うところでWPPを使うことも考えたほうがいい。(なぜならWPPは文字列をコピーし、後でユーザーモードで処理するからである)


ところどころうまく訳せなかったが、ドライバ内で文字列を扱うときは、

・ドライバ内部の文字列操作は常にPASSIVEであることを前提にしている
 付随してASSERT(KeGetCurrentIrql()==PASSIVE_LEVEL)としておくのがいいだろう。
・PASSIVEでない場合には、本当にそこで文字列が必要か考えること(操作はしなくてもいいようにするとか、WPP?を使うなど)
・どーしてもRtl関数をPASSIVEより高いIRQLで使いたい場合は、フォーマット文字列に%sなどの文字列さえ使わなければ動いてくれる。

ドライバのサンプルなどで、よく文字列操作関数を自作しているのを見かけたが、DISPATCH_LEVELなどで動くように自作していたんだろう。

続きを読む


WDKリリース [ドライバ開発]

News Flash - Windows Server 2008 R2 WDK has Shipped!
http://blogs.msdn.com/wdkdocs/archive/2008/11/01/news-flash-windows-server-2008-r2-wdk-has-shipped.aspx

KMDFのためのCoInstaller1.7が動かなかったりと、Vistaのだめっぷりの影響かよくわからないgdgdぶりだったら前回のリリースから結構たって、2008のSP1対応という形で最新版がリリースされました。
これにともなって、OSRのDDKBUILDも更新されていましたので要チェック。

WDKにWinDbgがデフォルトで入るようになっていて、Webで公開されているものよりも新しくなっているので、とりあえず試してみることをお勧め。

タダで作るWindowsドライバ開発環境 [ドライバ開発]

VisualStudio 2008 Express Edition
http://www.microsoft.com/japan/msdn/vstudio/express/

WDK 6001
http://www.microsoft.com/japan/whdc/devtools/wdk/WDKpkg.mspx
WDKのドキュメント
http://www.microsoft.com/japan/whdc/DevTools/WDK/WDKdocs.mspx#

ddkbuild.cmd 7.2 Final
http://www.osronline.com/article.cfm?name=ddkbuild_v72.zip&id=43

プロジェクトのコンパイル方法
(1)WDKとドキュメントをインストールする(C:\WinDDK\6001.18001)
(1.1)環境変数WLHBASEにC:\WinDDK\6001.18001を設定する
(2)DDKBUILDを適当な場所c:\winddkなどにコピーしておく
(3)VisualStudioでメイクファイルプロジェクトを作成する
(3.1)引数にc:\winddk\ddkbuild [対象OS] chk [プロジェクトのフルパス] -ceZ -PREFASTと指定する
(3.2)リリースモードのほうはchkの代わりにfreを指定する
以上

その他
・プロジェクトのカレントパス"."を設定してもうまく動いてくれない:-(
・ddkbuildのオプションの詳細は単独でddkbuildを実行すれば教えてくれる。
・sourcesにプログラムデータベースを作るように指定しておくと関数ジャンプができる。
・普通のビルドには-ceZをつけないでおくと、変更したファイルだけのビルドになり、デバッグチームと平行して開発している場合には有効では在るが、VisualStudioほど賢くないので注意が必要。
・-PREFASTはつけておくと、typoを防げる可能性があがるのでつけておいたほうがよい。


おまけ
TortoiseHg
http://sourceforge.net/projects/tortoisehg/
MercurialをWindowsで使えるようにするパッケージ
分散リポジトリを使えるようになるが、まだ概念がよくわかってないので
わかったらまたまとめる。

Vistaでカーネルデバッグ [ドライバ開発]

http://www.microsoft.com/japan/whdc/driver/tips/debug_vista.mspx
Vistaでカーネルデバッグ
今までのようにBoot.iniを直接編集できるわけではないようだ。
BCDEdit.exeを使って行うのだが、管理者権限が要求されるのと、コマンドラインツールなのでお手軽ではない。
1度しか設定しないとはいえこれは面倒だなぁ・・・

--

VMWareの仮想マシン上のOSと通信する
・仮想マシンにシリアルポートを追加する。デフォルトでは「\\.\pipe\com_1」などとなっているはず。
・仮想マシンを起動すると、そのパイプが開かれているはず。
・この段階でカーネルデバッグを起動するが、組み込みのシリアルポートは常に\\.\com1などを開いてしまうのでGUI上からの設定では動かない。そこで、windbgのショートカットを作成し、引数に「com:pipe,port=\\.\pipe\com_1」を追加する。

--

http://gigazine.net/index.php?/news/comments/20080306_mathias_verhasselt/
圧倒的画力のグラフィックを次々と紡ぎ出すコンセプトアーティスト「Mathias Verhasselt」

似たような絵を書ける人はいくらでもいるだろうが、
速度も伴うとなるとなかなかいないのではないだろうか

プログラミングで飯を食うものとして、こういうのを見ると気が引き締まります。





無料デフラグソフトとかいろいろ [ドライバ開発]

http://sourceforge.net/project/showfiles.php?group_id=199532&package_id=236738&release_id=581351

GIGAZINEで紹介されていたオープンソースのデフラグソフト
ソースをちょっと見てみたが、カーネルモードのZwFsFileControlなどのカーネル内部のファイル処理サポート関数で実装されているようで、サイズも非常にコンパクト。OS標準の機能で実装してるだけなので、Diskeeperいらない気がする。しいて言えば、ファイル情報をユーザーモードでDBなどにつっこんで解析したほうが、より高度な処理ができる気はする。

・VC10
現状のインテリセンスは昔からあるBSCファイルを利用しているので、全部オンメモリにおく必要があるとかテンプレートで動作がおかしいとかいろいろあり、また昨今のプロジェクトの肥大化にもついていけていない。
そこでもともとCE用に作っていたSQLServerを組み込んでインテリセンスで利用するようにするようだ。
精度は落ちるらしいが、これは期待したい。特にBoost使った瞬間ろくなことにならないので、激しく期待。

・Boost
むかーし、フルスクラッチで0からソースを書いていたころは自分のライブラリがあったので、「Boostなんて使う必要ねーや、STLあれば十分」なんて思ってたが、手ごろなXML出力機能欲しさに使ってみた。すごくいい・・・。XMLライブラリ使ってしまうといろいろ初期化だのなんだの要求されてだるいが、さくっと出力することができた。C++のデータ構造をXMLにするので、あとは外部のパーサに任せたって割り切れるところはかなりよかった。データ管理の手抜きするのにSharedPtrも使ってみた。コードが簡潔にかけて美しい。
元々あるプロジェクトがメモリの確保と開放ばかりしてるのでBoostPoolを使ってみたが、あっという間に20MBぐらい使ってしまったので、この昨日は無効にしておいた。
パスの処理するのにFilesystemというのもあるらしいからそれを使ってみたいが、元のコードがCなんだよなー・・・

・プラモその後
プラモは知り合いにガンプラ作成ページを教えてもらってそれを見ながら作ってる。
接着一つとってもやり方があって非常に参考になるが面倒。
組み立てる前にいろ塗りをしたいが、塗る前にやることが多すぎて大変。
昔のプラモより最近のほうが簡単らしいので、最近のプラモに切り替えようかと思ったりもするが、ここでくじけてしまうと一生作らない気がするのでまだがんばってみることにする。


Windows Performance Tools Kit, v.4.1.1 (QFE) [ドライバ開発]

http://www.microsoft.com/whdc/system/sysperf/perftools.mspx

パフォーマンスチェックツールらしいがVistaと2008Server以降・・・


前の10件 | 次の10件 ドライバ開発 ブログトップ

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。