最も好ましいバグレポートの送り方は、Linux PCMCIA 情報サイトにある HyperNews のメッセージリストを使うことです。この方法なら、現状の問題 (そして、もしあれば修正方法や回避方法)が他の人にも見えるからです。 バグレポートに必須の項目を以下に示します:
uname -rv
'' の実行結果)と
PCMCIA のドライバのバージョン(``cardctl -V
'' の実行結果)/etc/pcmcia
にある起動ファイルや PCMCIA 起動スクリプト
に加えて変更全てPCMCIA モジュールと cardmgr
デーモンはステータスメッセージを
システムログに送ります。システムログは普通、
/var/log/messages
や /usr/adm/messages
といった名前
だと思います。問題を調べるときには、このファイルを最初に見るべきです。
バグレポートを送る時にも、このファイルの内容は必ず入れてください。
システムのメッセージが見つからない場合には、/etc/syslog.conf
を見て、他のクラスのメッセージの出力先を調べてください。
バグレポートを送る前には、最新のドライバを使っていることを必ず確認して ください。既に直したバグのバグレポートを読むのは嬉しくないことでもない のですが、これはあまり有効な時間の使い方ではありませんから。
WWW にアクセスできなければ、直接私宛(
dhinds@pcmcia.sourceforge.org
)
にメールで送ってくださっても構いません。ただし、できればバグレポートは
他の人にも見せられるように、WWW サイトの方に送って欲しいと思っています。
もしカーネル自身がフォールトする(エラーを起す)場合、あなたが問題となる
アドレス、EIP 等から何か意味を読み取れるとしても、レジスタのダンプ情報
しか役に立たないでしょう。最近のバージョンの klogd
はフォールトが
起きたアドレスを、現在のカーネルのシンボルマップに基づいて変換しますが、
フォールトがモジュール内で起こった場合や問題が深刻で klogd
がフォー
ルトの情報をシステムログに書き込めない場合にはこの方法は使えません。
フォールトがカーネル本体で起こっている場合、フォールトが起きたアドレス
は System.map
ファイルに残ります。このファイルは
/System.map
か /boot/System.map
にあると思います。
フォールトがモジュールで起こっている場合には、nm
コマンドを使えば
同じ情報が得られますが、フォールトが起きたアドレスはモジュールがロード
されたアドレスが基準になっています。例えば、カーネルが以下のような
フォールトを起こしたとします:
Unable to handle kernel NULL pointer dereference
current->tss.cr3 = 014c9000, %cr3 = 014c9000
*pde = 00000000
Oops: 0002
CPU: 0
EIP: 0010:[<c2026081>]
EFLAGS: 00010282
フォールトが起きたアドレスは 0xc2026081 です。System.map
を見ると、
このアドレスはカーネルの最後のアドレスを越えているが分かるでしょう。つ
まり、フォールトはカーネルモジュールで起きているのです。どのモジュール
でフォールトが起きたのかを調べるために、``ksyms -m | sort
'' の
出力を調べましょう:
Address Symbol Defined by
c200d000 (35k) [pcmcia_core]
c200d10c register_ss_entry [pcmcia_core]
c200d230 unregister_ss_entry [pcmcia_core]
...
c2026000 (9k) [3c574_cs]
c202a000 (4k) [serial_cs]
したがって 0xc2026081 は 3c574_cs
モジュールの内部で、モジュール
の先頭からのオフセットが 0x0081 です。3c574_cs.o
内部のこのオフセット
位置を参照する方法は今のところありません。カーネルがモジュールをロード
した時、カーネルはモジュールをロードしたアドレスの先頭にヘッダを入れる
ので、実際にモジュールが始まる位置は ksyms
が示すアドレスから
オフセットを取った位置となります。ヘッダの大きさはカーネルのバージョン
ごとに異なります。お使いのカーネルでのヘッダの大きさを調べるには、
シンボルをエクスポートしているモジュール(前述の pcmcia_core
等)を
調べ、シンボルいずれかのアドレスをそのシンボルに対する nm
コマンド
の出力と比較します。この例では、register_ss_entry
は
0xc200d10c - 0xc200d000 = 0x010c というオフセット位置にロードされてい
ます。ここで ``nm pcmcia_core.o
'' は 0x00c0 というオフセットを示
していますから、ヘッダの大きさは 0x010c - 0x00c0 = 0x004c ということに
なります。
3c574_cs
の話に戻ると、フォールトが起きたオフセット位置は 0x0081
なので、これからヘッダの大きさである 0x004c を引くと、モジュールの実際
の位置は 0x0035 となります。ここで ``nm 3c574_cs.o | sort
'' を
実行すると以下のような出力となります:
0000002c d if_names
0000002c t tc574_attach
00000040 d mii_preamble_required
00000041 d dev_info
したがって、フォールトが起きた位置は tc574_attach()
です。
この例では、フォールトでシステム全体が固まることはないので、フォールト
が起きた後に ksyms
を実行することもできます。場合によっては、
モジュールがロードされた位置を間接的に推測するしかないこともあります。
同じ順序で操作すれば、普通はモジュールも同じ順序で同じ位置にロードされ
ます。特定のカードを挿入した時にフォールトが起こる場合は、そのカードを
挿す直前か、代わりに別のカードを挿した時の ksyms
コマンドの出力を
調べましょう。カードを挿す前に手動で insmod
でカードのドライバ
モジュールをロードし、ksyms
コマンドを実行するという方法もありま
す。
背景を詳しく知りたければ ``man insmod
'', ``man ksyms
'',
``man klogd
'' を見てください。カーネルのソースコードに入っている
Documentation/oops-tracing.txt
も関連があります。カーネルの
デバッグ関連のヒントをいくつか紹介します:
klogd
を殺してあると、ほとんどのカーネルメッセージは直接
テキストコンソールに表示されます。この方法は、klogd
からシステム
ログに書き込みができなくなってしまう問題が起きた時に役立ちます。/proc/sys/kernel/printk
が存在するならば、以下の操作で全ての
カーネルメッセージをコンソールに送ることができます:
echo 8 > /proc/sys/kernel/printk
CONFIG_MAGIC_SYSRQ
を有効に
してあると、特別な <Alt><SysRq> というキーの組合せで様々な
緊急用機能を使うことができます。この機能については、カーネルのソースツリー
に入っている Documentation/sysrq.txt
をご覧ください。
PCMCIA モジュールにはコンパイル時のオプションで決まるデバッグ用コード
がたくさん含まれています。 これらのコードの大部分はプリプロセッサの
PCMCIA_DEBUG
という定義で制御されています。もし
PCMCIA_DEBUG
が未定義ならば、デバッグ用のコードはコンパイルさ
れません。もし 0 に定義されていれば、コードはコンパイルされるものの、
利用されません。この数字を大きくすればデバッグメッセージはより細かくな
ります。PCMCIA_DEBUG
を定義してコンパイルした各モジュールには
整数を値に持つ pc_debug
という変数が設定され、この変数でデバッグ
出力の詳しさを制御できます。この変数はモジュールがロードされる際に設定
できるので、再コンパイルを行わなくてもモジュール別にデバッグ出力を制御
することができます。
syslogd
のデフォルトの設定は、カーネルのデバッグメッセージを無視
するようになっているかもしれません。これを確実に記録するためには、
/etc/syslog.conf
を編集して、``kern.debug
'' クラスの
メッセージがどこかに記録されるようにします。詳しくは
``man syslog.conf
'' をご覧ください。
PCMCIA パッケージの debug_tools/
ディレクトリには、デバッグ用
のツールがいくつか入っています。dump_tcic
と
dump_i365
コマンドは PCMCIA コントローラのレジスタを全て
ダンプし、多くのレジスタ情報をデコードします。これらのコントローラ
チップのデータシートを参照できるなら、この情報は非常に有効でしょう。
dump_cis
(バージョン 3.0.2 以前は dump_tuples
)コマンド
は、カードの CIS(Card Information Structure)を出力し、いくつかの重要な
ビットをデコードします。dump_cisreg
コマンドはカードのローカル
な設定レジスタを出力します。
メモリカードドライバである pcmem_cs
も 16 ビット PC カードの
デバッグに役立つことがあります。このドライバはどんな PCMCIA カードに対
しても利用でき、他のドライバと干渉することもありません。このドライバを
使えば、どんなカードの属性メモリや共通メモリにも直接アクセスできます。
CardBus カードの場合も同様で、memory_cb
ドライバはどんな 32 ビッ
トカードに対しても使うことができ、カードのアドレス空間にも直接アクセス
することができます。詳しくはオンラインマニュアルを参照してください。
バージョン 2.1.103 以降のカーネルでは、PCMCIA パッケージはステータス情報
のツリーを /proc/bus/pccard
ディレクトリ以下に作り
ます。この情報の多くは、PCMCIA ホストコントローラのデータシートを使わ
ないと意味が分かりません。この内容はドライバの設定によりますが、以下の
情報の全てあるいは一部を含んでいると思います:
/proc/bus/pccard/{irq,ioport,memory}
これらのファイルがある場合には、カーネルの通常のリソーステーブルを補う ためのリソースの割り当て情報が書かれています。最近のバージョンの PCMCIA システムは、(設定がしてあれば)追加のリソース情報をプラグ&プ レイ BIOS からできます。
/proc/bus/pccard/drivers
最近のリリースでは、このファイルには現在ロードされている PCMCIA クライ
アントドライバが列挙されています。/proc/modules
と異なり、こ
のファイルはカーネル内に静的にリンクされているかもしれないドライバも列
挙します。
/proc/bus/pccard/*/info
それぞれのソケットについて、ソケットのホストコントローラとその機能を示 します。
/proc/bus/pccard/*/exca
このファイルには、コントローラの ``ExCA'' Intel i82365sl 互換レジスタ セットのダンプが含まれています。
/proc/bus/pccard/*/{pci,cardbus}
CardBus ブリッジについての、ブリッジの PCI 設定空間のダンプと、 ブリッジの CardBus 設定レジスタのダンプが含まれています。
``Linux PCMCIA Programmer's Guide'' がクライアントドライバインタフェース
に関する最善の文書です。最新版は sourceforge.org
の
/pub/pcmcia/doc
ディレクトリにあります。WWW 上では
http://pcmcia.sourceforge.org
から入手できます。
使いたいデバイスが普通の ISA デバイスによく似ていれば、既存の Linux 用 のドライバの一部を流用することもできるでしょう。場合によっては、既存の ドライバを修正してブート後にもデバイスを追加したり外したりできるように するのがもっとも苦労するところです。今あるドライバの中では、メモリカード 用のドライバが、あらゆる種類の汚れ仕事をするのにカーネルの他の部分を利 用しない、唯一の「自己完結した」ドライバです。
多くの場合、新しい種類のカードをサポートする際の最大の障害は、メーカー から技術情報を入手することです。誰に頼めばよいかも分かりにくいですし、 どんな情報が必要かを正確に説明するのも困難です。しかし、一部の例外を除 くと、メーカーからの技術情報無しでドライバを書くのは不可能とは行かない までも非常に困難です。
ドライバがカードサービスシステムとどのように通信するかを説明するために、
多数のコメントを入れたダミーのドライバを用意しています。PCMCIA パッケージ
のソースコードに入っている clients/dummy_cs.c
がそれです。
私は、全ての PCMCIA クライアントドライバを PCMCIA パッケージの一部とし て配布するのは本当は適切でないと考えています。新しいドライバが加わるた びに本家のパッケージも段々メンテナンスしにくくなりますし、ドライバを取 り込むとメンテナンス作業の一部がドライバの作者から私へ移ってくるのも明 らかです。そこで全てのドライバを取り込む代わりに、寄付されたドライバは ケースバイケースの判断で取り込むかどうかを決めています。判断はユーザの 要望やメンテナンス性に基づいて行っています。本家のパッケージに取り込ま なかったドライバについては、私はドライバの作者に以下の方法で配布用のド ライバパッケージを作るようにお願いしています。
ドライバファイルは、PCMCIA のソース配布物で使われているのと同じディレクトリ
配置にしなければなりません。これはドライバを PCMCIA ソースツリーのトップ
ディレクトリで展開できるようにするためです。ドライバには
ソースファイル(./modules/
ディレクトリ内)、
オンラインマニュアル(./man/
ディレクトリ内)、
設定ファイル(./etc/
)が含まれていなければなりません。トップレベル
ディレクトリには README ファイルもなければなりません。
トップレベルディレクトリには makefile が必要で、これは
``make -f ...
all'' でドライバをコンパイルでき、
``make -f ... install
'' で必要なファイルを全てインストールできる
ように設定されていなければなりません。この makefile に .mk
という
拡張子が付いていれば、このファイルはトップレベルの Makefile
から
ターゲット all
と install
について自動的に呼び出されます。
このような makefile の作り方の例を以下に示します:
# Sample Makefile for contributed client driver
FILES = sample_cs.mk README.sample_cs \
modules/sample_cs.c modules/sample_cs.h \
etc/sample etc/sample.opts man/sample_cs.4
all:
$(MAKE) -C modules MODULES=sample_cs.o
install:
$(MAKE) -C modules install-modules MODULES=sample_cs.o
$(MAKE) -C etc install-clients CLIENTS=sample
$(MAKE) -C man install-man4 MAN4=sample_cs.4
dist:
tar czvf sample_cs.tar.gz $(FILES)
この makefile では、バージョン 2.9.10 以降の PCMCIA パッケージで定義さ
れているインストールターゲットを使っています。この makefile には、
ドライバ作者の利便のための ``dist'' ターゲットも入っています。最終的な
パッケージのファイル名にはバージョン番号も入れるとよいでしょう(
sample_cs-1.5.tar.gz
等)。完成品の配布ファイルの内容は以下のよう
になります:
sample_cs.mk
README.sample_cs
modules/sample_cs.c
modules/sample_cs.h
etc/sample
etc/sample.opts
man/sample_cs.4
このファイル配置であれば、寄付されたドライバのパッケージを展開した時に、 実質的に PCMCIA のソースツリーの一部となります。PCMCIA のヘッダファイル やユーザのシステム設定を調べる仕組みの利用、ファイルの依存関係の自動チェック を「通常の」クライアントドライバと同じように行うことができます。
私はこの仕様に準拠しているクライアントドライバを受け取れば、
sourceforge.org
の /pcmcia/contrib
ディレクトリに置きま
す。このディレクトリにある README ファイルに、寄付されたドライバの
展開方法が書いてあります。
クライアントドライバのインタフェースは昔からあまり変わっていませんし、 後方互換性はほぼ保たれています。本家のパッケージのマイナーバージョンが 上がっても普通は更新の必要はないでしょう。ドライバの更新が必要となるよ うな変更があれば、ドライバを寄付してくださった作者の方々にはできるだけ お知らせするようにします。
あなたが作っているディストリビューションのシステム設定ツールを PCMCIA
対応にしようとしているのなら、/etc/pcmcia
にある
*.opts
ファイルを「止め具」として使ってください。これらの
ファイルは、ユーザが新しいバージョンの PCMCIA パッケージのコンパイルと
インストールを行っても変更されません。メインの設定スクリプトを修正する
と、最初からのインストールを行った時にカスタマイズしたスクリプトが黙っ
て上書きされ、設定ツールとの連係が途切れてしまいます。適切なオプション
スクリプトの書き方が分からない場合や、追加の機能が必要な場合は、私に相
談してください。
あなたのディストリビューションとこの文書で説明している PCMCIA パッケージ の相違点を文書化してくだされば、ユーザにとって(そして私にとっても)役立 つでしょう。特に、起動スクリプトと設定スクリプトに関する変更点はぜひ 文書化してください。適切な情報を私まで送っていただければ、 個別ディストリビューションに関する注意 の節に追加させていただきます。
ディストリビューション用に PCMCIA パッケージを作る際には、寄付された ドライバ群は本家の PCMCIA パッケージの一部ではない点を覚えていてくださ い。メンテナンス上の理由により中心となるパッケージのサイズは制限しよう としており、新しいドライバを追加するのは特に需要が高いと思われるときだ けです。その他のドライバについては前の章で説明した通り、本家とは別に配 布しています。本家に統合されているドライバと別配布になっているドライバ の違いにはたいした意味はなく、歴史的経緯もある程度含まれています。また、 品質的な違いがあるわけでは決してありません。