モデムおよび、モデムに対して用いる getty に関しては、Modem-HOWTO の トラブルシューティングの章をご覧ください。
端末が数個だけならばテスタ(電圧計として使います)があれば十分でしょ うが、シリアルポートの配線を調べるための簡単な特殊器具もあります。その 中には「中継コネクタ(breakout)」と呼ばれるものがあります。 「breakout」という言葉は、導線をケーブルから取り出すといった意味です。 このような小物には 2 つコネクタが付いており、シリアルケーブルを繋ぐよ うになっています。電圧計を繋ぐ端子がついているものもあります。特定の モデム制御線がオンになっていると点灯する LED ランプがついているものもあ ります。任意の線と線を接続できるようにジャンパがついているものもありま す。スイッチがついているものもあります。
Radio Shack 等の電器屋で「RS-232 Troubleshooter」つまり 「RS-232 結線テスタ」を売っています(1998 年)。これは TD, RD, RTS, CTS, DTR, DSR をチェックします。緑のランプはオン(+12 V)を表し、赤のランプは オフ(-12 V)を表します。この店では「RS-232 シリアルジャンパボックス」と いう、接続ピンを自由に選べる装置も売っています。
どんな電圧計やテスタ(10 ドルで売られているような安物)でもうまく使え るはずです。これ以外の確認方法はトリッキーになります。抵抗を直列に繋い で LED にかかる電圧を下げない限り、LED を使ってはいけません。 20 mA の LED では 470Ω の抵抗を使ってください(ただし全ての LED が 20 mA とは限りません)。LED は決まった極性でしか光らないので、+ と - の電 圧を調べることができます。自動的に回路を検査するこのような小物を誰か作 りませんか? 論理プローブを使おうとすると、これを壊してしまうかもしれま せん。というのも、TTL が想定している電圧はたったの 5 V だからです。12 V の白熱電球を使うのはやめた方がいいでしょう。電球では極性はわかりませ んし、UART の出力電流は限られているため、たぶん光ることさえないでしょ う。
メスのコネクタの電圧を測定するには、曲げたペーパークリップを調べたい穴 に差し込むとよいでしょう。ペーパークリップの直径はピンよりも小さいはず なので、接触部を傷つけることはありませんん。接続するためには、ワニ口ク リップ(等)でペーパークリップを挟みましょう。
テストに使える器具が無く、かつ電気ショックを受ける(感電さえする)覚 悟があれば、最後の手段として電圧を味わうという方法もあります。調べる導 線をなめる前には、高圧電流が流れていないことを確かめましょう。両方の導 線に(同時に)手で触れ、ショックを受けるかどうかを確認します。ショックを 受けなければ接触部の肌をなめて濡らし、再び導線に触れてみましょう。これ でショックを受ければ、なめてみる気はきっとなくなるでしょう。
12 V を調べるには、指をなめて、その指で調べる導線をつまみます。 そして、別の導線に舌で触れます。舌で触れた導線に正の電圧がかかっていれ ば、はっきりとした味がするでしょう。どんな味がするか前もって知っておき たければ、懐中電灯の電池をなめてみるといいでしょう。
モデム制御線を監視し、その電圧が正(1)であるか負(0)であるかを示す Linux 用のプログラムがいくつかあります。 シリアルポートの監視/診断用のプログラム の章をご覧ください。
BIOS のメニューと出力メッセージを確認しましょう。ISA バス上の PnP シリアルポートの場合には、"pnpdump --dumpregs" を試したり、 Plug-and-Play-HOWTO をご覧になってください。PCI バスの場合には /proc/pci を見てください。setserial を使って探査を行ってもよいでしょう。 探査の節を参照してください。シリアルポー トにデータが何も流れていないようであれば、シリアルポートはあっても割り 込みが間違っているかもしれません。 この上なく遅い: テキストがすごく遅れてゆっくり画面に表示されます の節をご覧ください。
これは割り込みの設定が間違っているか、衝突しているためでしょう。 初めてモデムや端末、プリンタを使おうとしたときに出会うような現象をいく つか示します。場合によっては、入力した文字が何秒も経たないと表示されな いことがあります。入力した最後の文字しか表示されないこともあります。 また、その文字が単に目に見えない<改行>文字で、カーソルが 1 行下 に移動したことしかわからないこともあります。また別の場合としては、 画面にデータはたくさん表示されるのですが、16 文字ごとのかたまりでしか 表示されないこともあります。そして、あるかたまりの次のかたまりが表示さ れるまでには何秒もの長い待ち時間が続きます。 「input overrun(入力オーバーラン)」のエラーメッセージが表示される(ある いはログに残る)こともあります。
詳しい症状とそれが起こる理由については、
割り込みの問題に関する詳しい説明の 節や 割り込みの衝突の節、 割り込みの設定ミスの節を見てください。 プラグ&プレイデバイスがある場合には、Plug-and-Play-HOWTO も見てく ださい。
本当に割り込みの問題かどうかを簡易的に調べるには、"setserial" で IRQ を 0 に設定してください。これにより、ドライバは割り込みではなくポーリ ングを使うようになります。 これで「遅い」問題が解決するようであれば、割り込みの問題が起きています。 しかしポーリングはコンピュータの資源を大量消費するので、ポーリングに頼 らずきちんと割り込みの問題を解決しましょう。
割り込みの衝突を見つけだすのは容易ではないかもしれません。というのも、 Linux は割り込みの衝突を全く許さず、衝突を起こそうとすると /dev/ttySN: Device or resource busy エラー を送ってくるみたいだからです。しかし、Linux がだまされる可能性もありま す。例えば(ジャンパかプラグ&プレイで)ハードウェアには IRQ 5 を設定 しているのに、ドライバには "setserial" で IRQ 3 を設定している場合には、 IRQ 5 が使われていることはドライバにはわかりません。そしてドライバは 何か他のデバイスにも IRQ 5 を使わせようとし、悲惨なことが起こります。 以上のように、このエラーが出た時はハードウェアに実際に設定されている IRQ を Linux が正しく知っていないということです。"setserial" を使った り /proc/interrupts を見たりすることで設定を調べて衝突をチェックしよう としても、明らかになるのは Linux 側の設定だけなので、衝突については全 くわかりません。衝突はそのまま残ります。
こういった場合に行うべき作業は、ジャンパや PnP 設定ソフトウェアを使っ て、ハードウェアに実際に設定されている情報を調べることです。PnP の場合 には、"pnpdump --dumpregs" または "lspci" を実行しましょう。 そして、この結果を Linux 側の設定と比べるのです。
考えられる理由の一つは、シリアルポートを使っているデバイス(モデム や端末、プリンタ)が、あなたが考えているほど速く動作していないことです。
考えられる別の理由は、あなたが使っているシリアルポートが古い (UART 8250, 16450 や初期の 16550)とシリアルドライバが認識していること です。 UART とは何ですか?を参照し、 "setserial -g /dev/ttyS*" を使ってください。その結果として 16550A より 性能がよくない UART が表示されたら、これは多分設定の問題です。 この場合は、"setserial" の設定に問題があれば、これを変更します。 詳しくは setserial とは何か?を見てください。 当然のことですが、実際は古いシリアルポートを使っているのに setserial をだまそうとしても、単に事態が悪化するだけです。
Linux カーネルはシステムの起動時に IRQ の検出は全く行いません。 serial モジュールがロードされた時に、シリアルデバイスの検出が行われる だけです。したがって、カーネルが IRQ に関して行う表示は無視してくださ い。なぜなら、この時点では標準の IRQ を決め打ちしているからです。この ようになっているのは、IRQ 検出は当てにならず、間違うことがあるからです。 しかし setserial が起動スクリプトから実行された場合には、setserial は IRQ を変更し、新しい(そして多分正しい)状態を起動画面に表示します。 間違った IRQ が後で訂正されて画面に表示されなければ、何か問題が起こっ ています。
よって、IRQ 5 に設定されている ttyS2
がある場合であっても、Linux
の起動時には
ttyS02 at 0x03e8 (irq = 4) is a 16550A
と表示されます(古いカーネルでは "ttyS02" のところが "tty02" となります)。
実際に使う IRQ を Linux に知らせるには、setserial
を使わなければ
なりません。
"ls -l /dev/ttyS?" を実行してそのポートのファイルのパーミッション を調べてみましょう。ttyS? の所有者が自分であれば、読み書きのパーミッショ ンとして crw が必要です。最初の桁は c (キャラクタデバイス)です。ポート の所有者でなければ、8 桁目と 9 桁目が rw- でなければなりません。つまり 誰でもそのポートを読み書きできなければなりません。アクセス権限を得る方 法としては、グループパーミッションを持っている「グループ」に所属すると いったもっと複雑なものもあります。
このエラーは、カーネルがサポートしていないために、setserial や stty 等が要求した操作が行えないという意味です。以前は "serial" モジュー ルがロードされてないことが原因の場合が多かったのですが、PnP の登場によ り、このエラーはドライバ(および setserial)が考えているアドレスにモデム (あるいは他のシリアルデバイス)がないことを示すことが多くなりました。こ ういったアドレスにモデムがなければ、そのアドレスに送られた(操作のため の)コマンドは当然ながら処理されません。 シリアルポートのハードウェアの設定は? の節をご覧ください。
"serial" モジュールがロードされていないのに、そのモジュールはさっきロー ドしたと "lsmod" が表示する場合は、モジュールは現在はロードされている けれど、エラーが出た時にはロードされていなかったのかもしれません。多く の場合、モジュールは必要な時に自動的にロードされます(もし見つけること ができれば)。"serial" モジュールを強制的にロードさせるには、 /etc/modules.conf または /etc/modules に記述しておきます。モジュールそ のものは /lib/modules/.../misc/serial.o にあるはずです。
何らかのプログラムがポートを「オープン」する時、ロックファイル が /var/lock/ に作られます。lock ディレクトリのパーミッションが間違っ ていると、ここにロックファイルを作れません。パーミッションが正しいかど うかを確認するには "ls -ld /var/lock" を使います。普通は全員に対して rwx です(rwx が 3 度繰り返されます)。パーミッションが間違っている場合 には、"chmod" コマンドを使って修正します。もちろん、"lock" ディレクト リがなければ、そこにロックファイルを作ることはできません。ロックファイ ルに関する、より詳しい情報については ロックファイルとは何ですか?の節をご覧くだ さい。
このメッセージが出た場合にはおそらく、誰か他の人(あるいは他のプロセ ス)がシリアルポートを使っています。このポートを「使用中」のプロセスを 見つける方法はいくつもあります。一つの方法は、ロックファイル (/var/lock/LCK...)の中身を見ることです。これは、ポートを使っている プロセスの ID のはずです。プロセス ID が 例えば 261 ならば、"ps 261" を実行し、それが何かを調べましょう。そして、そのプロセスが不要であれば、 "kill 261" で優しく kill してもいいでしょう。これで終了しないなら、 "kill -9 261" を実行して強制的に kill してください。ただし、この場合に はロックファイルが消されずに残るので、手で消す必要があるでしょう。 もちろん、261 のようなプロセスが存在しなければ単にロックファイルを消 してかまいません。しかし、ロックファイルが示すプロセス ID (261 等)が 無効であれば、多くの場合そのロックファイルは自動的に削除されるはずです。
``device busy(デバイス使用中)''エラーのありがちな原因は、他のデバイス が既に使っている割り込みをシリアルポートに設定した場合です。シリアル ドライバは setserial(等)が割り当てた割り込みを設定値とし、ハードウェア 側の設定も同じであるものとして動作します。ハードウェア側の設定が違って いると、起こっているかもしれない衝突にドライバが気づくことはないので、 ``device busy'' エラーが出ることはありません。その代わり、エラーメッセー ジが出ないまま動作は 非常に遅くなります。
2 つのデバイスに同じ IRQ を割り当てている場合も、どちらのデバイスも使 われていなければ Linux がエラーを出すことはありません。それぞれのデバ イスが起動すると(初期化が行われると)、ドライバはハードウェア割り込みの 使用許可を Linux に求めます。Linux はどの割り込みが何に割り当てられて いるのかを調べ、要求された割り込みが既に使われていると、この "... busy" エラーを出します。したがって、2 つのデバイスが同じ IRQ を使っ ていても、片方のデバイスしか起動しないのであれば何も問題ありません。 しかし、次に(最初のデバイスを終了させないまま)もう一つのデバイスを起動 しようとすると、"... busy" エラーとなります。もちろん、ハードウェアに 設定されている実際の IRQ に関する情報が間違っているためにドライバが衝 突のことを知らないのであれば、"... busy" エラーは出ません。この場合は 両方の割り込みが同時に使われ、動作が極めて遅くなります。
さて、"setserial" を使おうとしたら "... busy" エラーが起きた時の問題が あります。最悪なことに、"setserial" はポートが使おうとしている IRQ を 教えてくれませんし、この IRQ を変えることもありません。こうなっている 理由は、"setserial" を使ってデバイスを処理することは、そのデバイスを起 動させようとするみたいなものだからです。このデバイスに "setserial" を 使うことはできません。なぜなら、その IRQ (ドライバ側が考えている IRQ) は他のデバイスが使っているからです。こうなっているべきではないのですが、 実際そうなっています。
こうなった場合、何が衝突しているのかをどうやって見つけるのでしょうか? IRQ の設定を調べるには、最後に setserial が設定を行った場所を探すとよ いでしょう(起動時のメッセージを見ましょう)。別の方法としては、 /proc/interrupts を見て衝突している部分を推測することもできます。 その後、衝突していると思われるプロセスを全て終了するか優しく kill して からもう一度 "setserial" を試してください。これを行う代わりに単にリブー トし、起動時に実行される "setserial" が同じ衝突を起こさないことを確か めてもいいでしょう。
modemstat
と statserial
は、モデムの各種信号線(DTR,
CTS など)の現在の状態を表示しますirqtune
を使えば、シリアルポートの割り込みの優先度を上げて
性能を向上させることができますhdparm
もいくらか役に立
つかもしれません