The Linux Serial HOWTO David S.Lawyer dave@lafn.org original by Greg Hankins v2.07 May 2000 The Linux Japanese FAQ Project v2.07j, May 2000 この文書は、シリアルポートの機能のうち、Modem-HOWTO, PPP-HOWTO, Serial-Programming-HOWTO, Text-Terminal-HOWTO で扱われていない範囲を説 明します。マルチポートシリアルカードに関する情報も紹介します。シリアル ポートに関して他の文書より詳しく書いてあるので、問題がシリアルポートそ のものにある場合は、これを読むのが一番でしょう。モデム、PPP (電話回線 でインターネットにアクセスするために使います)、テキスト端末を扱ってい る場合には、それぞれに対応する HOWTO 文書を先にご覧ください。 ______________________________________________________________________ 目次 1. はじめに 1.1 著作権、免責事項、クレジット 1.1.1 著作権 1.1.2 免責事項 1.1.3 商標 1.1.4 クレジット 1.2 リリースノート 1.3 この HOWTO の最新版について 1.4 シリアルポート関連の他の HOWTO 文書 1.5 フィードバック 1.6 シリアルポートとは何か? 2. ハードウェアによるバイトデータの転送の仕方 2.1 送信 2.2 受信 2.3 シリアルポートの大きなバッファ 3. シリアルポートの基礎 3.1 シリアルポートとは何か? 3.1.1 シリアル入門 3.1.2 ピンと配線 3.1.3 RS-232 や EIA-232 等 3.2 I/O アドレスと IRQ 3.3 名前: ttyS0, ttyS1 等 3.4 割り込み 3.5 データフロー (速度) 3.6 フロー制御 3.6.1 フロー制御の例 3.6.2 フロー制御がない時の症状 3.6.3 ハードウェアフロー制御対ソフトウェアフロー制御 3.7 データフローのパスとバッファ 3.8 複雑なフロー制御の例 3.9 シリアル操作ソフトウェア: デバイスドライバモジュール 4. シリアルポートは時代遅れなのか? 4.1 はじめに 4.2 低速で距離も短い EIA-232 ケーブル 4.3 コンピュータへのインタフェースの非効率さ 5. マルチポートシリアルボード/カード/アダプタ 5.1 マルチポートシリアル入門 5.2 /dev ディレクトリでの「デバイス」の作成 5.3 PC 標準のシリアルカード 5.4 ダムマルチポートシリアルボード (標準の UART チップが載っているもの) 5.5 インテリジェントマルチポートシリアルボード 5.6 未対応のマルチポートボード 6. シリアルポートの設定 6.1 PCI バスへの対応は進行中です 6.2 設定の概要 6.3 低レベル設定に関するありふれた間違い 6.4 I/O アドレスと IRQ: 起動時のメッセージ 6.5 シリアルポートの現在の I/O アドレスと IRQ の設定は? 6.5.1 デバイスドライバの設定は? 6.5.2 シリアルポートのハードウェアの設定は? 6.5.3 PnP シリアルポートのハードウェアの設定は? 6.6 シリアルの IRQ の選択 6.6.1 IRQ 0 は IRQ ではない 6.6.2 割り込みの共有とバージョン 2.2 以降のカーネル 6.6.3 どの IRQ を選ぶか? 6.7 アドレスの選択 --ttyS3 と衝突するビデオカード 6.8 I/O アドレスと IRQ のハードウェアへの設定 (主に PnP 向け) 6.8.1 PnP BIOS を使った I/O アドレスと IRQ の設定 6.9 IRQ と I/O アドレスを setserial に与える 6.10 高レベルの設定: stty など 6.10.1 フロー制御の設定: ハードウェアフロー制御がベストです 7. シリアルポートデバイス: /dev/ttyS2 等 7.1 シリアルポートデバイスの名前と番号 7.2 ttySN から /dev/modem にリンクを張るべきかどうか 7.3 マルチポートボードに関する注意 7.4 /dev ディレクトリにおけるデバイスの作成方法 8. 知っておくとよい便利なプログラム 8.1 シリアルポートの監視/診断用のプログラム 8.2 割り込みの優先度の変更 8.3 setserial とは何か? 8.3.1 はじめに 8.3.2 探査 8.3.3 起動時の設定 8.3.4 設定スクリプト/ファイル 8.3.5 スクリプトの編集 (バージョン 2.15 以降ではたぶん使いません) 8.3.6 /etc/serial.conf を用いる新しい設定方法 8.3.7 IRQ 8.4 stty 8.4.1 はじめに 8.4.2 「別の」端末に対しての stty の使用 8.4.2.1 リダイレクションを使う古い方法 8.4.3 端末の 2 つのインタフェース 8.4.4 どこに stty コマンドを置くか? 8.5 isapnp とは何か? 9. 速度 (フローレート) 9.1 十分に速い速度が設定できません 9.1.1 ハードウェアに速度を設定する方法: 除数と baud_base 値 9.1.2 速度設定に関する問題の回避 9.1.3 水晶発振器の周波数はボーレートではありません 9.2 シリアルのスループットの向上 10. ロックして他で使えないようにする 10.1 はじめに 10.2 ロックファイル 10.3 デバイスファイルの所有者、グループ、パーミッションの変更 11. 通信プログラムとユーティリティ 11.1 ソフトウェアの一覧 11.2 kermit と zmodem 12. シリアルに関するちょっとしたテクニックなど 12.1 ラインドライバ 12.2 欠陥品として知られているハードウェア 12.2.1 特定のビデオボードで起こる I/O アドレスの衝突を回避する方法 12.2.2 AMD Elan SC400 CPU (PC-on-a-chip) での問題 13. トラブルシューティング 13.1 シリアルの電気的な診断を行う道具 13.1.1 中継コネクタ等の小物 13.1.2 電圧の測定 13.1.3 電圧を味わってみる 13.2 シリアルポートの監視と診断 13.3 以下の節は Serial-HOWTO にも Modem-HOWTO にもあります: 13.4 物理的にはシリアルポートがあるのに、検出されません 13.5 この上なく遅い: テキストがすごく遅れてゆっくり画面に表示されます 13.6 なぜか遅い: あと 2、3 倍は速いはずなのですが 13.7 システム起動時の画面で、シリアルポートの IRQ が間違って表示されます 13.8 "Cannot open /dev/ttyS?: Permission denied" というエラーが出ます 13.9 ttyS? について "Operation not supported by device" というエラーが出る 13.10 "Cannot create lockfile. Sorry" (エラーメッセージ) 13.11 "Device /dev/ttyS? is locked." (デバイス /dev/ttyS? がロックされています) 13.12 "/dev/ttyS?: Device or resource busy" 13.13 トラブル対処のためのツール 14. 割り込みの問題に関する詳しい説明 14.1 割り込みの問題の種類 14.2 割り込みの誤設定や衝突で起こる症状 14.3 割り込みの設定ミス 14.4 割り込みの衝突 14.5 割り込みの問題の解決 15. UART とは何ですか? 性能にどのような影響を与えるのでしょうか? 15.1 UART 入門 15.2 2 種類の UART 15.3 FIFO 15.4 UART のモデル番号 16. ピン配置と信号 16.1 ピン配置 16.2 信号は決まった意味を持っていないことがあります 16.3 シリアルポート間のケーブル接続 16.4 RTS/CTS と DTR/DSR のフロー制御 16.4.1 DTR と DSR のピン 16.5 ポートのオープンを禁止する方法 17. 電圧の波形 17.1 ビット 1 つを表す電圧 17.2 バイトデータを表す電圧シーケンス 17.3 パリティ検査 17.4 バイトデータの構成 (フレーム分割) 17.5 「非同期」通信で同期を行う方法 18. その他のシリアルデバイス (非同期 EIA-232 以外のもの) 18.1 EIA-232 の後継 18.2 EIA-422-A (平衡型) と EIA-423-A (非平衡型) 18.3 EIA-485 18.4 EIA-530 18.5 EIA-612/613 18.6 汎用シリアルバス (Universal Serial Bus, USB) 18.7 同期通信と同期性 18.7.1 非同期と同期の定義 18.7.2 同期通信 19. 他の情報源 19.1 書籍 19.2 シリアルポート用ソフトウェア 19.3 Linux 向けの文書 19.4 Usenet のニュースグループ: 19.5 シリアルポートに関するメーリングリスト 19.6 インターネット上の情報 20. 日本語訳について ______________________________________________________________________ 1. はじめに この文書は、シリアルポートとマルチポートシリアルカードについての基本的 な情報を扱っています。モデムやテキスト端末に固有の情報は、 Modem-HOWTO と Text-Terminal-HOWTO に移動させました。getty (ログイン処理等を実行す るプログラム)に関する情報もこれらの HOWTO に移動させました。というの も、mgetty と uugetty はモデムと組み合わせて使うことが多く、agetty は テキスト端末と組み合わせて使われることが多いからです。モデムやテキスト 端末、プリンタを扱う場合には、この HOWTO を調べる必要はないでしょう。 しかし、シリアルポートを別のデバイスと組み合わせて使う場合、マルチポー トシリアルカードを使う場合、シリアルポートそのものに関する問題を解決す る場合、シリアルポートに関する技術的な情報を詳しく知りたい場合には、他 の HOWTO と共にこの HOWTO を参照する必要があるかもしれません (``関連す る HOWTO 文書'' をご覧ください)。この HOWTO には各種マルチポートシリア ルカードに関する情報を載せています。というのも、これはモデムでもテキス ト端末でも使われることがあるからです。この HOWTO は Intel x86 アーキテ クチャで動作する Linux を対象にしていますが、他のアーキテクチャでも使 えるかもしれません。 1.1. 著作権、免責事項、クレジット 1.1.1. 著作権 Copyright (c) 1993-1997 by Greg Hankins, 1998-2000 by David S. Lawyer Please freely copy and distribute (sell or give away) this document in any format. Forward any corrections and comments to the document maintainer. You may create a derivative work and distribute it provided that you: 1. Send your derivative work (in the most suitable format such as sgml) to the LDP (Linux Documentation Project) or the like for posting on the Internet. If not the LDP, then let the LDP know where it is available. Except for a translation, send a copy to the previous maintainer's url as shown in the latest version. 2. License the derivative work in the spirit of this license or use GPL. Include a copyright notice and at least a pointer to the license used. 3. Give due credit to previous authors and major contributors. If you're considering making a derived work other than a translation, it's requested that you discuss your plans with the current maintainer. 1.1.2. 免責事項 While I haven't intentionally tried to mislead you, there are likely a number of errors in this document. Please let me know about them. Since this is free documentation, it should be obvious that I cannot be held legally responsible for any errors. 1.1.3. 商標 Any brand names (starts with a capital letter) should be assumed to be a trademark). Such trademarks belong to their respective owners. 1.1.4. クレジット オリジナルの Serial-HOWTO の大部分は Greg Hankins さん gregh@cc.gatech.edu が書きました。 Greg さんはまた、他の方が提供した文 章の書き直しを文体や文章の流れの繋がりを保つために行っています。彼曰く 「貢献してくれた方々、意見をくださった方々の全てに感謝します。それぞれ の名前を挙げると長くなりすぎるので省略します(100 人を超えています)。シ リアルドライバについての質問に答えてくださった Ted Ts'o には特に感謝し ます」ということです。バージョン 2.00 のうち約半分は Greg Hankins さん の HOWTO の内容を引き継ぎ、残りの部分は David Lawyer が新たに書きまし た。Ted Ts'o も協力を続けてくれています。 1.2. リリースノート 2.00 はは大幅な改訂であり、古い Serial-HOWTO にあった端末とモデムに関 する情報はなくなりました。これらの情報は以下の文書に移動しています: o Text-Terminal-HOWTO o Modem-HOWTO 2.01: Modem-HOWTO などからプラグ&プレイに関する情報を追加しました。 setserial と stty の情報を更新しました。筆者はマルチポートカードに関す る全ての情報が最新かどうかをまだチェックしていません。この HOWTO 文書 は色々な情報源からの情報を集めて作ったという性質上、統一性に欠けている 部分があります。この点は将来出すバージョンで改善するかもしれません。 1.3. この HOWTO の最新版について Serial-HOWTO の最新版は LDP とそのミラーサイトで閲覧・入手できます。ミ ラーサイトのリストは にあり ます。文書は色々な形式で入手できます。最新版の日付を確認したいだけなら を見て、現在のバ ージョン(v2.07, May 2000)と比べてください。このバージョンの新しい点 は、ロッキングの方法、UART プロトコルに関する情報の整理、スティッキー パリティについてです。 1.4. シリアルポート関連の他の HOWTO 文書 モデム、テキスト端末、一部のプリンタや他の周辺機器はしばしばシリアルポ ートを使います。先に説明したミラーサイトのうち、最も近いサイトから以下 の HOWTO を入手してください。 o Modem-HOWTO モデムのインストールと設定について o Printing-HOWTO シリアルプリンタの使用に関する情報 o Serial-Programming-HOWTO シリアルポートの読み書きや状態の確認/設定 を行う C 言語のプログラム(またはその一部)を書くための参考情報です。 もうすぐ新しいバージョンが出ます。 o Text-Terminal-HOWTO テキスト端末の動作、インストール・設定・修復の 方法について 1.5. フィードバック 質問、意見、提案、追加の情報は筆者に送ってください。筆者は、読者の皆さ んがこの HOWTO についてどう思っているかを大変知りたいと思っています。 筆者は改善点を常に探しています! 理解できなかったところや、はっきりしな い部分はちゃんと筆者に教えてください。筆者に連絡するには (David Lawyer) までメールを送ってください。 1.6. シリアルポートとは何か? (新しい USB ポートや HSSI ポートでない)従来のシリアルポートは、非常に 古い I/O ポートです。シリアルポートはほとんど全ての PC に付いていま す。ですが 1998 年半ば以降の Macintosh (色付きのケースのもの)には USB ポートしかついていません。最も一般的な規格は RS-232 (EIA-232 とも呼ば れます)です。シリアルポートのコネクタは、PC の裏に9 ピンのコネクタ(25 ピンの場合もあります)が 1 つまたは 2 つ付いている形でよく見られます。 しかし、シリアルポートはそれだけのものではありません。シリアルポートに は、EIA-232 規格に準拠する信号を生成しなければならない関連電子技術も含 まれます。``電圧の波形'' の章を見てください。あるピンはデータのバイト 列を送るために使い、別のピンはバイト列を受け取るために使います。信号が 共通に使う接地電圧のピンもあります。他の「便利な」ピンは主に、「オフ」 を表す負の定常電圧と「オン」を表す正の定常電圧を使って信号を表すために 使います。 UART (Universal Asynchronous Receiver-Transmitter) チップがほとんどの 処理を行います。最近は普通、このチップの機能は別のチップに組み込まれて います。「``UART とは何ですか?''」を参照してください。UART は時間が経 つにつれ改良されており、現在は古いモデル(数年前のモデル)は時代遅れに なっています。 シリアルポートは元々はモデムを接続するために設計されたのですが、マウス やテキスト端末、ある種のプリンタ等の色々なデバイスをコンピュータに接続 するためにも使われています。これらのデバイスは、適切なケーブルを使って シリアルポートに繋ぐだけです。内蔵モデムの多くは組み込みのシリアルポー トを持っているので、内蔵モデムを PC に追加すると、別のシリアルポートが PC に加わったように見えます。 2. ハードウェアによるバイトデータの転送の仕方 以下はこの話題についての入門的な解説ですが、もっと進んだ内容については ``FIFO'' を見てください。 2.1. 送信 送信(transmitting)とは、シリアルポートを通じてコンピュータからバイト列 を送ることです。一旦、送信を理解できれば、受信は同じようなものなので理 解するのは容易です。ここで最初に示す例は極端に簡略化したものです。もっ と詳しい説明を後で追加します。コンピュータが(外部ケーブルに繋がってい る)シリアルポートから 1 バイトのデータを送ろうとする時、CPU はコンピュ ータ内部のバス上にあるそのデータをシリアルポートの I/O アドレスに送り ます。シリアルポートはそのデータを受け取り、シリアルケーブルの端子の送 信ピンを使ってこれを 1 ビットずつ送ります(シリアルビットストリーム)。 あるビット(とバイト)が電気的にはどう見えるのかについては、``電圧の波 形''の章をご覧ください。 上記の説明をもう少し詳しくして(まだ完全には程遠いものですが)繰り返しま す。シリアルポートで行われる処理のほとんどは UART (または同等のもの)が 行います。1 バイトのデータを転送するために、シリアルデバイスドライバプ ログラム(CPU 上で動作)はシリアルポートの I/O アドレスに 1 バイトを送り ます。このデータはシリアルポートの「送信シフトレジスタ」(大きさが 1 バ イト)に入ります。このシフトレジスタでは、このバイトデータから 1 ビット ずつ取り出され、1 ビットずつシリアル線に送られます。そして最後のビット が送信され、シフトレジスタが送るための別のバイトを必要とするようになる と、UART は別のバイトデータを送るよう CPU に求めるだけで済みます。これ なら単純な話ですが、CPU がバイトデータを即座に取得することができないた めに遅延が生じるかもしれません。なにしろ CPU はシリアルポートの処理以 外にも作業をこなしているのが普通です。 このような遅延をなくす方法は、シフトレジスタがバイトデータを必要とする 前に CPU がバイトデータを取得して、これをシリアルポートの(ハードウェ ア) バッファに格納することです。こうしておけば、シフトレジスタがバイト データを送り出してしまって次に送るバイトデータが即座に必要になった時に は、シリアルポートのハードウェアは自分のバッファに入っている次のバイト データをシフトレジスタに転送するだけです。新しいバイトデータを取得する ために CPU を呼ぶ必要はありません。 シリアルポートのバッファのサイズは元々 1 バイトしかありませんでした が、現在は普通 16 バイトです(高価なシリアルポートにはもっとあります)。 しかしそれでも、シフトレジスタが転送するデータを必要とした時に必ずバッ ファにデータがあるように、このバッファに十分なバイトデータを与え続ける という問題が残っています(送るデータがもう残っていない場合は除きます)。 これは割り込みを使って CPU と連絡することで行います。 まずはバッファが 1 バイトの古い方式のシリアルポートについて説明しま す。というのも、バッファが 16 バイトのものも同じように動作するからで す( ただし動作はより複雑です)。シフトレジスタがバイトデータをバッファ から取り出し、バッファが他のバイトデータを必要とすると、コンピュータの バス上にある専用の配線の電圧を上げることにより、CPU に割り込みが送られ ます。CPU が非常に重要な処理をしていなければ、CPU が実行中の処理は割り 込みにより強制的に中断され、シリアルポートのバッファに別のバイトデータ を与えるためのプログラムが実行されます。このバッファの目的は、シリアル ポートのケーブルから送り出されるバイトデータが途切れないように、追加の バイトデータが(送られるのを待って)ハードウェア内のキューに入った状態を 保つことです。 いったん CPU に割り込みがかかると、CPU は誰が割り込みをかけたかを知り ます。なぜなら、各シリアルポートについて専用の割り込み線があるからで す(ただし割り込みの共有をしていない場合)。それから CPU はシリアルデバ イスドライバを動作させます。ドライバは I/O アドレスにあるレジスタを チェックし、何が起きたのかを調べます。そして、シリアルポートの送信バッ ファが空になり、追加のバイトデータを待っていることを知ります。したがっ て、送るべきバイトデータがもっとあれば、CPU は次のバイトデータをシリア ルポートの I/O アドレスに送ります。このバイトは、前のバイトがまだ送信 シフトレジスタ内にあり、1 ビットずつ送られている間に届かなくてはなりま せん。 復習すると、1 バイトがシリアルポートの送信線へ完全に送り出されると、シ フトレジスタは空になり、以下の 3 つの動作がほとんど同時に起こります: 1. 次のバイトが送信バッファから送信シフトレジスタに入れられます。 2. この新しいバイトの(1 ビットずつの)送信が始まります。 3. 次の割り込みが発行され、たった今、空になった送信バッファへ次のバイ トを送るよう、デバイスドライバに指示します。 このように、シリアルポートは割り込み駆動(interrupt driven)であると言え ます。シリアルポートが割り込みを発行する度に、CPU は次のバイトを送りま す。 CPU が 1 バイトを送信バッファに送ると、次の割り込みを受け取るま で、CPU は他の処理を自由に行うことができます。シリアルポートはユー ザ(あるいはアプリケーションプログラム)が選択した固定の速度でビット列を 送信します。この速度はボーレートと呼ばれることもあります。シリアルポー トはバイトごとに追加のビット(スタートビット、ストップビット、場合に よってはパリティビットも)も付け加えるので、多くの場合、1 バイトごとに 10 ビットのデータが送られます。したがって、通信レート(速度とも言われま す) 19,200 ビット/秒(bps, bit per second)は 1,920 バイト/秒(1,920 割り 込み/秒)ということになります。 この処理を全て行うことは CPU にとっても重い負担です。これは色々な理由 から言えます。まずは、32 ビット(64 ビットのことだってあります)のバス上 で一回に 1 バイト(8 ビット)のデータしか送らないので、バス幅をあまり有 効に使っているとは言えません。また、割り込みを送る度に大きなオーバー ヘッドが生じます。割り込みを受け取った場合でも、デバイスドライバに分か ることは何かがシリアルポートで割り込みを起こしたことだけであり、文字が 送られたことが理由であることまでは分かりません。何が起こったかを調べる には、デバイスドライバは色々なチェックを行わなければなりません。同じ割 り込みが起こっても、文字を受け取ったのかもしれませんし、制御線の状態が 変化したのかもしれません。 重要な解決方法の一つは、シリアルポートのバッファの大きさを 1 バイトか ら 16 バイトに増やすことでした。つまり、CPU は割り込みを受け取ると、シ リアルポートに 16 バイトまでのデータを新たに送ることができます。これに より割り込みの発行は減りますが、太いバスにもかかわらず 1 バイトずつし かデータを送れない問題はそのままです。16 バイトのバッファは実際には FIFO (First In First Out, 先入れ先出し)のキューであり、よく FIFO と呼 ばれます。 FIFO の詳細については ``FIFO'' をご覧ください。これまでの説 明も一部繰り返してあります。 2.2. 受信 シリアルポートによるバイト列の受信は送信とほぼ同じで、方向が逆になって いるだけです。受信も割り込み駆動です。受信バッファを 1 バイトしか持た ない古い型のシリアルポートでは、外部ケーブルから 1 バイトのデータ全体 を受け取ると、このデータは(大きさが 1 バイトである)受信バッファに入り ます。するとシリアルポートは CPU に割り込みをかけてそのデータを取り込 ませ、現在受信中の次のデータを格納できる場所が空くようにします。16 バ イトのバッファを持っている新しいシリアルポートの場合は、この(バイトデ ータを取得するための) 割り込みはバッファに 14 バイトのデータが蓄積した 時点で発行されます。すると CPU は現在の処理を一旦止め、14 から 16 バイ トのデータをシリアルポートから取り出します。14 番目のバイトが受け取ら れた時に送られた割り込みに対し、これが起きてからさらに 2 つのバイトデ ータが届くと、受け取るべきバイトの個数は 16 バイトになるかもしれませ ん。しかし(2 バイトではなく) 3 バイト届いてしまうと、16 バイトのバッ ファは溢れてしまいます。 14 バイト未満のデータを取り込むことも、そのよ うに設定することやタイムアウトによりできます。詳しくは ``FIFO'' を見て ください。 2.3. シリアルポートの大きなバッファ 今まではシリアルポートが持っている 16 バイトの小さいハードウェアバッ ファについて説明しましたが、メインメモリにはもっと大きなバッファもあり ます。CPU はいくつかのバイトデータをハードウェアの受信バッファから取り 込むと、これらのデータをメインメモリ中のずっと大きな(例えば 8K バイト の)バッファに入れます。したがって、シリアルポートからデータを受け取る プログラムは、この大きなバッファから (プログラム中で "read" 文を用い て)データを取り出します。送信するデータについても同じことが言えま す。CPU がデータをいくらか送る必要がある場合、 CPU はメインメモリにあ る大きい(8K バイトの)送信バッファからデータを取り出し、ハードウェアが 持つ 16 バイトの小さな送信バッファに入れます。 3. シリアルポートの基礎 シリアルポートを使うだけなら基礎を理解する必要はありませんが、基礎を理 解しておけば、問題が起きた際に原因を特定する役に立つかもしれません。こ の章は新しい話題について述べるだけでなく、前の章(``ハードウェアによる バイトデータの転送の仕方'' の内容の一部も繰り返します。ただし、こちら の章ではずっと詳しい説明を行います。 3.1. シリアルポートとは何か? 3.1.1. シリアル入門 シリアルポートは I/O (入出力)デバイスです。 I/O デバイスはコンピュータにデータを出し入れするための方法です。I/O デ バイスにはシリアルポートやパラレルポート、ディスクドライブコントロー ラ、イーサネットボード、汎用シリアルバス等のたくさんの種類があります。 ほとんどの PC にはシリアルポートが 1 つか 2 つあります。各ポートはコン ピュータの裏側に 9 ピン(25 ピンのこともあります)のコネクタを持っていま す。コンピュータのプログラムは送信ピン(出力)にデータ(バイト列)を送るこ とができますし、受信ピン(入力)からデータを受け取ることもできます。他の ピンはフロー制御と接地のために使います。 シリアルポートは単なるコネクタではありません。シリアルポートは並列(パ ラレル)のデータを直列(シリアル)に変換し、データの電気的な表現を変えま す。コンピュータ内部では、データを表すビット群は並列に流れます(同時に 多数の配線を用います)。データを直列に流すとは、1 本の配線(シリアルコネ クタの送信ピンや受信ピン等)にビットのストリームを流すことです。シリア ルポートではこのようにデータを流すため、シリアルポートは送信ピン上でデ ータを並列(コンピュータ内部の形式)から直列に変換できなければなりませ ん(その逆の変換も必要です)。 シリアルポートの電子回路のほとんどは、UART と呼ばれるチップ(あるいは チップの一部)です。UART の詳細については、``UART って 何ですか? 性能に どんな影響を与えますか?''の章を見てください。しかし、まずはこの章から 読むとよいでしょう。全体における UART の位置づけが分かるからです。 3.1.2. ピンと配線 古い PC では 25 ピンのコネクタが使われていましたが、このうち実際に使わ れていたのは 9 本のピンだけです。したがって、現在ではほとんどのコネク タは 9 ピンです。9 本のピンは普通、それぞれ配線に繋がっています。デー タの送信と受信用に使われる 2 本の線の他に、信号の接地用に 1 本のピ ン(配線)が使われます。各配線の電圧は、この接地電圧に対して計測されま す。このように、双方向のデータの送信のために使う配線の最小数は 3 本で す。ただし、信号接地線がなくても動作することが知られてはいますが、この 場合には性能が落ちたり、エラーが起きたりします。 他にももっと配線がありますが、これらは制御のため(信号処理)に使われるだ けであり、データの送信には使われません。全ての信号を 1 本の線で共有す ることもできますが、シリアルポートはそうなっておらず、信号の種類ごとに 別々の専用線が用意されています。これらの制御用配線の一部(あるいは全 部)は「モデム制御線(modem control line)」と呼ばれます。モデム制御線の 状態は、 +12 V の有効(on)状態か、-12 V の無効(off)状態のどちらかです。 これらのモデム制御線の 1 つは、コンピュータに信号を送ってシリアルポー トへのデータ送信を止めさせるためのものです。これとは逆で、シリアルポー トに接続されたデバイスへ信号を送り、コンピュータへのデータ送信を止めさ せるための接続線もあります。また、接続されているデバイスがモデムの場合 には、モデムに電話を切るように指示したり、接続が確立していることや電話 が鳴っている(誰かが電話をかけてきている)ことをコンピュータに教えたりす るための線もあります。詳しくは ``ピン配置と信号'' の章をご覧ください。 3.1.3. RS-232 や EIA-232 等 (USB ではない)シリアルポートの規格は普通 RS-232-C, EIA-232-D, EIA-232-E のいずれかです。この 3 つはほとんど同じものです。もともと頭 に付いていた RS(Recommended Standard)が EIA (Electronics Industries Association)となり、EIA と TIA (Telecommunications Industries Association) が合併した後に EIA/TIA となりました。EIA-232 の仕様には同 期通信も書かれていましたが、同期に対応するためのハードウェアは PC には ほとんどついていません。 RS という呼称自体は過去のものとなりましたが、 今でも広く使われています。本 HOWTO 文書では EIA という表記を使います が、文書によっては完全な表記である EIA/TIAを使っているものもあります。 これ以外の(EIA-232 以外の)シリアルポートについては、 ``他のシリアルデ バイス (非同期 EIA-232 でないもの)'' の章をご覧ください。 3.2. I/O アドレスと IRQ コンピュータはそれぞれのシリアルポートと通信する必要があるので、 OS は それぞれのシリアルポートが存在することとそれらがある場所 (I/O アドレ ス)を知っていなければなりません。また、シリアルポートが CPU にサービス を要求する時にどの線(IRQ 番号)を使わなければならないかも OS は知ってい る必要があります。シリアルポートはこの線に割り込みを送ることによってサ ービスを要求します。したがって、それぞれのシリアルポートデバイスは I/O アドレスと IRQ (Interrupt ReQuest number)の両方を不揮発性メモリに保存 していなければなりません。詳しくは``割り込み''の節を参照してください。 PCI バスの場合は、必ずしもこのように動作するわけではありません。という のも、PCI には独自の割り込みシステムがあるからです。しかし、PCI 対応の BIOS は PCI の割り込みを IRQ にマッピングするようにチップを設定するた め、見かけ上は先の説明の通りに動作します。ただし、割り込みの共有が許さ れている点は除きます(複数のデバイスが同じ IRQ 番号を使えるわけです)。 I/O アドレスはメモリのアドレスとは別物です。 I/O アドレスがコンピュー タのアドレスバスに設定されると、別の配線に信号が流れるのです。この信号 が流れているとメインメモリはアドレスを無視しますが、固有の I/O アドレ スを持っている全てのデバイス(シリアルポート等)は設定されたアドレスに注 目し、それがデバイスのアドレスにマッチするかどうかをチェックします。も しアドレスがマッチすれば、その I/O デバイスはデータバス上のデータを読 み込みます。 3.3. 名前: ttyS0, ttyS1 等 シリアルポートには ttyS0, ttyS1 等の名前が付けられます(これらは普 通、DOS や Windows における COM1, COM2 等にそれぞれ対応します)。 /dev ディレクトリには、それぞれのポートに関する特殊ファイルがあります。 "ls /dev/ttyS*" を実行してこれらのファイルを見てみましょう。ただし、 (例え ば)ttyS3 ファイルがあるからといって、必ずしもそこに物理的なシリアルポ ートが存在するわけではありません。 (ttyS0, ttyS1 等の)どの名前がどの物理シリアルポートを指すのかは、以下 のようにして決まります。シリアルドライバ(ソフトウェア)は、どの I/O ア ドレスがどの ttyS に対応するのかを示す表を管理しています。このような名 前(ttyS1 等)から I/O アドレス(と IRQ)への対応は、設定も表示も "setserial" コマンドで行えます。 ``setserial とは何か?''の節をご覧くだ さい。このプログラムは、ハードウェアそのものの I/O アドレスや IRQ の設 定は行いません(ハードウェアの設定はジャンパやプラグ&プレイの設定プログ ラムで行います)。このように、どの物理ポートが ttyS1 などに対応するのか は、(setserial での)シリアルドライバの設定とハードウェアの設定の両方に 依存します。設定が間違っていると、物理ポートは(ttyS2 などの) 名前に対 応させられず、したがって使えなくなります。詳しくは ``/dev/ttyS2 等のシ リアルポートデバイス'' の章をご覧ください。 3.4. 割り込み シリアルポートは、ある数のバイトデータ(1, 4, 8, 14 のいずれかに設定さ れていると思います)のデータを FIFO バッファに受け取ると、通常はそのポ ートだけが使う特定の配線上に割り込みとして知られる電気信号を流すことに より、そのデータを取り込むように CPU に伝えます。このように FIFO は、 ある数のバイトデータを待って、それから割り込みを発行します。 しかし、この割り込みは、次のバイトデータが届くのを待っている間に、予期 しない遅延が生じた時にも送られます(タイムアウトといいます)。このよう に、バイトデータがゆっくり受信されていると(端末のキーボードで入力して いるように)、1 バイトを受け取るごとに割り込みが発行されるかもしれませ ん。一部の UART チップでは、以下のような規則になります: 4 バイトを連 続して受け取れるかもしれなかったのに、これらの 4 バイトのデータがいず れも出てこなければ、シリアルポートは次のバイトデータを待つのをあきら め、現在 FIFO に入っているバイトデータを取得させるために割り込みを発行 します。もちろん、FIFO が空であれば割り込みは発行されません。 (コンピュータ内部にある)それぞれの割り込み線には番号(IRQ)が付いてお り、シリアルポートは信号を送るためにどの線を使うのかを知っていなければ なりません。例えば ttyS0 は通常、IRQ 番号 4 を使います。これは IRQ4(ま たは IRQ 4)と書かれます。IRQ 番号のリスト等は "man setserial" に書かれ ています( 「シリアルポートのコンフィギュレーション上の注意事項 (Configuring Serial Ports)」の章を見てください)。シリアルポートが CPU の注意を引く必要がある時には必ず割り込みが発行されます。割り込みの発行 を適切なタイミングで行うことは重要です。というのも、シリアルポートの バッファは入ってくるデータを 16 バイト(古いシリアルポートでは 1 バイ ト)しか保持できないからです。このような受信データをバッファからうまく 取り出すことに CPU が失敗すると、これ以上のデータが入る場所がなくな り、小さなバッファがあふれて(オーバーラン)データが無くなってしまうかも しれません。これを ``フロー制御''で防ぐことはできません。 割り込みは、シリアルポートが 16 バイトのデータを小さい送信バッファから 外部ケーブルに全て送り出した直後にも発行されます。この送信バッファに は、送り出すデータ用の 16 バイトの空きができます。この事実を CPU に伝 え、小さい送信バッファに送信すべき新しいデータを入れさせるために割り込 みを用います。また、モデム制御線の状態が変化した時にも割り込みが発行さ れます。 上の説明のバッファは全てハードウェアバッファのことです。シリアルポート はメインメモリ上にも大きいバッファを持っています。これは後ほど説明しま す。 割り込みは多くの情報を伝えますが、これは間接的にしか行いません。割り込 みそのものは、特定のポートが注意を求めていることを割り込みコントローラ と呼ばれるチップに知らせるだけです。割り込みコントローラはこれを受けて CPU に信号を送ります。CPU はシリアルポートにサービスを提供する特殊なプ ログラムを実行します。このプログラムは割り込みサービスルーチンと呼ばれ ます(シリアルドライバのソフトウェアの一部です)。割り込みサービスルーチ ンはシリアルポートで起きた出来事を調べ、その問題 (シリアルポートのハー ドウェアバッファのデータ入出力など)を処理します。このルーチンはシリア ルポートで起きたことを簡単に知ることができます。というのも、シリアルポ ートのレジスタはシリアルデバイスドライバが知っている I/O アドレスにあ るからです。このレジスタは、シリアルポートの状態に関する情報を保持して います。デバイスドライバはこのレジスタを読んでその内容を調べることによ り、シリアルポートで起きたことを知り、適切な動作を行うことができます。 3.5. データフロー (速度) シリアルポートではデータ(文字、画像などを表すバイト列)の入出力が行われ ます。データが流れる速度であるフローレート(56k (56000) ビット/秒な ど)は(不正確ですが)「速度」と呼ばれます。ですが大抵の人は「フローレー ト」ではなく「速度」の方を使います。 平均速度は仕様で決められている速度よりも遅い場合が多いことを理解してお くことが大切です。待ち時間(あるいはアイドル時間)があると、平均速度は低 くなります。このような待ち時間には、``フロー制御''による 1 秒程度もあ る長い待ち時間も含まれます。別の極端な例としては、バイトデータを送る間 の数ミリ秒という非常に短い待ち時間があります。シリアルポートに接続した デバイス(モデムなど)がシリアルポートの最高速度に付いていけない場合に は、平均速度を低くしなければなりません。 3.6. フロー制御 フロー制御とは、配線を流れるバイトデータを止める機能のことです。これに は、バイトデータを失うことなくデータを再び流し始める機能も含まれます。 フロー制御は、モデムが瞬間のフローレートを非連続的に変えられるようにす るために必要です。 3.6.1. フロー制御の例 例として、33.6k の外部モデムを短いケーブルを使ってシリアルポートに接続 する場合を考えましょう。このモデムは電話回線上で 33.6k bps (ビット毎 秒)でデータを送受信します。データ圧縮やエラー訂正は全く行わないものと します。シリアルポートの速度は 115.2k bps に設定してあり、データをコン ピュータから電話回線に送ります。すると、コンピュータからモデムへは短い ケーブルを通って 115.2k bps でデータが流れます。しかし、モデムから電話 回線へは 33.6k bps でしかデータが流れません。データが出て行くよりも速 くデータが入ってくるので、モデムは超過分のデータ (115.2k -33.6k = 81.6k bps)をバッファに保持しなければなりません。 115.2k bps のデータの 流れが止まらない限り、結局はこのバッファは溢れて (空き容量がなくなっ て)しまいます。 ですが、ここでフロー制御が役立ちます。モデムのバッファが溢れそうになる と、モデムはシリアルポートに停止信号を送ります。シリアルポートはこの停 止信号をデバイスドライバに渡し、115.2k bps のデータの流れは停止しま す。モデムは、今までバッファに蓄えたデータを取り出しながら、そのまま 33.6k bps でデータを送り続けます。するとバッファには何も入ってこないた め、バッファ内のデータ量は減り始めます。バッファ内のデータがほとんどな くなると、モデムは開始信号をシリアルポートに送り、コンピュータからモデ ムへ再び 115.2k bps でデータが流れ始めます。フロー制御により事実上、短 いケーブル上での平均的なフロー速度(この場合は 33.6k bps)は、データを 「流し続けた」場合の速度である 115.2k bps よりもずっと遅くなります。こ れが「開始-停止」フロー制御です。 上記の簡単な例はコンピュータからモデムへの流れのフロー制御でしたが、反 対向きの流れに対して用いるフロー制御もあります。すなわちモデム(または 他のデバイス)からコンピュータの向きです。どちらの向きの流れにも 3 つの バッファ(1. モデム内のバッファ、 2. UART チップ(いわゆる FIFO)の内 部、3. シリアルドライバが管理するメインメモリ中のバッファ)があります。 フロー制御は、特定のバッファが溢れないように保護します。小さい UART FIFO バッファはこのような保護を受けていませんが、その代わりに、この バッファが発行する割り込みへの応答が高速であることを期待して動作しま す。FIFO は「First In, First Out(先に入ったデータが先に出る)」という、 バイトデータの扱い方を表しています。 3 つのバッファ全てが FIFO の規則 で動作しますが、これを名前として持っているのは 1 つだけです。これがフ ロー制御の本質ですが、説明することはもっとたくさんあります。 3.6.2. フロー制御がない時の症状 フロー制御の理屈を知っていると実際に役立てることができます。フロー制御 がない時に出る症状は、フロー制御の恩恵を受けずに送られたファイルからデ ータがごそっと消えてしまうことです。これはオーバーフローが起こった時に は、たいてい数バイトどころではない量のデータがあふれて失われるからで す。何百、何千バイトものデータが消え、その全てが一続きであることもよく あります。 3.6.3. ハードウェアフロー制御対ソフトウェアフロー制御 可能であれば、できるだけ「ハードウェア」のフロー制御を使いましょう。こ れは専用の「モデム制御線」を 2 本使い、「停止(stop)」と「開始(start)」 の信号を送るものです。 ソフトウェアによるフロー制御は、開始信号と停止信号を送るためにメインの 送信線と受信線を使います。ソフトウェアのフロー制御は、この信号を送るた めに ASCII 制御文字の DC1(開始)と DC3(停止)を使います。この制御文字は 単に、通常のデータストリーム内に挿入されます。ソフトウェアのフロー制御 は反応が遅いだけでなく、特別な対策を講じなければモデムを使ってバイナリ データを送ることもできません。バイナリデータには大抵、フロー制御用の制 御文字である DC1, DC3 が入っているので、特殊な対策を立てて、フロー制御 の停止信号である DC3 とバイナリコードの一部である DC3 を区別しなければ なりません。DC1 についても同様です。 3.7. データフローのパスとバッファ この話題については、フロー制御・(ハードウェアが持つ)16 バイトの FIFO バッファのペア・シリアルポートに接続されている大きいバッファのペアを含 めた大部分を既に説明しましたが、これ以外にもまだバッファの対がありま す。すなわちメインメモリ上に大きな(多分 8KB)バッファが存在し、これもシ リアルポートのバッファと呼ばれます。アプリケーションプログラムがデータ をシリアルポートに送ると、このデータはまずメインメモリの方の送信シリア ルポートバッファに格納されます。バッファの対は、データの流れの向きが反 対である送信バッファと受信バッファの組み合せです。 シリアルポートのデバイスドライバは、例えば 16 バイトのデータを 1 バイ トずつ送信バッファから取り出し、これをシリアルポートのハードウェアが送 信用に持っている 16 バイトの送信バッファに入れます。一度データが送信 バッファに入ると、その送信を止める方法はありません。そしてこのデータ は、シリアルポートに接続されているデバイスに送られます。シリアルポート も適切な大きさ (例えば 1K バイト)のバッファを持っています。デバイスド ライバが(フロー制御による指示で)コンピュータから出ていくバイトデータの 流れを止めた時には、実際に止まるのはメインメモリ上にある大きな送信バッ ファから出ていくバイトデータの流れです。これが起こり、シリアルポートに 接続されているデバイスへのデータの流れが止まった後であっても、アプリケ ーションプログラムは、8K バイトの送信バッファがいっぱいになるまでは、 ここにデータを送り続けることができます。 このバッファがいっぱいになると、アプリケーションプログラムはそれ以上の データを送る(C 言語では "write" 文を使います)ことができなくなり、アプ リケーションの実行を一時的に停止してバッファに空きができるのを待ちま す。このように、フロー制御の "stop" 信号は最終的には、データを送るプロ グラムを止めることができます。このプログラムが止まっても、コンピュータ は必ずしも計算を止めるわけではありません。フロー制御の stop 信号を受け て待っている間は、別のプロセスに切替えればよいのです。以上の説明は多少 簡略化しすぎです。というのも、"write" 文を待っている間にアプリケーショ ンプログラム自体に別処理をさせる方法も他にあるからです。 3.8. 複雑なフロー制御の例 多くの場合、伝送経路が複数のリンクを持ち、そのそれぞれが独自のフロー制 御を行うことがあります。例えば、モデム経由で BBS にアクセスしている PC に接続しているテキスト端末上で文字をタイプしたとします。この場合、使っ ているアプリケーションプログラム "minicom" はシリアルポートを 2 つ扱う ことになります。テキスト端末上で入力された文字は、まずシリアルポートか ら minicom に送られ、次に minicom から次のシリアルポートを経由でモデム に送り出されます。そして最後に、この文字は電話回線を通じて BBS に送ら れます。テキスト端末が画面に文字を表示できる速度には限界があるので、速 度を落すためにフロー制御の "stop" 信号が時々発行されます。"stop" 信号 が発行されると一体何が起こるのでしょうか? "stop" 信号が BBS まで届き、 BBS ホスト上でデータを送り出しているプログラムを止めるまでに長い時間が かかる場合を考えてみましょう。 この "stop" 信号の流れを追跡してみましょう(リンクによってソフトウェア で処理されたり、ハードウェアで処理されたりします)。まずは BBS から大き なファイルを「取得する」場合を考えます。この際には、テキスト端末とハー ドディスク上のファイルの両方に同時にデータが送られます。テキスト端末の 表示速度よりも速くデータが送られてくるので、テキスト端末は PC の 1 つ めのシリアルポートに "stop" 信号を送ります。デバイスドライバはこれを検 出し、(メインメモリ上にある)8KB のシリアルバッファから端末へのデータ送 信を停止させます。この時点ではまだ、minicom は端末へ送るためのデータを 8KB のバッファに送り続けています。 (1 つめのシリアルポートの)この 8KB の送信バッファがいっぱいになると、 minicom はここへの書き込みを止めなければなりません。minocom はデータを 送るのを止めて待ち状態に入ります。ですがこれによって同時に、モデムに接 続されている 2 番目のシリアルポートの 8KB の受信バッファからの読み込み も止まってしまいます。モデムからのデータは、8 KB のバッファがいっぱい になり、モデムに対する "stop" 信号が新しく送られるまで流れ続けます。モ デム(エラー訂正は有効であるものとします)は "stop 信号" を BBS 側のモデ ムに送ります。このモデムはバッファからデータを送り出すのを止め、この バッファがいっぱいになると、BBS ホストのシリアルポートに stop 信号を送 ります。BBS ホストでは、8KB(など)のバッファがいっぱいになり、BBS ホス ト側のプログラムから書き込みできなくなると、このプログラムが一時的に停 止します。 このようにして、テキスト端末から送られた stop 信号が BBS ホスト上のプ ログラムを止めます。とっても面倒な仕組みですね! stop 信号はシリアルポ ートを 4 つ通り、モデムを 2 つ通り、アプリケーションプログラムを 1 つ (minicom)を通過するのです。各シリアルポートは(一方向につき)バッファを 2 つ(8KB のバッファと、ハードウェアが持つ 16 バイトのバッファ)持ちま す。アプリケーションプログラムは C 言語のコード内部でもバッファを持っ ているでしょう。これも含めると、データは 11 個もの別々のバッファを通り ます。シリアルハードウェアの小さいバッファはフロー制御を直接は識別しな い点には注意してください。 BBS から端末へデータが流れる際に端末の速さの限界がボトルネックになって いる場合、フロー制御の "stop" 信号は実際には BBS からデータを送るプロ グラムを止めることになります。これは先程説明した通りです。ですが 「"stop" 信号がそんなに時間を食って、11 個のバッファ(もっと大きいバッ ファもある)が全部あふれることなんて本当にあるの?」と思われるかもしれま せん。テキスト端末が "stop" 信号を送った時に全てのバッファが容量いっぱ いに近かった場合には、そうなることは実際にあります。 ですが実験を行ってみれば、これよりももっと説明が複雑になることがお分か りになると思います。ある瞬間にデータを流しているリンクもあります し、(フロー制御によって)止まっているリンクもあります。端末からの "stop" 信号が、先に説明したようにうまく BBS ホストに伝わることは滅多に ありません。BBS 側に "stop" 信号を 1 つ届けるには、端末からは "stop" 信号をいくつか送らなければならないことがあります。実際の動作を理解する には、机にコインを置いて行う簡単な実験をやってみるといいでしょう。バッ ファの数は 2, 3 個で、各バッファの容量もコイン 2, 3 個だけにしてくださ い。 読者の皆さんは、なぜこんなことをいちいち説明するのかと思われるかもしれ ません。ですが筆者は、BBS から取得したテキストがなくなる原因をこれで理 解したことがあるのです。その時の状況はちょうど前の例と同じですが、モデ ム対モデムのフロー制御が無効になっていました。ハードディスクにも保存さ れるはずの、取得したテキストデータが実際には保存されなかったのですが、 その原因は端末からのフロー制御の "stop" 信号のためにモデムのバッファが オーバーフローしていたことでした。ボトルネックがないデータの経路が BBS からハードディスクまであっても、端末が原因となるオーバーフローがこの経 路上で起きたため、テキストデータが無くなってハードディスクに保存できま せんでした。モデム経由でハードディスクにデータを渡すはずが、モデムでオ ーバーフローが起こっていたために、ハードディスクに送るべきデータが消え ていたのでした。 3.9. シリアル操作ソフトウェア: デバイスドライバモジュール シリアルポート用のデバイスドライバは、シリアルポートを操作するソフト ウェアです。現在はこれはシリアルモジュールとして用意されています。この モジュールは普通、必要な時に自動的にロードされます。バージョン 2.2 以 降のカーネルはこれを行います。これより古いカーネルでは、必要な時にモ ジュールを自動ロードするためには kerneld を実行する必要がありました。 これを行わない場合には、/etc/modules に明示的に列挙する必要がありまし た。モジュールが Linux で一般的になる前は、シリアルドライバはカーネル に組み込むのが普通でした。もし、シリアルドライバがまだカーネルに組み込 んであるのなら(カーネルのコンパイル時にそう選択したのかもしれません)、 シリアルモジュールをロードしてはいけません。もしこれをロードしてシリア ルドライバが 2 つになってしまうと、シリアルポートは使えなくなります。 この場合にシリアルポートをオープンしようとすると "I/O error" となりま す。 シリアルモジュールがロードされると、存在するシリアルポートに関するメッ セージが画面に表示されます(よく間違った IRQ を表示します)。しかし、一 度 setserial を使ってデバイスドライバに(たぶん)正しい IRQ を教えれば、 次の表示は最初の表示に似ていますが、IRQ 等が正しくなっているはずで す。setserial の詳細については ``setserial とは何か?''をご覧ください。 カーネルのソースコードを編集してドライバを修正することができます。シリ アルドライバの大部分は serial.c ファイルにあります。シリアルポートを使 うプログラムの詳しい書き方については、Serial-Programming-HOWTO をご覧 ください(現在 Vern Hoxie さんが改訂中です)。 4. シリアルポートは時代遅れなのか? 4.1. はじめに 「はい」というのが答えですが…。シリアルポートはいくらか時代遅れですが 現在でも必要ですし、特に Linux では必要です。シリアルポートには欠点が たくさんありますが、新しい PC のほとんどにシリアルポートが付いているよ うです。Linux がサポートしている通常電話回線用のモデムは、シリアルポー ト経由で動くものだけです。 シリアルポートは、コンピュータと外部ケーブルの間でデータを運ばなければ なりません。よって、シリアルポートは 2 つのインタフェースを持ち、どち らのインタフェースも低速です。まずは外部ケーブルを通じた外界とのインタ フェースを考えてみましょう。 4.2. 低速で距離も短い EIA-232 ケーブル 従来の EIA-232 シリアルポートは、どうしても低速で、距離にも厳しい限界 があります。広告ではよく「高速」と謳われますが、実際に「高速」に動作す るのは、PC のすぐ隣にモデムがあるような非常に距離が短い場合だけです。 またネットワークカードと比べると、この「高速」というのも低速に過ぎませ ん。シリアルケーブルは全て共通の接地線を使う配線を用いているので、ハー ドウェアを追加しない限り(高速な伝送で必要となる)ツイストペア技術を使え ません。シリアルポート用の最新技術も存在しますが、これらは EIA-232 と 違って PC の標準ではありません。 ``EIA-232 の後継''をご覧ください。一 部のマルチポートシリアルカードはこれらをサポートしています。 1962 年に作られた RS-232 規格がツイストペア技術を使っていないことはあ る意味悲劇です。これを使っていれば 100 倍高速に動作できたはずなのです から。ツイストペアは電話線には 19 世紀末から使われてきました。 1888 年(110 年以上も前)の「ケーブル会議(Cable Conference)」は、ツイストペア の(電話システムへの)支持とその利点を報告しています。ですが、「ケーブル 会議」での合意は、80 年以上も後の RS-232 では生かされませんでし た。RS-232 は元々、端末をその隣に置いた低速モデムと接続するために設計 されたので、高速・長距離の伝送に関する必要性は理解されなかったようで す。 4.3. コンピュータへのインタフェースの非効率さ コンピュータと情報をやりとりするには、どんな I/O デバイスであってもコ ンピュータが読み書きできるアドレスが必要です。この目的のために多くの I/O デバイス(シリアルポート等)は I/O アドレスと呼ばれる特殊なアドレス を持っています(I/O ポートと呼ばれることもあります)。これは実際には、あ るアドレスの範囲であり、一番低位のアドレスがベースアドレスになります。 単に「アドレス」と言われた(書かれた)場合は、実際は大抵「ベースアドレ ス」を指しています。 一部の I/O デバイスは I/O アドレスを使わないで、直接メインメモリの読み 書きを行います。この方法だと大きな帯域を利用できます。というのも、昔な がらのシリアル I/O システムでは同時に 1 バイトしか転送できないからで す。メインメモリを直接読み書きする方法は色々あります。その一つが共有メ モリ I/O と呼ばれるものです(共有メモリは普通、I/O デバイスと同じカード 上にあります)。他の方法としては ISA バスの DMA(direct memory access, 直接メモリアクセス)や、 PCI バスでの DMA と同様の仕組み(速度はずっと速 い)である「バスマスタリング」があります。これらの方法は、シリアルポー トの方式よりもずっと高速です。したがって、(14 バイトごとの)割り込み駆 動インタフェースを持ち、バス自体が 4(または 8)バイトをまとめて処理でき るのに 1 バイトずつしか送信できない昔ながらのシリアルポートは、超高速 の I/O には向いていません。 5. マルチポートシリアルボード/カード/アダプタ 5.1. マルチポートシリアル入門 マルチポートシリアルカードは PC の ISA バスまたは PCI バスのスロットに 設置します。「…カード」と呼ぶ代わりに、「…アダプタ」や「…ボード」と 呼ばれることもあります。このようなカードを使うと、シリアルポートをたく さん使うことができます。今日では、マルチポートシリアルカードは(企業や 家庭における自動化を含めて)外部デバイスの制御に一般的に使われていま す。マルチポートシリアルカードは、遠隔地からコンピュータサーバを監視/ 制御するためにコンピュータサーバに接続できます。これはかつては主として たくさんの端末やモデムをシリアルポートに接続するために使われていまし た。こういった使い方もまだされていますが、マルチポートシリアルカードを モデムと組み合わせて使うと、普通のモデムの場合と同じ制限を受けます。つ まり、モデムが 56K モデムであっても、接続速度は 33.6K を超えることがで きません。 したがって、誰かがあなたに電話をかけ(そして、カードに挿さったモデムか らあなたのマルチポートシリアルカードに接続し)た場合、たとえ 56K モデム を使っていたとしても、どちらの向きの通信速度も 33.6K を超えることはで きません。ダイアルイン接続で 33.6K を超えるためには、電話線がデジタル 接続になっている必要があります。この場合、シリアルポートはもう関係なく なります。したがって、マルチポートシリアルカードは今では ISP や外部か ら 56K(33.6K 以上で)ダイアルイン接続をさせる必要がある人が使うには時代 遅れのものになりました。詳しくは Modem-HOWTO の「Modem Pools」と 「Digital Modem」の節を見てください。 各種マルチポートカードにはたくさんの外部コネクタ(DB-25 または (電話線 のような)RJ-45)がついており、たくさんのデバイス(モデム、端末など)を接 続できます。それから、こういった物理デバイスはそれぞれ各自のシリアルポ ートに接続されます。カードの外に面している部分の面積は限られているた め、全てのシリアルポートコネクタに対して十分な空間が取れないこともよく あります。この問題を解決するために、コネクタはカードから (外部に)延び ているケーブル(タコ足ケーブル)の端に繋がれることがあります。こういった コネクタはマルチポートカードとケーブルで繋がっている小さな箱に接続され ることもあります。 ダムシリアルポートも通常のシリアルポートとあまり変わりません。ダムシリ アルポートも割り込み駆動であり、このポートにサービスする動作のほとんど 全てはコンピュータの CPU が行います。これには普通、1 つの割り込みを全 てのポートで共有するためのシステムが付いています。だからといって CPU にかかる負荷が減るわけではありません。なぜなら、いずれかのポートがサー ビスを必要とするたびに CPU に割り込みがひとつ送られるからです。こう いったデバイスはは通常は特殊なドライバを必要とします。ドライバはカーネ ルに組み込むか、ソースコードの修正によって有効にしなければなりません。 賢いボードは通常の UART を使えますが、UART からの割り込みのほとんどを ボード内で内部的に処理します。これにより、CPU はこういった割り込みの全 てを扱うという負荷を逃れることができます。このボードはバイトデータを大 きな内部 FIFO に蓄え、一度に 1K バイトくらいのデータをメインメモリ上の シリアルバッファに転送します。メインメモリへのデータ転送を行う際に は、(ダムシリアルカードのように 8 ビットのバイトだけを転送するのではな く)32 ビットのバス幅を全て使うことができます。必ずしも全ての「賢い」ボ ードが同じように効率的なわけではありません。現在の多くのボードはプラ グ&プレイ対応です。 賢いボードを動かすためには、専用のドライバを使わなければなりません。こ のドライバはカーネルのソースコードに組み込まれていたり、モジュールとし て提供されることもあります。こういった場合でも、ドライバを有効にするに は何かしなければなりません。その作業には、カーネルのコンパイル時に選ぶ こと(または、予めコンパイルされているカーネルがそうなっているかどうか を確かめること)が含まれます。"make config" コマンドか "make menuconfig" コマンドを使うと、このオプションがどのように設定されている かを確かめることができます。場合によっては、特殊なドライバをロードした り、特定のパラメータを(LILO の append コマンドを使って) カーネルに渡す こともあります。ボードのメーカーは、このような情報を自社のウェブサイト に載せているはずです。残念ながら、古いボードの情報がないことも時々あり ますが、その情報はインターネット上の他の場所で見つけられるかもしれませ ん(議論用のニュースグループを含みます)。 5.2. /dev ディレクトリでの「デバイス」の作成 マルチポートボードが使うシリアルポートは、お使いのボードの種類によって 異なります。一部のポートは rc.serial や 0setserial に詳しく列挙されて いるかもしれません。これらのファイルは setserial パッケージまたは serial パッケージに入っているかもしれません。筆者としては、読者の皆さ んがマルチポートボードを使おうとしているのなら、最新バージョンの setserial を入手することを強くお勧めします。また多分、これらのデバイス を作成する必要があるでしょう。作成には mknod コマンドか MAKEDEV スクリ プトを入手してください。シリアルポート用のデバイス (/dev ディレクトリ にある)は、「64 + ポート番号」の足し算で作れます。したがって、ttyS17 用のデバイスを作成したければ、以下のコマンドを実行します: linux# mknod -m 666 /dev/ttyS17 c 4 81 ttyS デバイスの「メジャー」番号は必ず 4 である点(そして、5 は時代遅れ の cua デバイスの番号である点)に注意してください。また「64 + 17 = 81」 にも注意してください。 MAKEDEV スクリプトを使う場合には以下のコマンド を実行します: linux# cd /dev linux# ./MAKEDEV ttyS17 本 HOWTO に書かれているマルチポート製品の一覧以外にも、 Gary's Encyclopedia - Serial Cards という WWW ページがあ ります。これは完全ではありませんが、他へのリンクもいくつかあります。 5.3. PC 標準のシリアルカード 昔は PC にはシリアルカードが独立して挿さっていました。少し前はシリアル 機能はハードディスクのインタフェースカードに組み込まれていました。現在 は、普通は一つまたは二つのシリアルポートがマザーボードに組み込まれてい ます。しかし、追加のシリアルポートが 1 つから 4 つ必要な場合は今でも PC 用の旧式のシリアルカードを買えるでしょう。これらは ttyS0-ttyS3 (COM1 - COM4)として使います。これらを使って外付けシリアルデバイス(モデ ム、シリアルマウス等)を接続できます。小売のコンピュータショップでこう いったカードを扱っているのはごく一部だけです。しかし、インターネットを 通じて購入することもできます。PCI のシリアルカードを買う前には、Linux が対応していることを確かめましょう。 有名なブランドをいくつか紹介します: o Byte Runner (直接注文できます。価格も表示されています) o SIIG o Dolphin 注意: アドレスが衝突するため、COM4 と IBM8514 ビデオカード(など)は同時 に使えないかもしれません。 ``特定のビデオボードでの I/O アドレスの衝突 を避ける方法'' をご覧ください。 5.4. ダムマルチポートシリアルボード (標準の UART チップが載っているも の) 以下のボードは「シリアルアダプタ」とも呼ばれます。これらのカードは、対 応機能をカーネルにコンパイルして組み込む必要がある特殊な方法を使って割 り込みを共有していることがよくあります。 * => Debian では setserial を実行するファイルが、詳細な設定を表示しま す。 # => このボードについては後述の注を見ること o AST FourPort およびその互換カード (4 ポート) * # o Accent Async-4 (4 ポート) * o Arnet Multiport-8 (8 ポート) o Bell Technologies HUB6 (6 ポート) o Boca BB-1004 (4 ポート), BB-1008 (8 ポート), BB-2016 (16 ポート; mini-howto 文書があります) * # o Boca IOAT66 あるいは? ATIO66 (6 ポート、確かめていませんが Linux で は IRQ 共有に対応していません。RJ45 に似た、特殊な 10-ピンコネクタ を使います) o Boca 2by4 (4 シリアルポート、2 パラレルポート) o Byte Runner o Computone ValuePort V4-ISA (AST FourPort 互換) * o Digi PC/8 (8 ポート) # o Dolphin o Globetek o GTEK BBS-550 (8 ポート; mini-howto 文書があります) o Hayes ESP (カーネル 2.1.15 以降) o HUB-6 (Bell Technologies に問い合わせてください) o Longshine LCS-8880, Longshine LCS-8880+ (AST FourPort 互換) * o Moxa C104, Moxa C104+ (AST FourPort 互換) * o NI-SERIAL , National Instruments 製 o PC-COMM (4 ポート) o Sealevel Systems COMM-2 (2 ポート), COMM-4 (4 ポート), COMM-8 (8 ポート) o SIIG I/O Expander 2S IO1812 (4 ポート) # o STB-4COM (4 ポート) o Twincom ACI/550 o Usenet Serial Board II (4 ポート) * 一般的には、Linux は 8250, 16450, 16550, 16550A, 16650 などの UART を 使っている全てのボードに対応しています。もっと詳しいリストについては、 "setserial" の最新のマニュアルページを参照してください。 注: AST Fourport: rc.serial で skip_test を指定する必要があるかもしれませ ん。 BB-1004 と BB-1008 は DCD, RI ラインをサポートしておらず、そのためダイ アルイン用のモデムには使えません。他の目的では問題なく動作します。 Digi PC/8 の割り込み状態レジスタの位置は 0x140 です。 SIIG IO1812 のマニュアルに書かれている COM5 から COM8 のリストは誤って います。正しくは COM5=0x250, COM6=0x258, COM7=0x260, COM8=0x268 のはず です。 5.5. インテリジェントマルチポートシリアルボード Linux 互換のドライバが使えることを確かめ、ドライバ付属の情報を読んでく ださい。これらのカードは、標準のデバイスでなく特殊なデバイス(/dev ディ レクトリにある)を使います。この情報はハードウェアごとに異なります。こ の文書に載せるべき新しい情報があれば、ぜひ筆者にメールを送ってくださ い。 Linux のドライバモジュールの名前は *.o ですが、これらは全てのモデルで 正しく動作するとは限りません。また、(I/O アドレスや IRQ 等の)パラメー タをモジュールに与える必要があることも多いので、それに関する説明を見つ ける必要もあります(ソースコードツリーの中にあるかもしれません)。 マルチポートカードのブランドはたくさんあり、それぞれから色々な種類のカ ードがよく出されます。今のところ、これらのカードをここで網羅しようとは していません(また挙げているものの多くは時代遅れになっているかもしれま せん)。したがって、このリストはマルチポートカードやそのブランドについ て古いものと新しいものがごっちゃになっています。ウェブページから分かる 場合には連絡先は削除しました。ドライバに関する情報も同じウェブページで 見つかるはずです。ウェブページを紹介していない場合、そのカードはたぶん 古いと思います。リストをよりよくするために情報を追加したいと思う方は、 筆者にお知らせください。 o Chase Research (UK ベース、ISA/PCI カード) ウェブページ: ドライバのステータス: 2.2 カーネル用。Chase がサポートしています。 o Comtrol RocketPort (36MHz ASIC; 4, 8, 16, 32 ポート、128 ポートま で) ウェブページ: http://www.comtrol.com ドライバのステータス: Comtrol 社がサポートしています(rocket.o)。 ドライバの入手先: ftp://tsx-11.mit.edu/pub/linux/packages/comtrol o Computone IntelliPort II (ISA, PCI, EISA バス用。64 ポートまで) ウェブページ: ドライバの入手先: , パッチ は にあります。 メーリングリスト: 本文に "subscribe linux-computone" と書いたメール を に送ります。注意: Computone は、古い ATvantage カードや IntelliPort カードをサポート していません。 o Connecttech ウェブサイト: ドライバの入手先: o Cyclades Cyclom-Y (Cirrus Logic CD1400 UART; 8 - 32 ポート), Cyclom-Z (MIPS R3000; 8 - 64 ポート) ウェブサイト: ドライバのステータス: Cyclades がサポートしています。 ドライバの入手先: ftp://ftp.cyclades.com/pub/cyclades。また、バー ジョン 1.1.75 以降の Linux カーネルに含まれています: cyclades.o o Decision PCCOM8 (8 ポート) 連絡先: ウェブサイト: なし(消滅) ドライバの入手先: ftp://ftp.signum.se/pub/pccom8 o Digi PC/Xi (12.5MHz 80186; 4, 8, 16 ポート), PC/Xe (12.5/16MHz 80186; 2, 4, 8 ポート), PC/Xr (16MHz IDT3041; 4, 8 ポート), PC/Xem (20MHz IDT3051; 8 - 64 ポート) ウェブサイト: ドライバのステータス: Digi 社がサポートしています。 ドライバの入手先: ftp://ftp.dgii.com/drivers/linux でも入手できます し、バージョン 2.0 以降のカーネルにはドライバが含まれていま す(epca.o)。 o Digi COM/Xi (10MHz 80188; 4, 8 ポート) 連絡先: Simon Park さん, si@wimpol.demon.co.uk ドライバのステータス: 不明。 注意: Simon さんは仕事のため、何ヵ月も続けて電子メールが使えなくな ることがよくあります。 Mark Hatle さん( )のご厚意により、ドライバが 必要ならば入手できるようになっています。 Mark さんはドライバのメン テナンスやサポートは行いません。 o Equinox SuperSerial Technology (30MHz ASIC; 2 - 128 ポート) ウェブサイト: http://www.equinox.com ドライバのステータス: Equinox 社がサポートしています。 ドライバの入手先: ftp://ftp.equinox.com/library/sst o Globetek ウェブサイト: ドライバの入手先: o GTEK Cyclone (16C654 UART; 6, 16, 32 ポート), SmartCard (24MHz Dallas DS80C320; 8 ポート), BlackBoard-8A (16C654 UART; 8 ポート), PCSS (15/24MHz 8032; 8 ポート) ウェブサイト: http://www.gtek.com ドライバのステータス: GTEK 社がサポートしています。 ドライバの入手先: ftp://ftp.gtek.com/pub o Hayes ESP (COM-bic; 1 - 8 ポート) ウェブサイト: http://www.nyx.net/~arobinso ドライバのステータス: バージョン 2.1.15 (1998年)以降の Linux カーネ ルは対応しています(esp.o)。setserial 2.15 以降も対応しています。作 者もサポートしています。 ドライバの入手先: http://www.nyx.net/~arobinso o Multi-Tech Systems 製のインテリジェントシリアルインタフェース PCI 版は 4 または 8 ポート。 ISA 版は 8 ポート。DTE 速度は 460.8K。 ウェブページ: o Maxpeed SS (Toshiba; 4, 8, 16 ポート) ウェブサイト: http://www.maxpeed.com ドライバのステータス: Maxpeed 社がサポートしています。 ドライバの入手先: ftp://maxpeed.com/pub/ss o Microgate SyncLink ISA/PCI 高速マルチプロトコルシリアルカード。同期 HDLC 用です。 ウェブサイト: ドライバのステータス: Microgate 社がサポートしていま す(synclink.o)。 o Moxa C218 (12MHz 80286; 8 ポート), Moxa C320 (40MHz TMS320; 8 - 32 ポート) ウェブサイト: http://www.moxa.com ドライバのステータス: Moxa 社がサポートしています。 ドライバの入手先: > (台湾からは www.moxa.com.tw/... も使えます。「...」の部分は上記と同じです。) o SDL RISCom/8 (Cirrus Logic CD180; 8 ポート) ウェブサイト: http://www.sdlcomm.com ドライバのステータス: SDL 社がサポートしています。 ドライバの入手先: ftp://ftp.sdlcomm.com/pub/drivers o Specialix SX (25MHz T225; 8? - 32 ポート), SIO/XIO (20 MHz Zilog Z280; 4 - 32 ポート) ウェブページ: ドライバのステータス: Specialix 社がサポートしています。 ドライバの入手先: 古いドライバの入手先: o Stallion EasyIO-4 (4 ポート), EasyIO-8 (8 ポート), EasyConnection (8 - 32 ポート) - これらには Cirrus Logic CD1400 UART が載っています。 Stallion (8MHz 80186 CPU; 8, 16 ポート), Brumby (10/12 MHz 80186 CPU; 4, 8, 16 ポート), ONboard (16MHz 80186 CPU; 4, 8, 12, 16, 32 ポート), EasyConnection 8/64 (25MHz 80186 CPU; 8 - 64 ポート) 連絡先: sales@stallion.com または http://www.stallion.com ドライバのステータス: Stallion 社がサポートしています。 ドライバの入手先: ftp://ftp.stallion.com/drivers/ata5/Linux から入 手できます。また、バージョン 1.3.27 以降の Linux カーネルに含まれて います。 o System Base ウェブサイト: Comtrol 社, Cyclades 社, Digi 社, Stallion 社の製品のレビューが Linux Journal 誌の 1995 年 6 月号に掲載されています。この記事は http://www.ssc.com/lj/issue14 で読むことができます。 5.6. 未対応のマルチポートボード 2000 年 1 月 1 日現在、以下のボードは Linux でのサポートが全く謳われて いません。状況が変化していたらお知らせください。 o Aurora (PCI 版のみ) 6. シリアルポートの設定 6.1. PCI バスへの対応は進行中です カーネル 2.2 のシリアルドライバは PCI バスへの特別な対応は入っていませ ん。しかし、カーネル 2.3 と 2.4 では、ついに一部の PCI シリアルカー ド(およびモデムカード)に対応します。多くの PCI カードは、ドライバによ る特殊なサポートが必要です。ドライバはカードにデジタル的に格納されてい る ID を読み込み、そのカードにどうやって対応するか(あるいはサポートす るかどうか)を決めます。確実に Windows モデムではないにもかかわらず動作 しない PCI カードをお持ちであれば、そのカード用のドライバを作る手助け ができます。これを行うには、シリアルドライバのメンテナである Theodore (Ted) Y. Ts'o さんに連絡する必要があります。しかし、まずは Windows モ デムの一覧のサイト を見 て、PCI モデムとそれに関連する話題の最新情報を調べてください。 また、Ted Ts'o には "lspci -vv" の出力のコピーと PCI モデム(またはシリ アルポート)のモデルとメーカーに関する詳しい情報を電子メールで送る必要 があります。そうすれば、彼は動作するかもしれないテスト用ドライバの場所 をできるだけ教えてくれるでしょう。次に、このドライバを入手してコンパイ ルします。カーネルも多分再コンパイルすることになるでしょう。そして、こ のドライバをテストしてうまく動作するかどうかを調べ、その結果を Ted Ts'o に報告します。上記の手順全てをちゃんと行うつもりがあるなら(そして この文書が最新版なら)、彼に必要な情報を送ってください。メールアドレス は です。 PCI モデムはあまり標準化されていません。一部のカードは PC との通信にメ インメモリを使います。8 桁の 16 進アドレスが表示されたら、そのカードは おそらく Linux では使えないでしょう。一部のカードは、特殊な方法を使わ ないと IRQ が有効になりません。"lspci" の出力を見れば、カードがサポー トされているかどうかを調べる役に立つでしょう。4 桁の I/O ポートが表示 され、長いメモリアドレスが表示されなければ、そのモデムは "setserial" で I/O ポートと IRQ を設定するだけで動作すると思います。この方法で 3COM 3CP5610 PCI モデムを動かすのに成功した人もいます。 6.2. 設定の概要 多くの場合、設定は自動的に行われるので、ユーザがすることは何もありませ ん。しかし場合によっては設定を行う必要があります(あるいは単に設定を確 かめるだけのこともあるでしょう)。こういった場合に最初にすべきこと は、Linux におけるシリアルポートの設定の 2 つの部分を知ることです。 最初の部分(低レベル設定)は、I/O アドレス、IRQ、名前(ttyS2 など)を割り 当てることです。この I/O と IRQ の組は、ハードウェアとシリアルドライバ の両方に設定しなければなりません。これを簡単に「I/O と IRQ の設定」と 呼ぶことにしましょう。setserial はドライバを設定するために使います。 PnP の機構やジャンパなどはハードウェアの設定に用います。詳しくは後述し ます。設定をする必要があるにも関わらず詳しいことが分かっていなければ、 すぐに問題に出会ってしまうでしょう。 2 番目の部分(高レベルの設定)は速度(38.4K ビット/秒など)の設定やフロー 制御の選択などです。これはしばしば PPP や minicom といった通信プログラ ムや、getty (他の人があなたのマシンにログインできるようにポート上で動 作します)が行います。しかし、こういったプログラムに対しては、希望する 速度等の設定をメニューや設定ファイルを使って行う必要があります。この高 レベルの設定は、 stty プログラムによっても行えます。stty は、問題があ る時に現在の状態を表示する際にも役立ちます。詳しくは ``stty'' の章をご 覧ください。 Linux が起動する時には、いくつかのシリアルポートの検出 と(低レベル)設定が試みられます。正確にどうなるのかは、お使いの BIOS, ハードウェア、 Linux ディストリビューション等によって違います。シリア ルポートがうまく動作しているならば、何もする必要はありません。アプリケ ーションプログラムはたいてい高レベルの設定を行ってくれますが、必要な情 報を与えてやる必要があるかもしれません。プラグ&プレイのシリアルポー ト(内蔵モデムに組み込まれることが多いです)では、事情はずっと複雑になり ます。低レベルの設定(IRQ と I/O アドレスの設定)が必要となる場合を以下 に示します: o 3 つ以上のシリアルポートを使う予定の場合 o 新しいシリアルポート(内蔵モデムなど)をインストールする場合 o シリアルポートで問題が起きた場合 バージョン 2.2 以降のカーネルでは、割り込みの共有を使えば低レベルの設 定を行わなくても 3 つ以上のシリアルポートを使うことができます。ただ し、これが動作するのはシリアルポートのハードウェアが割り込みの共有に対 応している場合だけですし、その設定もシリアルポートの低レベルの設定より 簡単とは言えません。 ``2.2 以降のカーネルと割り込みの共有'' をご覧くだ さい。 低レベルの設定(IRQ と I/O アドレスの設定)は、(高レベルの設定と比べる と) 比較的問題を起こしやすいようです。多くの場合は完全に自動で、何も設 定することがないのにです。そこで、この章の大部分はその話題を扱います。 シリアルドライバが正しい IRQ と I/O アドレスを知るまでは、ポートは全く 動作しません。Linux では検出さえされないでしょう。検出されたとしても、 IRQ が間違っていれば、動作は極めて遅いかもしれません。 ``この上なく遅 い: テキストがすごく遅れてゆっくり画面に表示されます'' を見てくださ い。 Wintel の世界では、I/O アドレスと IRQ は「リソース」と呼ばれます。した がって、我々は特定のリソースを設定していることになります。しかし、他の 種類の「リソース」がたくさんあるので、この言葉は他に色々な意味を持つこ とになります。復習になりますが、低レベルの設定は 2 つの値 (IRQ 番号と I/O アドレス)を 2 つの場所に設定することです: 1. デバイスドライバ(多くの場合、起動時に "setserial" を実行して設定し ます) 2. シリアルポートのハードウェアそのもののメモリレジスタ 起動(= ブート時)メッセージを見てください。これは通常は正しいです。しか し問題が起きている場合には、これらのメッセージの一部がハードウェアの正 しい設定を示していない(そして正しくないと思われる)可能性が高いです。 ``I/O アドレスと IRQ: 起動時のメッセージ'' をご覧ください。 6.3. 低レベル設定に関するありふれた間違い 多くの人がやってしまう一般的な間違いを示します: o setserial コマンド: (autoconfig オプションを付けずに) setserial を 実行し、ハードウェアも調べられたと思い込む(実際には調べられません) o setserial のメッセージ: 起動時に画面に表示されるメッセージを見て、 ハードウェアが実際に設定された結果だと間違って信じてしまう o /proc/interrupts: シリアルポートが使われていない時は、その割り込み は /proc/interrupts に現われないが、それを見てシリアルポートが見つ からない(あるいは割り込みが設定されていない)と誤って信じてしまう o /proc/ioports: このファイルが表示するのは setserial とほぼ同じ(つま り間違っている可能性のある)データでしかないのに、それが実際のハード ウェア設定だと思い込んでしまう 6.4. I/O アドレスと IRQ: 起動時のメッセージ 多くの場合、ポートの低レベルの設定は起動時に自動的に行われます(しかし 常に正しいとは限りません)。何が起きているか調べるには、画面上の起動 メッセージを見ましょう。Linux がロードされる前に BIOS が出すメッセー ジ(例は挙げません)の確認も怠らないでください。このような BIOS のメッセ ージの出力は Pause キーを押すと一時的に止めることができます。スクロー ルして流れてしまったメッセージを戻して見るには、Shift-PageUp キーを使 います。Shift-PageDown キーを押すと反対向きにスクロールします。 dmesg コマンドを使えばいつでも起動メッセージの一部を見ることができますが、大 事な部分が抜け落ちていることもよくあります。起動メッセージの例(1999 年 半ばの時点) を以下に示します: ttyS00 は /dev/ttyS0 と同じである点に注 意してください。 検出されたものが最初に表示されます(ただし IRQ は大雑把に推定したものに 過ぎません): Serial driver version 4.27 with no serial options enabled ttyS00 at 0x03f8 (irq = 4) is a 16550A ttyS01 at 0x02f8 (irq = 3) is a 16550A ttyS02 at 0x03e8 (irq = 4) is a 16550A 保存された値が後で表示されますが、これも正しいとは限りません: Loading the saved-state of the serial devices... /dev/ttyS0 at 0x03f8 (irq = 4) is a 16550A /dev/ttyS1 at 0x02f8 (irq = 3) is a 16550A /dev/ttyS2 at 0x03e8 (irq = 5) is a 16550A ちょっとした不一致がある点に注意してください。最初のメッセージでは IRQ=4 に ttyS2 があるように表示されていますが、二番目のメッセージでは IRQ=5 になっています。最初のメッセージしか表示されないかもしれません。 ほとんどの場合は最後に表示されるものが正しいメッセージです。しかし問題 がある場合には紛らわしいかもしれません。この章の残りに書かれているこの 難しいことの説明を読む前には、とりあえずシリアルポートを使ってみて、正 しく動作するかどうかを調べるとよいでしょう。ちゃんと動作しているなら ば、この先は特に読まなくてもかまいません。 2 番目のメッセージは、起動時に実行される setserial プログラムが出力し ます。このメッセージは、デバイスドライバが正しいと思っている設定を示し ます。しかし、これも間違っていることがあります。例えば、ハードウェアの IRQ が実際には IRQ=8 に設定されていることもあります(どちらのメッセージ も間違っている)。IRQ=5 が表示されるのは、誰かが間違ってその情報を設定 ファイルに入れたため(あるいはこれと同様の理由)かもしれません。 Linux が時々間違った IRQ を取得するのは、Linux が IRQ の探査を行わないからで す。 Linux は単に「標準」の IRQ を仮定するか(最初のメッセージ)、ユーザ が行った設定をそのまま使います(2番目のメッセージ)。この両者はいずれ も、正しいとは限りません。シリアルドライバの IRQ が間違っていると、シ リアルポートの動作が非常に遅くなったり、まったく動作していないように見 えたりします。 最初のメッセージは、Linux がシリアルポートの探査を行った結果ですが、 IRQ の探査は行われていません。ポートがここに現われた場合、そのポートは 存在しますが、IRQ は間違っていることがあります。 Linux が IRQ のチェッ クを行わないのは、どのみち完璧にはチェックできないためです。 Linux は IRQ が先に示した値であることを仮定します。なぜなら、これらが「標準的」 な値だからです。setserial に autoconfig オプションや auto_irq オプショ ンを付けて実行すると手動で確認を行えますが、これも正しいという保証はあ りません。 BIOS のメッセージに表示されるデータ(最初に表示される)はハードウェアに 設定されている値です。シリアルポートがプラグ&プレイならば、 isapnp を 実行してこれらの設定を変えることができます。Linux が起動した後に、これ に関するメッセージを探しましょう。先の例に挙げられている、最後のシリア ルポートのメッセージは、BIOS のメッセージと一致していなければなりませ ん(これは isapnp が変えているかもしれません)。一致しない場合には、ポー トのハードウェアの設定を変更するか、ハードウェアに実際に設定されている 内容を setserial を使ってドライバに教えなくてはなりません。 また、プラグ&プレイのシリアルポートをお使いの場合には、プラグ& プレイ のソフトウェアがハードウェア内部の IRQ と I/O を設定しなければ、 Linux はこれらを検出しません。これは、物理的に存在するシリアルポートが起動 メッセージで表示されない一般的な理由です。PC のハードウェア(PnP BIOS) はこのようなシリアルポートの低レベルな設定を自動的に行います。PnP の設 定は後で説明します。 6.5. シリアルポートの現在の I/O アドレスと IRQ の設定は? 前の節では、起動メッセージをみることにより設定を調べる方法を説明しまし た。起動メッセージで十分な情報が得られれば、この節を読む必要はありませ ん。情報が十分でなければ、これを調べる方法がいくつかあります。 「I/O と IRQ の設定はどうなっているの?」という問いへの答えは実際には 2 通りあります。1. デバイスドライバに設定されている値(これは普通は setserial コマンドで設定と表示を行います)。 2. 実際にハードウェアに設 定されている値。両者は同じ値でなければなりません。同じ値でなければ問題 が起こります。なぜなら、ドライバが物理的なシリアルポートに関して間違っ た情報を持つことになるからです。間違った I/O アドレスがドライバに設定 されていると、ドライバは存在しないポートにデータを送ろうとします。ある いはもっと悪いケースとしては、シリアルポートでない実在のポートにデータ を送ろうとします。間違った IRQ がドライバに設定されていると、ドライバ がシリアルポートからの割り込みサービス要求を受け取れずに、非常に遅かっ たり全く応答しなかったりします。この場合は、 ``この上なく遅い: テキス トがすごく遅れてゆっくり画面に表示されます'' の節をご覧ください。ドラ イバに設定されている UART のモデルが間違っている場合にも問題が起こりが ちです。I/O-IRQ の組がドライバとハードウェアで同じかどうかを確かめるに は、これらの値がどのように設定されているのかをドライバとハードウェアの 両方について調べなければなりません。 6.5.1. デバイスドライバの設定は? これを調べるのは簡単です。単に起動メッセージを見るか、 "setserial -g /dev/ttyS*" を実行するだけです。シリアルポートがうまく動作していれば、 この表示内容がハードウェアにも設定されているでしょう。この情報を調べる 別の方法としては、/proc ディレクトリにある「ファイル」を見る方法があり ます。このような別の方法を説明する重要な理由は、これらはデバイスドライ バに設定されている情報しか表示しないことに注意してもらうためです。一部 の人は、/proc ディレクトリにある特定のファイルを見て、これがハードウェ アに設定されていると勘違いしてしまいますが、「必ずしもそうではありませ ん」。 /proc/ioports は、ドライバが使っている I/O アドレスを表示します。 /proc/interrupts は、現在動作している(デバイスをオープンした)プロセス のドライバが使っている IRQ を表示します。上記のいずれの場合も、表示さ れるのはドライバの設定内容であり、ハードウェアの実際の設定内容では必ず しもありません。/proc/interrupts は、それぞれのデバイスに対して割り込 みがいくつ発行されたのかも表示します(数千個のこともよくあります)。この 情報から問題解決の手がかりをつかむことができます。なぜなら、大量の割り 込みが発行されていれば、その割り込みを使っているハードウェアがどこかに あるということだからです。割り込みが少ししか表示されないことは時に、そ の割り込みが実際にはどのシリアルポートによっても物理的に生成されていな いことを意味します。したがって、使おうとしているシリアルポートに対して ほとんど割り込みが発行されていなければ、ハードウェアには割り込みが設定 されていないかもしれず、つまりドライバが間違った割り込みを使っていると いうことかもしれません。現在実行中の("minicom" のような)プログラムを チェックするために /proc/interrupts を見るには、このファイルを見ている 間はずっとプログラムを実行し続ける必要があります。これを行うには、プロ グラムを終了せずにシェルに行ってみましょう。 6.5.2. シリアルポートのハードウェアの設定は? デバイスのハードウェアに実際にどの I/O アドレスと IRQ が設定されている のかを調べるにはどうすればいいのでしょうか? Linux が起動を始める前に、 もしかすると BIOS のメッセージがある程度の情報を教えてくれるかもしれま せん。 Shift-PageUp キーを使って起動メッセージの表示を戻し、BIOS が出 した一番最初のメッセージを見ましょう。これは Linux が起動する前の設定 です。 setserial はこの設定を変えることはできませんが、isapnp や pciutils は設定を変えられます。 大雑把な方法の一つとして、"autoconfig" オプションを付けて setserial に 検出を行わせてみる方法があります。この方法では、検出を行うアドレスを推 定する必要があります。``setserial とは何か?'' を見てください。PCI シ リアルポートの場合には、"lspci" コマンドを使ってください(2.2 より前の カーネルの場合は /proc/pci を見てください)。お使いのシリアルポートがプ ラグ&プレイならば、以下の 2 つの節を見てください。 ジャンパで設定したポートの場合は、これはジャンパで設定した内容です。ポ ートがプラグ&プレイ(PnP)ではないけれど DOS プログラムを使って設定され ている場合には、そのプログラムを実行した人が設定したように設定されてい ます。 6.5.3. PnP シリアルポートのハードウェアの設定は? PnP シリアルポートは、電源が切られた時に設定をハードウェアに保存しませ ん。これは、電源を切っても設定が変わらないジャンパ(非 PnP)と対照的で す。ISA PnP シリアルポートをお使いであれば、シリアルポートが全く I/O アドレスや IRQ を持たず、事実上使えない状態になる可能性があります。こ の場合でもまだ、pnpdump を使ってそのシリアルポートを見つけることが可能 なはずです。 ISA バスでのプラグ&プレイの場合、pnpdump (isapnptools に含まれていま す)を試すとよいでしょう。--dumpregs オプションを使うと、ポートに設定さ れている実際の I/O アドレスと IRQ が表示されるはずです。 pnpdump が 「試した」アドレスはデバイスの I/O アドレスではなく、特殊なものです。 PnP ポートの場合は、DOS/Windows での設定内容を調べてもあまり役に立ちま せん。Windows は設定情報をレジストリに保存しますが、これは Linux では 使われません。BIOS の不揮発性メモリにも Windows の情報が記憶されている こともありますが、レジストリ内にある Windows の現在の設定とは同期が取 れていないことがあります(??)。Linux の起動時に PnP BIOS に自動設定をさ せているのならば(そして Linux を起動する際には、PnP オペレーティングシ ステムでないと BIOS を設定しているならば)、Linux は BIOS の不揮発性メ モリ内の設定を使うはずです。 6.6. シリアルの IRQ の選択 OS か PnP BIOS が全てのデバイスを設定するという本物のプラグ&プレイ設定 を行っているならば、IRQ を選ぶことはありません。PnP は最も良いと思われ る割り当てを選んでこれを設定します。しかし、Linux でプラグ &プレイ用の ツール(isapnp と pcitools)を使っている場合には、IRQ の選択を行う必要が あります。使いたい IRQ を既に知っている場合には、この節を飛ばしてもか まいませんが、IRQ 0 の使い方が特殊であることだけは知っておいてくださ い(次の段落を読んでください)。 6.6.1. IRQ 0 は IRQ ではない IRQ 0 は実際には(ハードウェアでは)タイマですが、setserial を使ったシリ アルポートの設定においては特殊な意味を持っています。この指定は、そのポ ートには割り込みがないことをドライバに伝え、ドライバはポーリングを使っ た動作を行います。ポーリングは非常に効率が悪いのですが、割り込みが衝突 した場合や、割り込みの設定ミスがあった場合には試すとよいでしょう。 IRQ 0 を設定する利点は、ハードウェアに設定されている割り込み番号を知る必要 がない点です。IRQ 0 は、実際に使える割り込みが見つかるまでの急場をしの ぐためだけに使うべきです。 6.6.2. 割り込みの共有とバージョン 2.2 以降のカーネル 一般的な規則では、全てのデバイスが固有の IRQ を持ち、IRQ の共有を行わ ないことになっています。しかし大抵のマルチポートを使う場合のように、 IRQ の共有が許されている場合もあります。ただし、共有が許されているとし ても、効率は良くないかもしれません。というのも、共有されている割り込み が与えられる度に、どこで割り込みが発行されたのかを調べなければならない からです。したがって、可能であれば、全てのデバイスに固有の割り込みを与 えるといいでしょう。 バージョン 2.2 より前のカーネルでは、IRQ はほとんどのマルチポートボー ド同士だけでしか共有できませんでした。バージョン 2.2 以降のカーネル は、場合によっては全てのシリアルポートで IRQ を共有できます。バージョ ン 2.2 のカーネルで共有を動作させるには、CONFIG_SERIAL_SHARE_IRQ を設 定してカーネルをコンパイルしなければなりません。また、シリアルポートの ハードウェアも共有に対応していなければなりません(対応していれば、2 つ のシリアルカードが 1 つの割り込み線に異なる電圧を流しても、「これが割 り込みです」という意味の電圧しか受け取られません)。よってバージョン 2.2 のカーネルであっても、割り込みの共有はしない方が良いかもしれませ ん。 6.6.3. どの IRQ を選ぶか? シリアルポートのハードウェアには、限られた IRQ しか設定できないことが よくあります。しかし IRQ が衝突するのも嫌でしょう。したがって、選択の 余地はあまりありません。PC では普通、ttyS0 と ttyS2 が IRQ4 に、ttyS1 と ttyS3 が IRQ 3 にあります。 /proc/interrupts を見れば、現在動作中の プログラムが使っている IRQ がどれかわかります。このような IRQ は使わな い方がいいでしょう。IRQ 5 がサウンドカードに使われるようになる前には、 シリアルポートでもよく使われていました。 以下に、Greg (Serial-HOWTO の元々の著者)がどのように /etc/rc.d/rc.serial を設定しているかを示します。rc.serial は起動時に実 行されるファイル(シェルスクリプト)です(場所や名前は違うことがありま す)。バージョン 2.15 より後の "setserial" では、必ずしもこのように設定 が行われるわけではありませんが、これは IRQ の選択の例にもなります。 /sbin/setserial /dev/ttyS0 irq 3 # シリアルマウス /sbin/setserial /dev/ttyS1 irq 4 # Wyse 製のダム端末 /sbin/setserial /dev/ttyS2 irq 5 # Zoom 製のモデム /sbin/setserial /dev/ttyS3 irq 9 # US Robotics 製のモデム 標準の IRQ 割り当てを示します: IRQ 0 タイマチャネル 0 (「割り込み無し」を意味することもあります。詳しくは後述します) IRQ 1 キーボード IRQ 2 コントローラ 2 へのカスケード IRQ 3 シリアルポート 2 IRQ 4 シリアルポート 1 IRQ 5 パラレルポート 2, サウンドカード IRQ 6 フロッピーディスク IRQ 7 パラレルポート 1 IRQ 8 リアルタイムクロック IRQ 9 IRQ2 にリダイレクト IRQ 10 割り当て無し IRQ 11 割り当て無し IRQ 12 割り当て無し IRQ 13 数値コプロセッサ IRQ 14 ハードディスクコントローラ 1 IRQ 15 ハードディスクコントローラ 2 割り込みを選ぶための決定的な方法はありません。割り込みをマザーボード や、他のボードが使っていないことを確かめるしかありません。2, 3, 4, 5, 7, 10, 11, 12, 15 を選ぶことができます。IRQ 2 と 9 は同じであることに 注意してください。IRQ 2 と 9 のどちらを使っても、シリアルドライバはこ れをうまく認識します。非常に古いシリアルボードをお使いの場合には、8 以 上の IRQ は使えないかもしれません。 IRQ 1, 6, 8, 13, 14 は使わないでください! これらの IRQ はマザーボード が使うからです。マザーボードが使っている IRQ を取り上げると、とても悲 しいことになります。設定が終わったら、割り込みを使うプログラムを実行す る時に /proc/interrupts を再確認し、IRQ の衝突が起こっていないことを確 かめてください。 6.7. アドレスの選択 --ttyS3 と衝突するビデオカード IBM 8514 ビデオカード(とその類似品)の I/O アドレスは、聞くところでは 0x?2e8 です(? は 2, 4, 8, 9 のいずれか)。16 進値の先頭の 0 である桁を シリアルポートが無視する場合には(多くの場合はそうです)、これは 0x02e8 にある ttyS3 と衝突するかもしれません(しかし、シリアルポートがうまく設 計されていれば衝突しないはずです)。このアドレスで ttyS3 を使おうとして いる場合には、これは悪い知らせです。 ほとんどの場合は、可能であればデフォルトのアドレスを使うべきです。ここ で言うアドレスは、8 バイトの範囲の最初のアドレスを表しています。例え ば、 3f8 は実際には 3f8-3ff の範囲です。それぞれのシリアルデバイス は(I/O アドレスを必要とする他のタイプのデバイスと同じく)固有のアドレス 範囲を必要とします。これは重なっては(衝突しては)いけません。シリアルポ ートのデフォルトのアドレスを以下に示します: ttyS0 のアドレス 0x3f8 ttyS1 のアドレス 0x2f8 ttyS2 のアドレス 0x3e8 ttyS3 のアドレス 0x2e8 6.8. I/O アドレスと IRQ のハードウェアへの設定 (主に PnP 向け) I/O アドレスと IRQ をハードウェアに設定した後には、setserial を使って ドライバを設定することも忘れないでください。非 PnP のシリアルポートの 場合には、ポートのハードウェアの設定はジャンパか、("ジャンパレス"の場 合には)設定を行うための DOS プログラムの実行によって行います(このプロ グラムで PnP が無効になるかもしれません)。PnP シリアルポートを設定する 際に考えられる方法のリストを以下に示します: o PnP BIOS の CMOS 設定メニューを使う(普通は ttyS0 (Com1) と ttyS1 (Com2) にある外付けデバイスだけに使います) o PnP BIOS に PnP シリアルポートを自動的に設定させる。 ``PnP BIOS を 使った I/O アドレスと IRQ の設定'' を参照してください o PnP シリアルポートと PnP 対応の Linux を使っているならば何もしなく てかまいません(Plug-and-Play-HOWTO を参照) o PCI でない PnP シリアルポートの場合には isapnp を用いる o PCI バスの場合には pciutils (pcitools) を用いる I/O アドレスと IRQ は電源を入れる度に(PnP を使って)シリアルポートのレ ジスタに設定しなければなりません。というのも、PnP ハードウェアは電源が 切られた時の設定内容を覚えていないからです。これを行う簡単な方法は PnP OS を使っていないと PnP BIOS に教えてやることで、そうすると起動の度に BIOS が自動的に設定を行います。ただし、(PnP OS である)Windows を「PnP OS ではない」と BIOS に認識させたまま Windows を起動すると、Windows 側 で問題が発生するかもしれません。詳しくは Plug-and-Play-HOWTO をご覧く ださい。 プラグ&プレイは I/O と IRQ の設定を自動化するために設計されました。し かし現時点の Linux では、話をややこしくしているだけです。標準の Linux カーネルはプラグ&プレイをあまりうまくサポートしていません。 Linux カー ネルをプラグ&プレイ OS にするパッチを使っているならば、上記のことは全 て OS が自動的に処理できるはずです。しかし、シリアルポート以外のデバイ スの設定を自動化するためにこのパッチを使ったとしても、手動でドライバの 設定をしなければならないかもしれません。というのも、Linux のドライバの 多くは PnP 対応の Linux 向けに書かれていないからです。isapnptools や BIOS を使ってプラグ&プレイの設定を行っているならば、これは 2 つの値を モデムカードのシリアルポート部分のレジスタに設定するだけなの で、setserial の設定はユーザが行う必要があるでしょう。1999 年初めの時 点では、これらの設定は簡単でもありませんし、詳しい文書もありません。 Plug-and-Play-HOWTO と isapnptools FAQ をご覧ください。 6.8.1. PnP BIOS を使った I/O アドレスと IRQ の設定 PnP OS や isapnp を使って I/O と IRQ の設定を行う方法の説明はそれらの ソフトウェアに付いてくるはずですが、PnP BIOS にそういった設定をさせよ うと思っている場合にはそうはいきません。全ての PnP BIOS がこれを行える わけではありません。BIOS には普通、最初の 2 つのシリアルポートを設定す るための CMOS メニューがあります。このメニューは見つけにくいかもしれま せんが、Award 製の BIOS ならば "chipset features setup" の下にありま す。多くの場合、ここではほとんど何も選べません。他のものがメニューにな ければ、最初の 2 つのシリアルポートには標準の I/O アドレスと IRQ が設 定されます。``シリアルポートデバイスの名前と番号''をご覧ください。 好むと好まざるとに関わらず、PC を起動すると PnP BIOS が PnP によるハー ドウェアデバイスの(I/O と IRQ の)設定を始めます。PnP BIOS が行う処理が 不十分で、残りの設定が(読者の皆さんがおそらく持っていない) PnP OS に残 されるかもしれません。あるいは PnP OS を持っていないと設定されている場 合には、全ての PnP デバイスを完全に設定するかもしれませんが、デバイス ドライバの設定は行いません。これは読者の皆さんが望む動作ですが、PnP BIOS が行った設定を正確に調べることは必ずしも容易ではありません。 PnP OS を持っていないことを BIOS に設定してあれば、PnP BIOS は最初の 2 つだけでなく全ての PnP シリアルポートの設定を行うはずです。 BIOS の動 作を間接的に制御する方法は(もし MS Windows9x を同じ PC で使っていれ ば)、Windows における設定を「強制」することです。 Plug-and-Play-HOWTO を「forced」で検索してください。Windows 上で「強制」した設定を CMOS BIOS メニューを使って上書きするのは簡単です。この「上書き」機能の設 定・解除が行える BIOS オプションがあると思います。 新しい PnP デバイスが追加されると、BIOS は PnP 設定を変更して調整を行 わなければなりません。衝突を避ける必要が生じれば、既存のデバイスの I/O と IRQ の設定が変わることもあります。この目的のため、非 PnP デバイスの I/O と IRQ をどのように設定しているのかを BIOS に教えてあれば、BIOS は 非 PnP デバイスのリストを保存しています。これを BIOS に教える方法の一 つは、DOS/Windows 上で ICU と呼ばれるプログラムを実行することです。 しかし、この情報でデバイスドライバを設定するために、BIOS が行った設定 を調べるにはどうすればよいでしょうか? BIOS 自身もある程度の情報を出し ます。これは設定メニューや、コンピュータの起動時に画面に現われるメッセ ージを通じて得られます。 ``シリアルポートのハードウェアの設定は?'' を ご覧ください。 6.9. IRQ と I/O アドレスを setserial に与える いったんハードウェアの IRQ と I/O アドレスを設定したら(あるいは PnP で 割り当てられるようにしたら)、今度は Linux が起動される度に "setserial" コマンドが実行されるようにする必要があります。 ``起動時の設定''の節を ご覧ください。 6.10. 高レベルの設定: stty など 原則としては、アプリケーションプログラムが設定の大部分(あるいは全て)を 行います。これを行うコマンドは stty です。 ``stty'' をご覧ください。 6.10.1. フロー制御の設定: ハードウェアフロー制御がベストです 解説が``フロー制御''にあるので、そちらもご覧ください。普通は Xon/Xoff を使ったソフトウェアフロー制御よりもハードウェアフロー制御を使う方がい いでしょう。完全なハードウェアフロー制御を用いるには普通、シリアルポー トとデバイスを接続するケーブル内にフロー制御用の線が 2 本必要です。デ バイスがカード上にあるならば、確実にハードウェアフロー制御が使えるはず です。 多くのアプリケーション(と getty プログラム)には、フロー制御に関するオ プションがあり、必要に応じて設定できます。デフォルトでハードウェアフロ ー制御を設定することもできます。IRQ と I/O アドレスのように、フロー制 御もシリアルドライバとシリアルポートに接続されているハードウェアの両方 に設定しなければなりません。ハードウェアの設定方法は、ハードウェアに よって異なります。多くの場合は、PC からシリアルポート経由でハードウェ アデバイスに送る特定の「初期化文字列」があります。モデムの場合は、通信 プログラムは両方の設定を行うはずです。 お使いのプログラムがシリアルドライバのフロー制御を設定しない場合には、 stty コマンドを使って自分で設定できます。ドライバは Linux が停止した時 の設定を覚えていないので、起動時やログイン時に実行されるファイル(シェ ルが bash の場合には /etc/profile など)に stty コマンドを入れておくと よいでしょう。以下にポート ttyS2 でハードウェアフロー制御を行うために 追加する内容を示します: stty crtscts < /dev/ttyS2 stty のバージョンが 1.17 以上の場合は: stty -F /dev/ttyS2 crtscts crtscts は、シリアルポートの RTS と CTS ピンを使ってハードウェアフロー 制御を行う設定の指定を表します。前の文の大文字を crtscts と綴ります。 7. シリアルポートデバイス: /dev/ttyS2 等 デバイスディレクトリにデバイスを作成する方法については ``/dev ディレク トリにおけるデバイスの作成方法'' をご覧ください。 7.1. シリアルポートデバイスの名前と番号 Linux のデバイスはメジャー番号とマイナー番号を持っています。シリアルポ ートはそれぞれ、/dev ディレクトリで 2 つの名前を持つ可能性があります。 すなわち ttyS と cua です。これらのドライバは少し異なった動作をしま す。cua デバイスは使わないことが勧められており、将来は使われなくなりま す。Modem-HOWTO の「cua デバイス」の章をご覧ください。 DOS/Windows は COM という名前を使いますが、setserial プログラムでは tty00, tty01 といった名前を使います。これらを dev/tty0, dev/tty1 等と 混同しないでください。dev/tty0 等はコンソールデバイス(PC のモニタ)の名 前であり、シリアルポートではありません。以下の表はアドレスの「標準的 な」対応を示します(読者の皆さんの場合は異なるかもしれません)。 I/O DOS メジャー マイナー メジャー マイナー アドレス COM1 /dev/ttyS0 4, 64; /dev/cua0 5, 64 3F8 COM2 /dev/ttyS1 4, 65; /dev/cua1 5, 65 2F8 COM3 /dev/ttyS2 4, 66; /dev/cua2 5, 66 3E8 COM4 /dev/ttyS3 4, 67; /dev/cua3 5, 67 2E8 全てのディストリビューションに ttyS デバイスが付いているはず(多くの ディストリビューションには古い cua デバイスもあるはず)である点に注意し てください。これは以下のコマンドを実行すれば確かめられます(古い cua デ バイスがなくても心配する必要はありません): linux% ls -l /dev/cua* linux% ls -l /dev/ttyS* 7.2. ttySN から /dev/modem にリンクを張るべきかどうか 一部のインストーラは 2 つの追加デバイスを作ります。すなわちモデム用の /dev/modem とマウス用の /dev/mouse です。どちらも /dev ディレクトリに ある適切なデバイスへのシンボリックリンクです。このリンク先のデバイスは インストール時に選択されています (ただしバスマウスの場合はこの限りでは なく、/dev/mouse はバスマウスのデバイスへのリンクとなります)。 /dev/mouse と /dev/modem の利点については、過去に何度も議論がありまし た。これらのリンクの使用はお勧めできません。特に、モデムをダイアルイン 用に使おうと考えている場合には、 /dev/modem を用いるとロックファイルが 正しく動作しないことがあり、問題が起きるかもしれません。しかし、リンク を張り直したり削除した場合には、一部のアプリケーションは再設定が必要に なるかもしれません。 7.3. マルチポートボードに関する注意 ボードの アドレスと IRQ については、setserial プログラムに付属している rc.serial や /etc/rc.boot/0setserial を見てください。マルチポートボー ドについては I/O アドレスやデバイス名を含む細かい話がたくさんありま す。 7.4. /dev ディレクトリにおけるデバイスの作成方法 デバイスが存在しなければ、mknod コマンドを使ってこれを作成しなければな らないでしょう。例えば ttyS0 に対するデバイスを作成する必要があるとし ます: linux# mknod -m 666 /dev/cua0 c 5 64 (cua デバイスは既に過去のものです) linux# mknod -m 666 /dev/ttyS0 c 4 64 MAKEDEV スクリプトを使うこともできます。このスクリプトは /dev ディレク トリにあります。マニュアルページを見てください。このスクリプトを使う と、デバイスを簡単に作成できます。例えば ttyS0 に対応するデバイスを作 る必要がある場合には、以下のコマンドを実行します: linux# cd /dev linux# ./MAKEDEV ttyS0 このスクリプトはデバイスの作成処理と正しいパーミッションの設定を行いま す。 8. 知っておくとよい便利なプログラム getty に関する情報のほとんどは Modem-HOWTO に移動しました。端末に直接 接続する getty の使用法に関する情報が Text-Terminal-HOWTO に少し書かれ ています。 8.1. シリアルポートの監視/診断用のプログラム 各種モデム制御線を監視し、これが正(1 または緑)であるか負(0 または赤) であるかを示すプログラムがいくつかあります。 o modemstat (Linux の PC コンソール上でしか正しく動作しません。小さい ウィンドウで状態を表示します。色付きですし、コンパクトです。終了す るには kill しなければなりません) o statserial (画面全体を使って情報を表示します) o serialmon (RTS, CTS, DSR の監視は行いませんが、他の機能のログを残し ます) これらのプログラムのいくつかは既に使えるようになっているかもしれま せん。そうでない場合には、シリアル用ソフトウェア から入手してくだ さい。1998 年 6 月の時点では、筆者は Linux 用のシリアルポート監視プ ログラムを知りません。 8.2. 割り込みの優先度の変更 o irqtune はシリアルポートの割り込みの優先度を高くし、効率を向上させ ます。 o ハードディスクのチューニングを行う hdparm があればさらに便利でしょ う。 8.3. setserial とは何か? この節は 3 つの HOWTO(Modem, Serial, Text-Terminal)に入っています。 HOWTO によって内容が多少異なります。 8.3.1. はじめに ラップトップ機(PCMCIA)では絶対に setserial を使わないでください。 setserial は、シリアルポートの I/O アドレスやポートのハードウェアに設 定されている割り込み(IRQ)、使用している UART の種類等をデバイスドライ バのソフトウェアに伝えられるようにするプログラムです。このプログラム は、現在ドライバに設定されている内容の表示も行います。加えて、ハード ウェアを探査して UART の種類や IRQ を調べさせることもできますが、これ には厳しい制限があります。 ``探査''の節を見てください。 setserial は PnP シリアルポートのハードウェアの IRQ 等を設定できない点に注意してく ださい。 組み込みのシリアルポートが 1 つか 2 つしかなければ、普通は setserial を使わなくても正しく設定されます。シリアルポートがこれ以上ある場合(ま たはシリアルポートに問題がある場合)には、setserial を使う必要があるで しょう。 setserial のマニュアルページ以外にも、 /usr/doc/setserial.../ や /usr/share/doc/setserial の情報を調べてください。お使いの Linux ディストリビューションでの setserial の扱いが書かれているはずです。 setserial はドライバに IRQ 等を割り当てるために、多くの場合は起動時に 起動スクリプトが自動的に実行します。 setserial は serial モジュールが ロードされている場合(または同等の機能がカーネル構築時に組み込まれてい る場合)にしか動作しません。 (何らかの理由で)serial モジュールを後から アンロードすると、カーネルは以前に setserial で行った設定を忘れます。 したがって、設定を元に戻すためには setserial を再び実行しなければなり ません。起動スクリプト経由での実行に加え、serial モジュール(など)がロ ードされた時には setserial に似た何らかのプログラムも実行されます。し たがって、画面上で起動メッセージを見る時に setserial が 2 度実行された ように見えるかもしれませんが、実際に 2 度実行されているのです。 setserial を使って、ポートがクローズされた後に動作し続ける時間を設定す ることができます(これは、メイン RAM 上のバッファにまだ残っている文字を 全て出力させるためです)。この設定はボーレートが遅い(1200 以下)場合には 必要です。また「フロー制御」によるウェイトが多くかかる場合には、速度が 速くても必要となります。マニュアルページの "closing_wait" を見てくださ い。 setserial は、シリアルポートのハードウェアそのものの IRQ や I/O アドレ スの設定は行いません。ハードウェアの設定は、ジャンパまたはプラグ &プレ イで行います。setserial には、ハードウェアに既に設定されているのと同じ 値を指定しなければなりません。使えると思うアドレスを勝手にでっちあげ て、それを setserial に教えてはいけません。しかし、I/O アドレスが分 かっているけれど IRQ が分からない場合には、setserial に IRQ を調べるよ うに指示することもできます。 使用可能なコマンドの一覧は、単に引き数無しで setserial を実行すれば表 示されます。このコマンドは、トラブル処理の際に普通使う詳細表示オプショ ンである -v のような 1 文字オプションは表示できません。 setserial では I/O アドレスのことを「ポート」と呼ぶ点に注意してください。 setserial -g /dev/ttyS* を実行すると、そのポートに関するデバイスドライバの設定状況が表示されま す。詳しい情報を表示させるには "-g" オプションに "-a" を追加します。た だし、ほとんどの人はこの追加の情報を扱う(あるいは理解する)必要はありま せん。なぜなら普通はデフォルトの設定で十分だからです。普通の場合は、ハ ードウェアは "setserial" が報告するのと同じ設定になっていますが、問題 がある場合には、"setserial" が間違っている可能性が高いでしょう。実 際、setserial を実行して全く嘘の I/O ポートアドレスや IRQ, UART を設定 することができます。それ以降に "setserial ..." を実行すると、この嘘の 値がエラーメッセージもなしに表示されます。もちろん、このような間違った 値ではシリアルポートドライバは(動くとしても)正しく動作しません。 setserial による設定は PC の電源を切ると消えますが、PC の電源を再び入 れた時には設定ファイルの情報(または前の設定)が残っているかもしれませ ん。最近のバージョンでは setserial を使って変更した設定は自動的に設定 ファイルに保存されます。古いバージョンでは、設定ファイルはユーザが手で 編集した時しか内容が変わらないので、何度起動しても同じ設定が使われま す。``設定スクリプト/ファイル''の節を見てください。 8.3.2. 探査 適切なオプションを使えば、setserial は(指定された I/O アドレスについ て)シリアルポートを探査できますが、そのためには I/O アドレスを推定しな ければなりません。例えば setserial に /dev/ttyS2 を探査させる と、setserial は ttyS2 があるとコマンド自身が思っているアドレス (2F8)しか探査しません。ttyS2 が別のアドレスにあることを setserial に指 示した場合は、setserial はそのアドレスを探査します。 ``探査''の節を見 てください。 setserial の目的は UART がそこにあるかどうか調べ、もし UART があればそ の IRQ を調べることです。"setserial" は最後の手段として使ってくださ い。というのも、こういったことを行うにはもっと早い方法 (モデムの検出に wvdialconf を使ったり、起動メッセージのごく最初の部分を見たり、pnpdump --dumpregs を使う等)があるからです。物理的なハードウェアの検出を試す場 合には、setserial の -v オプション(詳細表示)と autoconfig コマンドを 使ってください。得られる出力が 16550A といった UART の種類であれば成功 です。逆に UART の種類について "unknown" と表示された場合には、その I/O アドレスにはシリアルポートは全くないと思われます。一部の安物のシリ アルポートはうまく認識されないので、"unknown" と表示されてもそこにシリ アルポートが存在することもあります。 setserial は UART の種類の自動検出以外にも IRQ の自動検出ができます が、これも必ずしも正しく動作するとは限りません。バージョン 2.15 以上の setserial では最後の探査の結果は保存され、設定ファイル /etc/serial.conf に格納されるかもしれません。このファイルは、次に Linux を起動する時に使われます。起動時に serial モジュールがロードされ る等した時は、UART の探査は自動的に行われ、その結果が画面に出力されま す。しかし、表示される IRQ は間違っているかもしれません。同じものをも う一度出力させた時に得られるのは、普通は探査を行わず、したがってハード ウェアの実際の設定について信頼できる情報を出力しないスクリプトの実行結 果です。単に誰かがスクリプトに書き込んだ設定データか /etc/serial.conf に保存された設定データが表示されているだけです。 2 つのシリアルポートのハードウェアに同じ I/O アドレスが設定されている ことがあります。もちろんこれは認められていないのですが、実際にそういう ことは起こります。一つのアドレスに実際にシリアルポートが 2 つある時 も、探査では一つのシリアルポートしか検出されません。しかし、違う IRQ が設定してあれば、IRQ の探査で IRQ = 0 が表示されるかもしれません。筆 者の場合は、こうなったのは最初に setserial を使って嘘の値を設定した時 だけです。 8.3.3. 起動時の設定 カーネルが serial モジュールをロードする時(または「モジュール相当のも の」がカーネルに組み込まれている場合)には、ttyS{0-3} だけが自動検出さ れ、ドライバは IRQ 4 と 3 しか使わないように設定されます( ハードウェア に実際に設定されている IRQ に関わらず)。これは setserial を実行したと きのように、起動メッセージとして表示されます。3 つ以上のシリアルポート を使っていると、IRQ の衝突が起きてしまうかもしれません。 正しい IRQ を setserial に教えてこういった衝突を回避するために(あるい は別の理由のために)、setserial を再び実行するファイルがどこかにあるか もしれません。これはシリアルポートを使う他のどのプロセスよりも前に、起 動の最初の方のステップで実行されます。実際、読者の皆さんが使っている ディストリビューションでも、起動時に setserial プログラムが起動スクリ プトから自動的に実行されるように設定されているかもしれません。お使いの ディストリビューションでの扱い方についての詳しい説明は、 /usr/doc/ や /usr/share/doc/ というディレクトリにある "setserial..." のような名前の ファイルに書かれているかもしれません。 8.3.4. 設定スクリプト/ファイル ここでの目的は /etc ツリーにあって起動時に setserial を実行するスクリ プトを修正(または作成)することです。ほとんどのディストリビューションに はそのためのファイルが付属しています(しかし最初は /etc ツリーに置かれ ていないかもしれません)。さらに、バージョン 2.15 以降の setserial は大 抵 /etc/serial.conf ファイルを持っています。これは setserial を実行す るスクリプトが使うファイルで、ユーザがスクリプトを直接編集する必要をな くすためのものです。さらに、 (バージョン 2.15 以降では)コマンドライン から setserial を使うだけで最終的に設定ファイルを変更できます。 したがって、バージョン 2.15 より前ならばすべきことはスクリプトを編集す ることだけです。バージョン 2.15 以降では、次の 3 つの作業のどれかを行 えば大丈夫です: 1. スクリプトを編集する。 2. /etc/serial.conf を編集す る。 3. コマンドラインから "setserial" を実行し、自動的に /etc/serial.conf を編集させる。このうちのどれを使う必要があるかは、お 使いのディストリビューションや設定の方法によります。 8.3.5. スクリプトの編集 (バージョン 2.15 以降ではたぶん使いません) setserial のバージョンが 2.15 (1999年)より前の場合、setserial の設定に は /etc/serial.conf は使われません。したがって、起動時に "setserial" を実行しているファイルを探し、これを編集する必要があります。このような ファイルが存在しなければ、新しく作る(または起動の初期段階に実行される ファイルにコマンドを追加する)必要があります。このようなファイルが現在 使われているなら、/etc ディレクトリツリー内のどこかにあるでしょう。し かし、バージョン 6.0 より前の RedHat ではこのファイルは /usr/doc/setserial/ に置かれているので、使う前には /etc ツリーに移動さ せる必要があります。このようなファイルを見つけるには "locate" コマンド を使うとよいでしょう。例えば、'locate "*serial*" ' のように入力しま す。 以前は /etc/rc.d/rc.serial というスクリプトが一般的に使われていまし た。Debian は /etc/rc.boot/0setserial を使っていました。かつては /etc/rc.d/rc.local というファイルも使われていましたが、このファイルは あまり早くは実行されないので、適切とは言えませんでした。rc.local が実 行されるよりも前に他のプロセスがシリアルポートをオープンしようとして、 シリアル通信が失敗するという問題が報告されました。 このようなファイルが用意されていれば、その中にはコメントアウトされた指 定例がたくさん入っているはずです。これらの一部をアンコメントしたり修正 することにより、正しい設定を行えるはずです。 setserial へのパスが正し いことと、デバイス名が正しいことを確かめてください。このファイルを手で 実行して(単にスーパーユーザとしてファイル名を入力します)正しく動作する かどうか調べることにより、テストを行うことができます。こういったテスト は何度も再起動して正しい設定にするよりもずっと早く行えます。もちろん、 コマンドラインから setserial を実行することによりコマンド単独のテスト も行えます。 ttyS3 について UART や IRQ を自動的に setserial に調べさせたければ、以 下のような指定を追加します。 /sbin/setserial /dev/ttyS3 auto_irq skip_test autoconfig 自動的に設定したい全てのシリアルポートに対してこれを行ってください。実 際にマシン上に存在するデバイス名を必ず使ってください。場合によっては、 これはハードウェアのせいで正しく動作しないので、IRQ や UART の実際の設 定がわかっているのなら、"setserial" を使って明示的にこれらの値を割り当 てるとよいでしょう。例えば、 /sbin/setserial /dev/ttyS3 irq 5 uart 16550A skip_test のようにします。 バージョンが 2.15 以降の場合(お使いのディストリビューションが変更を 行っている場合。RedHat は行っていません)には、これを行うのは比較的面倒 かもしれません。というのも、起動時に setserial を実行するファイルであ る /etc/init.d/setserial 等はユーザが編集するためのファイルではないか らです。 ``/etc/serial.conf を用いる新しい設定方法'' の節を見てくださ い。 8.3.6. /etc/serial.conf を用いる新しい設定方法 バージョン 2.15 より前の setserial では、setserial の設定方法は、起動 時に setserial を実行するシェルスクリプトを手で編集することでした。 ``スクリプトの編集 (バージョン 2.15 以降ではたぶん使いません)'' の節を 見てください。バージョン 2.15 (1999 年) 以降の setserial では、この シェルスクリプトは編集されないことになり、設定ファイルである /etc/serial.conf からデータを読み込むようになりました。さらには serial.conf を編集する必要さえないこともあります。なぜな ら、"setserial" コマンドをコマンドラインで使うと、 serial.conf は自動 的にきちんと編集されるからです。 この方式なら、わざわざ設定(あるいは設定変更)のためにファイルを編集しな くても、Linux を起動する度に setserial を正しく動作させられます。ただ し大きな落とし穴があります。というのも、serial.conf を編集するのは実際 には "setserial" ではないということです。ディストリビューションごとに 扱いが違うため話はなおさらややこしくなっています。さらに、動作を変える ためにユーザが serial.conf を編集することもできます。 よく起こるのはこういうことです: ユーザが PC をシャットダウンした時、起 動時に "setserial" を実行するスクリプトは再び実行されますが、今回は "stop" の分岐に書かれている部分しか実行しません。この部分は "setserial" を使って "setserial" の現在の状態を調べ、この情報を serial.conf ファイルに書き込みます。したがって、"setserial" を実行して serial.conf ファイルを変更しようとしても、変更は即座に行われるのではな く、マシンを正常にシャットダウンした時にしか行われません。 ここまでくればどういう問題が起こる可能性があるのか想像がつくかもしれま せん。シャットダウンが正常にできず(誰かが電源スイッチを切る等)、変更が 保存されなかった場合を考えてください。また、"setserial" で試行錯誤をし ていて、最後に元の状態に戻すのを忘れていた場合(または元の状態に戻す時 にミスをした場合)を考えてください。すると「試行錯誤中」の設定が保存さ れてしまいます。 手動で serial.conf を編集すれば、編集した部分はシャットダウンの時に破 棄されます。なぜなら、シャットダウンの時にその時点の setserial の状態 に戻されるからです。シャットダウンの時に serial.conf を変更させないた めの方法もあります。serial.conf の最初の行に書かれている "###AUTOSAVE###" といった部分を削除するのです。すくなくともあるディス トリビューションでは、インストール直後の初めてのシャットダウンの時に最 初の行から "###AUTOSAVE###" を削除することは自動的に行われます。 serial.conf にはたぶん、参考になる情報がコメントの形で書かれているで しょう。 起動時に(設定ファイルに従って) setserial を実行するために通常使われる ファイルは、/etc/init.d/setserial (Debian) や /etc/init.d/serial (Redhat) 等ですが、普通はこのファイルを編集すべきではありません。バー ジョン 2.15 を使っている RedHat 6.0 では、起動時に setserial を実行さ せたい場合に /etc/init.d/ に移動させる /usr/doc/setserial-2.15/rc.serial ファイルが付いています。 ポートを無効にするには setserial を使って "uart none" を設定しま す。/etc/serial.conf のフォーマットは、コマンドラインで "setserial" の 後に置くパラメータとほぼ同じものを各ポートについて 1 行ずつ書く形式で す。自動保存を行っていなければ、/etc/serial.conf を手で編集してくださ い。 BUG: 1999 年 7 月の時点では、###AUTOSAVE### に由来するバグ/問題があり ます。これは "setserial -Gg /dev/ttyS*" で表示される setserial のパラ メータしか保存されず、他のパラメータが保存されないというもので す。"setserial" の全てのパラメータを表示させるには -a フラグを使いま す。これはごく一部のユーザにしか影響を与えないでしょう。というのも普 通、保存されないパラメータはほとんどの場合はデフォルト値で大丈夫だから です。これはバグとして報告されているので、現在は修正されているかもしれ ません。 setserial で設定した現在の設定をシャットダウンすることなく設定ファイル (serial.conf)に保存するには、シャットダウンの時に通常行われる処理をさ せます。つまり、シェルスクリプト /etc/init.d/{set}serial stop を実行し ます。 "stop" コマンドにより現在の設定が保存されますが、シリアルポート 自体は動作したままです。 場合によっては新旧両方の設定方法がインストールされているかもしれません が、起動時に実行されるのはたぶんそのうちの片方だけでしょう。Debian で は、古くて使わないファイルに "...pre-2.15" というラベルが付いていま す。 8.3.7. IRQ デフォルトでは、ttyS0 と ttyS2 が IRQ 4 を共有し、ttyS0 と ttyS3 が IRQ 3 を共有しています。しかし、次の条件が成り立たなければシリアルの割 り込みの共有はできません: すなわち (1) カーネルが 2.2 以降である、 (2) 割り込みの共有をサポートするようにカーネルをコンパイルしている、 (3) シリアルポートが割り込みの共有をサポートしているという条件です。 ``割り込みの共有とバージョン 2.2 以降のカーネル'' をご覧ください。 ttyS0 と ttyS1 の 2 つのシリアルポートしか使っていない場合にも問題はあ りません。というのも、存在しないデバイスについては共有する IRQ の衝突 が起きないからです。 内蔵モデムを追加した状態でも ttyS0 と ttyS1 をそのままにするならば、未 使用の IRQ を見つけ、これをシリアルポートの両側(またはモデムカード)に 設定し、setserial を使ってデバイスドライバに割り当てなければなりませ ん。IRQ 5 がサウンドカードに使われていなければ、これをモデム用に使って もよいでしょう。ハードウェアの IRQ を設定するには、isapnp や PnP BIOS, あるいは Linux を PnP にするためのパッチを使う必要があるかもしれませ ん。余っている IRQ を調べる参考として、"man setserial" を実行して "IRQ 11" などを検索してみてください。 8.4. stty 8.4.1. はじめに stty はシリアルポートの設定を色々やりますが、アプリケーションプログラ ム(および getty プログラム)が設定を扱うこともよくあるので、ユーザが使 う必要はあまりありません。このプログラムは、問題が起こった時やポートの 設定を見たい時には便利です。端末やコンソールで ``stty -a'' を実行すれ ばポートの設定を見ることができます。また、-a (all) オプションを付けず に stty を実行すれば、通常と異なる設定になっている部分が短くリスト表示 されます。シリアルポートの達人になろうというのでなければ、全ての設定を 覚える必要はありません。ほとんどはデフォルトのままで大丈夫なはず で、1970 年代に作られた特定の古いダム端末に対してだけ設定がいくつか必 要となります。 setserial は実際のシリアルポートだけを扱うのに対して、stty はシリアル ポートと仮想端末(PC モニタで使う Linux 標準のテキストインタフェース 等)の両方に対して使われます。PC モニタに対しては、stty の設定の多くは 無意味です。ボーレート等を変えても実際には何も変わらないように見えるで しょう。 stty の設定をいくつか示すと、速度(ビット/秒)、パリティ、ビット/バイ ト、ストップビットの数、8 番目のビットを落とすかどうか、モデム制御シグ ナル、フロー制御、ブレーク信号、行末マーカー、文字ケースの変更、パディ ング、バッファ溢れの際にビープ音をならすかどうか、入力した文字をエコー 表示するか、バックグラウンドタスクの端末への書き込みを許すかどうか、特 殊(制御)文字の定義(どのキーをを押すと割り込みがかかるか等)があります。 詳しくは stty のマニュアルページか info ファイルを見てくださ い。termios のマニュアルページも見てください。これは stty で設定できる のと同じオプションを含んでいますが、(1999 年半ばの時点では) stty のマ ニュアルページが説明できていない機能も含んでいます。 一部の getty の実装(getty_ps パッケージ)では、stty に通常与えるコマン ドは getty の設定ファイル(/etc/gettydefs)に書かれます。この設定ファイ ルがなくても、getty のコマンドラインはユーザが stty を必要としないよう に十分な設定ができます。 stty の設定などを変更する C プログラムを書くことができます。これに関す る文書をいくつか見れば、stty コマンドの使い方(およびたくさんある使用可 能な引き数)もよく理解できるでしょう。Serial-Programming-HOWTO も役に立 ちます。マニュアルページ termios には C 言語の構造体(termios 型)の説明 があります。この構造体は stty の設定をコンピュータのメモリに格納しま す。C 言語の構造体のフラグ名の多くは、stty コマンドの引き数とほぼ同じ です(そして同じ動作をします)。 8.4.2. 「別の」端末に対しての stty の使用 stty を使って、自分が現在使っている端末の調査や設定を行うのは簡単で す。これを別の(よその)端末やシリアルポートに対して行うのは面倒かもしれ ません。例えば、読者の皆さんが PC のモニタ (tty1) にいて、そして stty を使ってシリアルポート ttyS2 を扱いたいと考えているとします。 2000 年 より前の頃は、リダイレクト演算子 < を使う必要がありました。 2000 年以 降では(お使いの setserial のバージョンが 1.17 以上で、stty のバージョ ンが 2.0 以上ならば)、-F オプションを使うという別の方法があります。こ れはリダイレクションを使う古い方法が失敗する場合でも動作します。しか し、たとえ最新版であっても、ttyS2 上に端末があり、そこでシェルが動作し ているならば、表示されるものは確かではなく、設定しようとしてもうまくい かないだろうということを注意しておきます。その理由を理解したければ ``端末の 2 つのインタフェース'' をご覧ください。 新しい方法は ``stty -F /dev/ttyS2 ...'' です(あるいは -F の代わりに --fileを使います)。... が -a であれば、このコマンドで stty の全ての設 定が表示されます。リダイレクションを使う古い方法(最近のバージョンでも まだ使えます)では ``stty ... < /dev/ttyS2'' を使います。新しい方法では 動作するのに古い方法だとハングする場合は、オンにしてくれるモデム制御線 がないためにポートがハングしていると思われます。このように、古い方法も まだトラブル解決に役立ちます。詳しくはこの後の節を読んでください。 8.4.2.1. リダイレクションを使う古い方法 リダイレクション演算子には問題があります(この演算子ではなく、新しい -F オプションを使えば問題は起きません)。stty を使おうとすると時々、コマン ドがハングし、何も起こらないことがあります(リターンキーを押しても、次 のコマンドのプロンプトが出ない)。これは大抵ポートがハングしてしまった ためであり、これはモデム制御線のいずれかがオンになるのをポートが待って いるために起こります。例えば、モデム制御線を無視するように "clocal" を 設定していない場合、CD 信号がオンにならなければポートはオープンできま せんし、stty はポートに対して動作しません(新しい -F オプションを使って いない場合)。同様の状況は、ハードウェアフロー制御でも起こるようです。 オンになる必要がある導線がポートに繋いだケーブルになければ、ハングする のを防ぐ簡単な方法はありません。 このようなハングを防ぐ方法の一つは、新しい -F オプションを使い、 "clocal" や "crtscts" を設定することです。-F オプションが使えない場合 は、たとえ制御線がオフであってもポートを強制的に動作させるプログラム を、そのポートに対して使ってみてもよいでしょう。すると多分このプログラ ムは、この先ポートをオープンするために制御線が必要なくなるようにポート を設定できます: すなわち clocal または -crtscts を設定しま す。"minicom" を使ってこれを行うには、別の ttyS 等に合わせて minicom を再設定し、それから minicom の終了と再実行を行わなければなりません。 その後再び minicom を再設定しなければならないので、単に PC を再起動す るだけの方が簡単かもしれません。 リダイレクションを使う古い方法は、ttyS2 を stty への標準入力とします。 すると、stty プログラムは「ファイル」である ttyS2 にリンクしてこれを 「読み取る」ことができるようになります。しかし、ttyS2 に送られたバイト データは普通に期待される通りに読み取るのではなく、ポートの読み取りや変 更ができるように、このリンクを使ってポートの設定を調べます。 ``stty ... > /dev/ttyS2'' を使って端末を設定しようとする人もいますが、このコ マンドで設定することはできません。この場合は設定は行われずに、使ってい る端末(例えば tty1)に対する stty コマンドで普通に表示されるメッセージ が得られ、これが ttyS2 に送られます。しかし、ttyS2 の設定は全く変わり ません。 8.4.3. 端末の 2 つのインタフェース コマンドライン編集機能を有効にしてシェル(bash など)を使っている時は、2 つの異なる端末インタフェース(stty -a を実行した時に表示されるもの)があ ります。コマンドラインで入力を行う時には一時的な "raw" インタフェー ス(つまり "raw" モード)を持っており、それぞれの文字は入力するごとにコ マンドラインエディタが読み込みます。<リターン>キーを叩くと、コマンドラ インエディタは終了し、端末インタフェースはその端末の通常の "cooked" イ ンタフェース(cooked モード)に切り替わります。この cooked モードは、次 のプロンプトが端末に送られるまで続きます。この cooked モードでは何も入 力しませんが、raw モードで入力された文字は <リターン> キーが押されると cooked モードになります。 プロンプトが端末に送られると、端末は "cooked" モードから "raw" モード に変わります(これはエディタを起動する時とちょうど同じように行われま す。というのも、コマンドラインエディタを起動しようとしているからで す)。 "raw" モードの設定は、"cooked" モードから得た基本設定のみに基づ いて行われます。raw モードはこれらの設定を保持しますが、他のいくつかの 設定はモードを "raw" に変えるために変更します。前の "raw" モードで使わ れた設定には全く依存しません。したがって、stty を使って raw モードの設 定を変えると、「設定された」と思われる端末上で<リターン>キーを叩いた途 端にこのような設定は無くなってしまいます。 ここで、stty を入力して端末インタフェースを見る時には、cooked モードか raw モードの設定を表示することができます。その時にはどちらを見るのかを はっきりさせる必要があります。コマンドラインを表示している端末を扱うた めに別の端末から stty を使う場合には、表示は raw モードのものになりま す。行われた変更は raw モードにしか適用されず、「設定」しようとした端 末上で誰かが<リターン>を押すと消えてしまいます。しかし、自分のいる端末 で(リダイレクトの < を使わずに) stty コマンドを入力し、それから<リター ン>を押した場合は話が違ってきます。<リターン>キーにより端末は cooked モードになります。行われた変更は保存され、端末が raw モードに戻った時 にも残っています(もちろん raw モードで変更できない設定の場合は除きま す)。 この状況により問題が起こることがあります。例えば、端末インタフェースを ぐちゃぐちゃにしてしまい、これを戻すために別の端末に行って "stty -F dev/ttyS1 sane" (等)を実行したとしましょう。ところが、この方法は使えま せん! もちろんぐちゃぐちゃになってしまった端末から "stty sane ..." の 入力を試みることはできますが、入力した文字を見ることはできません。上記 の現象はダム端末だけではなく、PC モニタ上で使う仮想端末や、X 上の端末 ウィンドウにも当てはまります。言い換えれば、これは Linux を使うほとん ど全ての人に当てはまります。幸運なことに、stty を起動時に実行するファ イルはシェルが動作していない端末(あるいは端末が繋がっていないシリアル ポート)を扱えるので問題はありません。 8.4.4. どこに stty コマンドを置くか? コンピュータが起動する度に stty にシリアルインタフェースを設定させる必 要があるのなら、コンピュータが起動する(Linux が起動する)度に実行される ファイルに stty コマンドを入れておく必要があります。このファイルはシリ アルポートが使われる(ポートにおける getty の実行も含みます)前に実行さ れなければなりません。これを置くことができる場所はたくさんあります。複 数の場所にこれを置いたのに、その場所のうちの一つしか知らなければ(覚え ていなければ)衝突が起きてしまうでしょう。したがって、設定したことは記 録しておきましょう。 stty コマンドを置く場所の一つは、システムが起動する時に setserial を実 行するファイルの内部です。この場所はディストリビューションやバージョン ごとに異なります。低レベルの処理が先に行われるようにするため、これは setserial の後に置くのが良いでしょう。置かれているファイルが起動時に全 て実行されるディレクトリ(System V Init) が /etc ディレクトリツリーの下 にあれば、"stty" という名前のファイルを作って stty コマンドを実行させ ても良いでしょう。 8.5. isapnp とは何か? isapnp は、内部モデムを含めた ISA バス用のプラグ&プレイ (PnP)デバイス を設定するためのプログラムです。このプログラムは "isapnptools" と呼ば れるパッケージに他のプログラム("pnpdump")と一緒に入っていま す。"pnpdump" は全ての ISA PnP デバイスを見つけ、これらのデバイスを設 定するオプションを出力します。この出力は、PnP の設定ファイルである /etc/isapnp.conf に追加できる形式です。コンピュータの起動時に毎回実行 され、ISA PnP デバイスを設定できるように、isapnp コマンドはシステムの 起動ファイルに書かれます。BIOS が PnP をサポートしていなくても、これを 行うことは可能です。詳しくは Plug-and-Play-HOWTO を見てください。 9. 速度 (フローレート) ここで言う "速度" は本当は「データフローレート(data flow rate)」という 意味なのですが、大抵の人はこれを速度と誤用しています。速度の単位はビッ ト/秒(あるいはボー)です。速度は "stty" コマンドまたはシリアルポートを 使うプログラムで設定します。 ``stty'' をご覧ください。 9.1. 十分に速い速度が設定できません ハードウェアが対応している最大速度を知る必要があります。1998 年末の時 点では、ほとんどのハードウェアが 115.2k bps までの速度にしか対応してい ませんでした。いくつかの 56k 内蔵モデムは 230.4k bps に対応していま す。最近の Linux カーネルは高速(115.2k 以上)対応していますが、以下の理 由のいずれかあるいは両方のために、対応が難しい場合があります: 1. アプリケーションプログラム(または stty)が高速対応していない 2. setserial の設定がデフォルトの速度の 115,200 である(しかし、このデ フォルト値を変えるのは簡単です) 9.1.1. ハードウェアに速度を設定する方法: 除数と baud_base 値 普通使われる除数とそれに対応する速度(最大速度は 115,200 とします)のリ ストを示すと 1 (115.2k), 2 (57.6k), 3 (38.4k), 6 (19.2k), 12 (9.6k), 24 (4.8k), 48 (2.4k), 96 (1.2k) などとなります。シリアルドライバは、ハ ードウェアに「除数」(正の整数)のみを送ることによってハードウェアの速度 を設定します。この「除数」でハードウェアの最大速度が割り算され、遅い速 度となります(ただし除数が 1 の場合は言うまでもなく、ハードウェアに最大 速度で動作するよう命令します)。 普通は(通信プログラムや stty で)速度を 115.2k に指定すると、シリアルド ライバはポートのハードウェアに除数 1 を設定します。これは言うまでもな く最高速度の設定です。お使いのハードウェアの最高速度が例えばたまたま 230.4k ならば、115.2k を指定した時の除数が 1 であるため、実際の速度は 230.4k になります。これにより設定した速度の倍の速度になります。実際、 どんな速度を指定しても実際の速度は倍になってしまいます。460.8k で動作 できるハードウェアがあったとすると、実際の速度は設定値の 4 倍となるで しょう。 9.1.2. 速度設定に関する問題の回避 こういった計算を正しくさせるには(しかし必ずしも問題が解決するとは限り ません)、"setserial" を使って baud_base 値を実際のポートの最大速度 (例 えば 230.4k)に変更します。そうすると(アプリケーションや stty を使っ て)速度を 230.4k にした場合に除数として 1 が使われ、設定したのと同じ速 度が得られます。しかし問題があります: (1999 年半ばの時点では)stty や多 くの通信プログラムは最大速度の設定値が 115.2k であり、230.4k 等を設定 することができないのです。したがって、このような場合の一つの解決方法 は、 setserial では何も変更せず、実際の速度は設定した速度の 2 倍である ことを自分で覚えておくことです。 あまりマシとは言えませんが、別の回避策もあります。この方法を使うには、 (setserial を使って) baud_base 値をハードウェアの最大速度にしてくださ い。これにより計算方法が正しくなり、115.2k を指定すれば実際に 115.2k の速度が得られるようになります。ここでもまだ、通信プログラムなどが最高 速度を設定させてくれない場合に、最高速度を設定する方法を見つける必要が あります。幸運なことに、setserial にはこれを行う方法があります: "divisor 1" として "spd_cust" パラメータを使うのです。すると、通信プロ グラムで速度を 38400 とした時にポート内の除数は 1 に設定され、最高速度 で動作します。例: setserial /dev/ttyS2 spd_cust baud_base 230400 divisor 1 "divisor" を先に説明した(spd_cust と組み合わせる)特殊な用途以外の目的 で使ってはいけません。 通信プログラムで設定できない速い速度を 2 つ以上使いたい場合には、先の 説明ほど簡単には行きません。しかし同じ原則が当てはまります。baud_base 値は単にデフォルトのままにしておき、速度を設定する時には実際は除数しか 設定していないと考えるのです。したがって実際の速度は常に、シリアルドラ イバが設定した除数で最大速度を割った値となります。 ``ハードウェアに速 度を設定する方法: 除数と baud_base 値'' をご覧ください。 9.1.3. 水晶発振器の周波数はボーレートではありません baud_base 値の設定は普通、ハードウェア内の水晶発振器の周波数よりずっと 低い点に注意してください。というのも、水晶発振器の周波数はハードウェア 内で 16 で割られ、実際の最高速度となることが多いからです。水晶発振器の 周波数の方が高くなければならない理由は、このように周波数が高速ならば、 各ビットが 1 か 0 であるかを決めるためのサンプルをたくさん取ることがで きるからです。 9.2. シリアルのスループットの向上 (E)IDE のハードディスクを使っているシステムであり、かつスループットが 悪くてシリアルポートがオーバーランする場合は hdparm を試してください。 これは (E)IDE のパラメータ(ディスクの IRQ が発行されている間は他の IRQ をアンマスクする等)を変更可能にするユーティリティです。このユーティリ ティを使うと応答が良くなってオーバーランを無くすのに役立つでしょう。た だし、マニュアルページは必ずよく読んでください。というのも、一部のドラ イブとコントローラの組合せではこのユーティリティがうまく動作せず、ファ イルシステムを壊してしまうかもしれないからです。 irqtune と呼ばれるユーティリティも試してください。これはデバイス(例え ばモデムが繋がっているシリアルポート)の IRQ の優先度を変更するユーティ リティです。これにより、お使いのシステムのシリアルポートのスループット が向上するかもしれません。irqtune の FAQ は http://www.best.com/~cae/irqtune に あります。 10. ロックして他で使えないようにする 10.1. はじめに 自分がシリアルポートを使う時には、他の人は同時に使えないようにしたいと 思うでしょう。しかし、他の人にも使わせたいこともあるかもしれません。例 えば自分がテキスト端末を使っている時に、他の人が重要なメッセージを送れ るようにしたい場合です。 自分が現在使用中のシリアルポートを他の人(や他のプロセス)が使えないよう にする方法(ロッキング)は色々あります。この処理は自動的に行われるはずで すが、問題が起きた時のためにロッキングを知っておくことは重要です。プロ グラムが異常終了したり、(コンセントを引き抜くなどで)PC が突然落ちたり した場合には、シリアルポートがロックしたままになってしまうかもしれませ ん。ロックが残ったままであっても、普通は次にシリアルポートを使おうとし た時に自動的にロックは消されます。しかしまれにそうでないこともありま す。そんな時には何が起こったのかを理解する必要があります。 ロッキングを実装する方法の一つは、ロックを処理できるようにカーネルを設 計することですが、Linux はこれまではこの方法を避けてきました(今では使 われなくなった cua デバイスは例外です)。Linux で使われる方法は 2 つあ ります。 1. ロックファイルを作る方法 2. /dev/ttyS2 等のデバイスのパーミッションや所有者を変える方法 10.2. ロックファイル ロックファイルは特定のデバイスが使用中であることを示すために作られるた だのファイルです。このファイルは /var/lock に置かれます。以前は /usr/spool/uucp に置かれていました。Linux では、ロックファイルの名前は LCK..name となることがあります。ここで name はデバイス名か、UUCP のサ イト名です。ほとんどのプロセス(getty は除きます)は、そのデバイスに排他 的にアクセスできるようになるためにロックファイルを作ります。例えば、モ デムを使ってダイアルアウトを行うと、誰かがモデムを使っていることをロッ クファイル(ひとつだけでないこともあります)が他のプロセスに伝えます。 ロックファイルの内容は主に、デバイスをロックしているプロセスの ID で す。ロックされているデバイスをどうしても使いたければ、プロセスはロック ファイルを無視して、とにかくデバイスを使ってしまってもよい点に注意して ください。これはテキスト端末にメッセージを送りたい時などに便利です。 プログラムがシリアルポートを使おうとしたけれど、そのポートがロックファ イルでロックされている時は、このプログラムはロックファイルが示す PID がまだ使われているかどうかを確認するはずです。その PID が使われていな ければロックは無効ということなので、(無効になったロックファイルを消し てから)そのままポートを使っても大丈夫です。残念ながらプログラムによっ てはこのような処理を行わず、実際にはデバイスが使用中でなくてもデバイス が使用中だというメッセージを表示してあきらめてしまうものもあります。 ロックファイルがらみの問題は、同じデバイスが 2 つの別名を持っており、 その結果として別の名前を持つが実際には同じデバイスを示すロックファイル が 2 つできる場合に起こる可能性があります。かつては各々の物理シリアル ポートは 2 つの異なるデバイス名(ttyS0 と cua0)を持つことが有名でした。 ロックをチェックするプログラムは ttyS と cua の両方に対応していました が、現在は cua がなくなったので処理は簡単になりました。バージョンの古 いプログラムはまだ cua を使っていることがあります。別名を使うこ と(/dev/modem で /dev/ttyS2 を示す等)はトラブルを自ら招くようなもので す。 10.3. デバイスファイルの所有者、グループ、パーミッションの変更 デバイスを使うには、ユーザ(setuid されている場合は、実行するプログラ ム) は /dev ディレクトリにあるデバイス「ファイル」を読み書きするための パーミッションを持っている必要があります。したがって、他の人がデバイス を使えないようにする筋の通った方法は、自分自身をそのデバイスの一時的な 所有者にし、他には誰も使えないようなパーミッションを設定することです。 このような処理をするプログラムもあります。同じような方法として、デバイ スファイルのグループも使えます。 ロックファイルは他のプロセスがデバイスを使えないようにしますが、デバイ スファイルの所有者/パーミッションの変更は他のユーザ(やグループ) がデバ イスを使えないようにします。ひとつの状況として、グループに対してシリア ルポートへの書き込みのパーミッションは与えられているけれど、読み取りの パーミッションは出ていない場合があります。この場合、ポートへの書き込み は単にテキスト端末へのメッセージ送信になるだけですが、読み取りは悲惨な ことになります。別のプログラムが先にデータを読み出してしまうと、データ の読み取りの必要があった元々のプログラムのデータがなくなってしまいま す。このように、読み取りは書き込みよりも大きな害を及ぼすことがありま す。読み取りではデータがなくなりますが、書き込みでは余計なデータが追加 されるだけだからです。これが、書き込みは許しても読み取りは許さない理由 です。これは通常ファイルの場合とちょうど反対になります。通常ファイルで は他人に読み取りを許可しますが、書き込み(修正)は許しません。シリアルポ ートを使う場合は普通、読み取りと書き込みの両方が必要です。 デバイスファイルの属性を変更するプログラムは、終了時には変更した部分を 元に戻すはずです。しかし、異常終了した場合には、次に誰かが使おうとした 時に "permission denied" エラーが出るような状態のままのデバイスファイ ルが残ることがあります。 11. 通信プログラムとユーティリティ 11.1. ソフトウェアの一覧 以下に通信プログラムをいくつか紹介します。お使いのディストリビューショ ンに付属していなければ、FTP で入手することもできます。 o ecu - 通信プログラム o C-Kermit - 移植性が高く、スクリプ ト記述ができ、ファイル転送・文字集合変換・ zmodem に対応しているシ リアル・TCP/IP 共用の通信プログラム。 o minicom - telix に似た通信プログラム o seyon - X ベースの通信プログラム o xc - xcomm 通信パッケージ o term と SLiRP は、シェルアカウントを使って TCP/IP 機能を提供しま す。 o screen はマルチセッションプログラムです。これは仮想コンソールのよう に動作します。 o callback を使うと、リモートモデムに電話をかけた時に、そのモデムは いったん電話を切ってからコールバックしてくれます(電話代を節約できま す)。 o mgetty+fax はファックスを扱います。ps_getty の代わりに使うことがで きます。 o ZyXEL は ZyXEL U-1496 モデムを制御するプログラムです。このプログラ ムはダイアルイン、ダイアルアウト、コールバックによるセキュリティ機 能、ファックス、音声メールボックスを扱います。 o SLIP と PPP に関連するソフトウェアは ftp://metalab.unc.edu/pub/Linux/system/network/serial で入手できま す。 11.2. kermit と zmodem (ttyS3 で)kermit で zmodem を使うには、.kermrc に以下の記述を追加しま す: define rz !rz < /dev/ttyS3 > /dev/ttyS3 define sz !sz \%0 > /dev/ttyS3 < /dev/ttyS3 モデムが接続されている正しいポートを必ず指定してください。zmodem を使 うには、kermit のプロンプトで単に rz または sz と入力してく ださい。 12. シリアルに関するちょっとしたテクニックなど 役に立つと思われるシリアル関連のちょっとしたテクニックを紹介します。 12.1. ラインドライバ テキスト端末では EIA-232 は十分高速ですが、許されるケーブル長が短すぎ ることはよくあります。この問題は平衡型伝送技術により解決します。テキス ト端末で平衡型伝送を行うための一般的な方法は、シリアル回線に 2 つのラ インドライバをインストールして、非平衡型から平衡型への変換(および逆変 換)を行うことです。これは特殊な機器であり、新しく買うとなると高価で しょう。 12.2. 欠陥品として知られているハードウェア 12.2.1. 特定のビデオボードで起こる I/O アドレスの衝突を回避する方法 IBM 8514 ボード(など)の I/O アドレスは 0x?2e8 と言われています(? は 2, 4, 8, 9 のいずれか)。シリアルポートがアドレスを展開する時に 16 進値 の先頭の 0 である桁を無視する(多くのシリアルポートはそのように動作しま す)場合には、これは 0x02e8 にある ttyS3 の I/O アドレスと衝突します(た だしシリアルポートがうまく設計されていれば衝突しないはずです)。これ は、このアドレスで ttyS3 を使おうとしている人には困った話です。これと は別の問題で Linux は ttyS3 にある内蔵モデムを検出できません が、setserial を使ってこのアドレスに ttyS3 を置けば、モデムはうまく動 作するでしょう。 12.2.2. AMD Elan SC400 CPU (PC-on-a-chip) での問題 これは割り込みと UART の状態レジスタが競合するという問題です。UART の トランスミッタがバイトデータの送信を終え、UART の送信バッファが空にな ると(送信バッファは次のバイトデータを待ちます)割り込みが発行されます。 しかし UART の状態レジスタは、これが十分反映されるほど速く更新されま せん。その結果、割り込みサービスルーチンが高速なチェックを行うと、何も 起こっていないと(間違って)判断します。したがって、次に転送すべきバイト データはシリアルポートに送られず、UART のトランスミッタは届くことのな いバイトデータを虚しく待ち続けることになります。割り込みサービスが状態 レジスタをチェックするまでの待ち時間がもう少し長ければ、実際の状態が反 映され、全てがうまく行くはずなのですが…。 シリアルドライバにパッチを当てることにより、この問題を解決しようという 提案もあります。しかし、欠陥ハードウェアに対応するために Linux にパッ チを当てるべきでしょうか? しかも問題ないハードウェアでの性能が落ちるか もしれないのに。 13. トラブルシューティング モデムおよび、モデムに対して用いる getty に関しては、Modem-HOWTO のト ラブルシューティングの章をご覧ください。 13.1. シリアルの電気的な診断を行う道具 13.1.1. 中継コネクタ等の小物 端末が数個だけならばテスタ(電圧計として使います)があれば十分でしょう が、シリアルポートの配線を調べるための簡単な特殊器具もあります。その中 には「中継コネクタ(breakout)」と呼ばれるものがあります。「breakout」と いう言葉は、導線をケーブルから取り出すといった意味です。このような小物 には 2 つコネクタが付いており、シリアルケーブルを繋ぐようになっていま す。電圧計を繋ぐ端子がついているものもあります。特定のモデム制御線がオ ンになっていると点灯する LED ランプがついているものもあります。任意の 線と線を接続できるようにジャンパがついているものもあります。スイッチが ついているものもあります。 Radio Shack 等の電器屋で「RS-232 Troubleshooter」つまり「RS-232 結線テ スタ」を売っています(1998 年)。これは TD, RD, CD, RTS, CTS, DTR, DSR をチェックします。緑のランプはオン(+12 V)を表し、赤のランプはオフ(-12 V)を表します。この店では「RS-232 シリアルジャンパボックス」という、接 続ピンを自由に選べる装置も売っています。 13.1.2. 電圧の測定 どんな電圧計やテスタでも(10 ドルで売られているような安物でさえ)うまく 使えるはずです。電圧のチェックに他の方法を使うのは面倒です。抵抗を直列 に繋いで LED にかかる電圧を下げない限り、LED を使ってはいけません。 20 mA の LED では 470Ω の抵抗を使ってください(ただし全ての LED が 20 mA とは限りません)。LED は決まった極性でしか光らないので、+ と - の電圧を 調べることができます。自動的に回路を検査するこのような小物を誰か作りま せんか? 論理プローブは使おうとすると壊れてしまうかもしれません。という のも、TTL が想定している電圧はたったの 5 V だからです。12 V の白熱電球 を使うのはやめた方がいいでしょう。電球では極性はわかりませんし、UART の出力電流は限られているため、たぶん光ることさえないでしょう。 メスのコネクタの電圧を測定するには、曲げたペーパークリップを調べたい穴 に差し込むとよいでしょう。ペーパークリップの直径はピンよりも小さいはず なので、接触部を傷つけることはありません。接続するためには、ワニ口ク リップ(等)でペーパークリップを挟みましょう。 13.1.3. 電圧を味わってみる テストに使える器具が無く、かつ電気ショックを受ける(感電さえする)覚悟が あれば、最後の手段として電圧を味わうという方法もあります。調べる導線を なめる前には、高圧電流が流れていないことを確かめましょう。両方の導線 に(同時に)片方の手で触れ、ショックを受けるかどうかを確認します。ショッ クを受けなければ接触部の肌をなめて濡らし、再び導線に触れてみましょう。 これでショックを受ければ、なめてみる気はきっとなくなるでしょう。 12 V を調べるには、まず指をなめて、一方の導線をその指に押しつけます。 次に別の導線に舌で触れます。舌で触れた導線に正の電圧がかかっていれば、 はっきりとした味がするでしょう。どんな味がするか前もって知っておきたけ れば、懐中電灯の電池をなめてみるといいでしょう。 13.2. シリアルポートの監視と診断 モデム制御線を監視し、その電圧が正(1)であるか負(0)であるかを示す Linux 用のプログラムがいくつかあります。 ``シリアルポートの監視/診断用のプロ グラム'' の章をご覧ください。 13.3. 以下の節は Serial-HOWTO にも Modem-HOWTO にもあります: 13.4. 物理的にはシリアルポートがあるのに、検出されません デバイス(モデムなど)が確かに動作しているなら、そのデバイスが繋がってい るシリアルポートは検出されています。まったく動作しないのであれば、シリ アルポートが検出できることを確かめる必要があります。 BIOS のメニューと出力メッセージを確認しましょう。 PCI バスならば lspci を使います。 ISA バス上の PnP シリアルポートの場合には、"pnpdump --dumpregs" を試したり、 Plug-and-Play-HOWTO をご覧になってください。 "scanport" を使うと、ISA 上の全てのポートをスキャンし、シリアルポート かもしれない未知のポートを見つけることができます(ただしポートの探査は 行いません)。scanport は PC をハングさせるかもしれません。 setserial を使って探査を行ってもよいでしょう。``探査''の節を参照してください。シ リアルポートにデータが何も流れていないようであれば、シリアルポートは あっても割り込みが間違っているかもしれません。 ``この上なく遅い: テキ ストがすごく遅れてゆっくり画面に表示されます'' の節をご覧ください。 2 つのポートが同じ I/O アドレスを持っている場合、探査では間違ってポー トが一つしか示されません。プラグ&プレイによる検出では両方のポートが見 つかるので、これが問題になるのは、プラグ&プレイでないポートが少なくと も一つある場合だけです。「共有」されているポートに接続しているデバイス ではほとんどどんなエラーでも報告/検出されることがありますが、同じポー トに 2 つのデバイスが繋がっているという事実は検出されないようです(幸い にも自分で見つける場合は除きます)。IRQ が違う場合には、setserial で各 IRQ を探査したときに IRQ の検出に失敗することにより、この状態を「検 出」できると思います。 ``探査''の節をご覧ください。 13.5. この上なく遅い: テキストがすごく遅れてゆっくり画面に表示されま す これは割り込みの設定が間違っているか、衝突しているためでしょう。初めて モデムや端末、プリンタを使おうとしたときに出会うような現象をいくつか示 します。場合によっては、入力した文字が何秒も経たないと表示されないこと があります。入力した最後の文字しか表示されないこともあります。また、そ の文字が単に目に見えない<改行>文字で、カーソルが 1 行下に移動したこと しかわからないこともあります。また別の場合としては、画面にデータはたく さん表示されるのですが、16 文字ごとのかたまりでしか表示されないことも あります。そして、あるかたまりの次のかたまりが表示されるまでには何秒も の長い待ち時間が続きます。「input overrun(入力オーバーラン)」のエラー メッセージが表示される(あるいはログに残る)こともあります。 詳しい症状とそれが起こる理由については、 ``割り込みの問題に関する詳しい説明''の章や``割り込みの衝突''の節、``割 り込みの設定ミス''の節を見てください。プラグ&プレイデバイスがらみの問 題なら、Plug-and-Play-HOWTO も見てください。 本当に割り込みの問題かどうかを簡易的に調べるには、"setserial" で IRQ を 0 に設定してください。これにより、ドライバは割り込みではなくポーリ ングを使うようになります。これで「遅い」問題が解決するようであれば、割 り込みの問題が起きています。ただし、その場合でも割り込みの問題を解決す べきです。なぜなら、ポーリングはコンピュータの資源を大量に消費します し、時にはスループットを劇的に低下させるからです。 割り込みの衝突を見つけだすのは容易ではないかもしれません。というのも、 Linux は割り込みの衝突を全く許さず、ユーザが衝突を起こそうとしていると 判断すると``/dev/ttyS?: Device or resource busy'' エラーを送ることに なっているからです。しかし、本当に衝突が起こる可能性があるのは "setserial" が間違った情報を指定していた場合です。したがっ て、"setserial" を使っても衝突は明らかになりません(また、"setserial" の情報に基づいて設定される /proc/interrupts を調べても衝突はわかりませ ん)。それでもハードウェアの実際の設定を調べる時に、間違っている部分を 正確に突き止めて直すには、"setserial" に設定されている情報を知らなけれ ばなりません。 こういった場合に行うべき作業は、ジャンパや PnP 設定ソフトウェアを使っ て、ハードウェアに実際に設定されている情報を調べることです。PnP の場合 には、"pnpdump --dumpregs" (ISA バスの場合)または "lspci" (PCI バスの 場合)を実行しましょう。そして、Linux ("setserial" 等)が考えているハー ドウェアの設定とこの結果を比べてください。 13.6. なぜか遅い: あと 2、3 倍は速いはずなのですが 考えられる理由の一つは、シリアルポートを使っているデバイス(モデムや端 末、プリンタ)が、あなたが考えているほど速く動作しないことです。 考えられる別の理由は、あなたが使っているシリアルポートが古い (UART 8250, 16450 や初期の 16550)とシリアルドライバが認識していることで す。``UART とは何ですか?''を参照し、 "setserial -g /dev/ttyS*" を使っ てください。その結果として 16550A より性能がよくない UART が表示された ら、これは多分設定の問題です。この場合は、"setserial" の設定に問題があ れば、これを変更します。詳しくは ``setserial とは何か?''を見てくださ い。当然のことですが、実際は古いシリアルポートを使っているのに setserial をだまそうとしても、単に事態が悪化するだけです。 13.7. システム起動時の画面で、シリアルポートの IRQ が間違って表示され ます 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 を使わなければ なりません。 13.8. "Cannot open /dev/ttyS?: Permission denied" というエラーが出ま す "ls -l /dev/ttyS?" を実行してそのポートのファイルのパーミッションを調 べてみましょう。ttyS? の所有者が自分であれば、読み書きのパーミッション として crw が必要です。最初の桁は c (キャラクタデバイス)です。ポートの 所有者でなければ、8 桁目と 9 桁目が rw- でなければなりません。つまり誰 でもそのポートを読み書きできなければなりません。パーミッションを変更す るには "chmod" を使います。アクセス権限を得る方法としては、グループパ ーミッションを持っている「グループ」に所属するといったもっと複雑なもの もあります。 13.9. ttyS? について "Operation not supported by device" というエラー が出る このエラーは、カーネルがサポートしていないために、setserial や stty 等 が要求した操作が行えないという意味です。以前は "serial" モジュールがロ ードされてないことが原因の場合が多かったのですが、PnP の登場により、こ のエラーはドライバ(および setserial)が考えているアドレスにモデム (ある いは他のシリアルデバイス)がないことを示すことが多くなりました。こう いったアドレスにモデムがなければ、そのアドレスに送られた(操作のため の)コマンドは当然ながら処理されません。 ``シリアルポートのハードウェア の設定は?'' の節をご覧ください。 "serial" モジュールがロードされていなかったが今ロードしたと "lsmod" が 表示する場合は、モジュールは今ロードされたけれど、エラーが出た時にはロ ードされていなかったのかもしれません。多くの場合、モジュールは必要な時 に自動的にロードされます(もし見つけることができれば)。"serial" モジュ ールを強制的にロードさせるには、 /etc/modules.conf または /etc/modules に記述しておきます。モジュールそのものは /lib/modules/.../misc/serial.o にあるはずです。 13.10. "Cannot create lockfile. Sorry" (エラーメッセージ) 何らかのプログラムがポートを「オープン」する時、ロックファイルが /var/lock/ に作られます。lock ディレクトリのパーミッションが間違ってい ると、ここにロックファイルを作れません。パーミッションが正しいかどうか を確認するには "ls -ld /var/lock" を使います。普通は全員に対して rwx です(rwx が 3 度繰り返されます)。パーミッションが間違っている場合に は、"chmod" コマンドを使って修正します。もちろん、"lock" ディレクトリ がなければ、そこにロックファイルを作ることはできません。ロックファイル に関する、より詳しい情報については ``ロックファイルとは何ですか?''の節 をご覧ください。 13.11. "Device /dev/ttyS? is locked." (デバイス /dev/ttyS? がロックさ れています) このメッセージが出た場合にはおそらく、誰か他の人(あるいは他のプロセ ス)がシリアルポートを使っています。このポートを「使用中」のプロセスを 見つける方法はいくつもあります。一つの方法は、ロックファイル (/var/lock/LCK...)の中身を見ることです。これは、ポートを使っているプロ セスの ID のはずです。プロセス ID が 例えば 261 ならば、"ps 261" を実 行し、それが何かを調べましょう。そして、そのプロセスがもはや不要であれ ば、 "kill 261" で優しく kill してもいいでしょう。これで終了しないな ら、 "kill -9 261" を実行して強制的に kill してください。ただし、この 場合にはロックファイルが消されずに残るので、手で消す必要があるでしょ う。もちろん、261 のようなプロセスが存在しなければ単にロックファイルを 消してかまいません。しかし、ロックファイルが示すプロセス ID (261 等)が 無効であれば、多くの場合そのロックファイルは自動的に削除されるはずで す。 13.12. "/dev/ttyS?: Device or resource busy" これはアクセス(つまり使用)しようとしているデバイスがビジー状態 (使用 中)と考えられるか、デバイスが必要としているリソース(IRQ 等)が他のデバ イスに使われていると考えられることを示します。本当に「ビジー状態」のこ ともありますが、そうでなければ間違って「ビジー状態」のように見えている だけです。 ``resource busy'' の部分はよく、(例えば ttyS2 で)「他のデバイスが ttyS2 の割り込みを使用中なので、ttyS2 は使えません」という意味になりま す。 "setserial" の設定による割り込みの衝突の可能性が考えられます。こ のエラーメッセージをもっと正確に言うと、「ttyS2 を使えませ ん。setserial のデータ(とカーネルのデータ)が、他のデバイスが ttyS2 の 割り込みを使っていると示しています」となるでしょう。2 つのデバイスが同 じ IRQ を使っていても、そのうちの片方しか起動していなければ何も問題は 起きません。まだ衝突は起きていないからです。しかし、次に(最初のデバイ スを終了させないままで) 2 番目のデバイスを起動しようとすると、"... resource busy" のエラーメッセージが出ます。こうなるのは、カーネルが追 跡するのはどの IRQ が実際に使われているかだけなので、デバイスが使用(オ ープン)されなければ衝突は起きないからです。 2 通りの場合が考えられます。まず、本当に割り込みが衝突しそうなので、そ れを避けようとしているという場合もあるでしょう。しかし、setserial が勘 違いをしているという場合もありますし、そうだとすると(setserial が間 違った衝突を予測したという以外には) ttyS2 が使えない理由はどこにもない はずです。ここですべきことは、ttyS2 が使っていると setserial が考えて いる割り込み番号を調べることです。これは言うのは簡単ですが、ttyS2 に対 して "setserial" を使えないため、実際にやるのは面倒です。"setserial" が使えないのは、ttyS2 の IRQ は「ビジー状態」ということになっており、 同じく "device busy" のエラーメッセージを出すからです。これを解決する には、再起動するか、衝突していそうなプロセスを優しく kill してくださ い。再起動する際には次のことを行ってください。 1. シリアルポートに関する起動メッセージをよく見る。 2. 起動時に "setserial" を実行するファイルが(単独で)同じ衝突を繰り返し て起こさないことを祈る。 ttyS2 が使っている IRQ を知っているつもりであれば、 /proc/interrupts を見て、現在その IRQ を使っている他のデバイスを見つけるとよいでしょ う。/proc/interrupts (や "setserial")が示す疑わしい IRQ が正しい(ハー ドウェアの設定と同じ)かどうかを全てチェックし直すのもよいでしょう。割 り込みが衝突している可能性があるかどうかを調べる方法は、 "setserial" を使って IRQ に 0 (ポーリング)を設定することです。 IRQ にずっと 0 を設 定したままにするのはよくありません。というのも、CPU の資源を余計に使う からです。 13.13. トラブル対処のためのツール トラブルに対処する時に使うとよいプログラムがいくつかあります: o "lsof /dev/ttyS*" により、オープンされているシリアルポートがリスト 表示されます。 o "setserial" は、シリアルポートの低レベルハードウェア設定の表示と設 定を行います(ドライバ側の設定です)。詳しくは ``setserial とは何 か?'' の節を見てください。 o "stty" はシリアルポートの設定("setserial" が扱う部分を除く)の表示と 設定を行います。``stty'' の節を見てください。 o "modemstat" と "statserial" は、モデムの各種信号線(DTR, CTS など)の 現在の状態を表示します。 o "irqtune" を使えば、シリアルポートの割り込みの優先度を上げて性能を 向上させることができます。 o ハードディスクのチューニングを行う "hdparm" もいくらか役に立つかも しれません。 o "lspci" は、PCI バス上のハードウェアの実際の IRQ 等を表示します。 o "pnpdump --dumpregs" は、ISA バス上の PnP デバイスについて、ハード ウェアの実際の IRQ 等を表示します。 o /proc ディレクトリの「ファイル」のいくつか(ioports や interrupts 等)。 14. 割り込みの問題に関する詳しい説明 ``トラブルシューティング''の章では症状別に問題点を挙げていますが、この 章では割り込みの設定を誤っている場合に何が起こるのかを説明します。この 章は、何がその症状を起こすのか、同じ原因で他のどんな症状が出るのか、こ れらにどう対処すべきなのかを理解する助けになるでしょう。 14.1. 割り込みの問題の種類 "setserial" プログラムは、シリアルドライバが考えている割り込みの設定を 表示します。シリアルドライバ(と setserial)が正しい情報を持っていれば、 割り込みに関することは全てうまく行くはずです。もちろん、デバイスに対応 する /dev/ttyS ファイルは存在しなければなりませんし、プラグ&プレイ(ま たはジャンパ)でハードウェアにアドレスと IRQ を設定していなければなりま せん。Linux は割り込みの衝突を知っていて許可することはないので、衝突を 起こすような設定を試みると "Device or resource busy" というエラーメッ セージが表示されます。 ユーザが割り込みを衝突させそうになるとカーネルは割り込みの衝突を避けよ うとして "resource busy" というメッセージを出します。すると割り込みの 衝突が起こることはあり得ないのでしょうか? いいえ、簡単に起こります。 ハードウェアの設定が本当に衝突を起こしそうなときに setserial が判断を 誤り、「衝突はない」と嘘をつくこともあるのです。このような場合、"... busy" というメッセージは出ませんが、性能が著しく悪くなります。 2 つの デバイスは同じ割り込み信号を同じ信号線に送るので、CPU は割り込みが 1 つのデバイスからしか来ていないと勘違いします。これについては以降の節で 詳しく説明します。 2 つのデバイスに同じ IRQ を割り当てても、どちらのデバイスも使われてい なければ Linux は文句を言いません。それぞれのデバイスは開始(初期化)の 際に、Linux にハードウェア割り込みを使う許可を求めます。Linux はどの割 り込みがどのデバイスに割り当てられているかを管理しているので、その割り 込みが既に使われていると、"... busy" のエラーメッセージが出力されるこ とになります。したがって、2 つのデバイスが同じ IRQ を使っていても、 1 つのデバイスしか使わなければ、何も問題はありません。しかし、(最初のデ バイスを終了させずに)次のデバイスを使おうとすると、"... busy" のエラー メッセージが出ることになります。 14.2. 割り込みの誤設定や衝突で起こる症状 起きる症状は、最近の FIFO バッファを持っているシリアルポートを使ってい るかどうか、あるいは FIFO バッファを持たない古いシリアルポートを使って いるかどうかで変わってきます。古いシリアルポートで起こる症状を理解する ことも重要です。なぜなら、同じことが新しいシリアルポートで起こることが 時々あるようだからです。 古いシリアルポートの場合には、数秒ごとに 1 文字しか通過できません。こ れは非常に遅いので、ほとんど動作していないように見えます(特に、空白文 字や改行文字などの見えない文字が通過する場合)。FIFO バッファを持つ新し いシリアルポートの場合には、数秒後の間に 16 文字までが流れていくのが見 えるでしょう。 ポートにモデムが繋がっていて電話番号をダイアルしても、CONNECT メッセー ジが通らないため、接続していないように見えます。しかしずっと待ってから 接続し、ログインメッセージ(あるいはその類)の一部が最終的に表示されるか もしれません。接続のあなた側からの応答が遅れて、相手側があきらめて接続 を切ってしまい、"NO CARRIER" メッセージが出るかもしれません。 minicom を使っている場合にうまく動作しているかどうか調べるための一般的 なテスト方法は、一番簡単なコマンドである "AT" を入力し、これにモデムが 反応するかどうかを調べることです。単に at を入力すると、普通 は(割り込みが OK ならば)即座にモデムから "OK" という返事があるはずで す。割り込みの設定がおかしければ、at を入力しても何も返ってこな いかもしれません。しかし 10 秒くらい経ってからカーソルが 1 行下がるか もしれません。何が起こっているかというと、FIFO が 1 バイトしか保持でき ないように動作しているのです。入力した "at" は FIFO をオーバーランさ せ、どちらの文字も消えてしまいます。しかし、しばらく待っていたために最 後の だけは通り、カーソルが 1 行下がることによって、この見えな い文字を「見る」ことになります。1 文字を入力してから 10 秒待てば、その 文字が画面にエコーバックされるはずです。あなたが文字を打てる速度が 1 分間当り 1 単語より少なければ、これでも大丈夫でしょう :-) 14.3. 割り込みの設定ミス 割り込みの役割が分からなければ、先に ``割り込み''の節を見てください。 シリアルポートのハードウェアには IRQ が 1 つ設定されているけれど、デバ イスドライバにこれと異なる IRQ が設定されている場合、デバイスドライバ はシリアルポートから送られる割り込みを全く捕捉しません。シリアルポート は割り込みを使ってデバイスを呼び出してサービス(16 バイトの受信バッファ からのバイトデータの受け取りや、16 バイトの送信バッファへのバイトデー タの書き込み) を要求するので、シリアルポートは全く動作しないと思われま す。 しかしそれでも動く--あるいは動いているように見えることもあります。これ はどうしてでしょうか? つまり、シリアルポートにサービスを提供する方法に は、割り込み以外にも遅いポーリングを使う方法があるのです。この方法は割 り込みを必要としません。ポーリングとは、デバイスドライバが時々シリアル ポートを調べて、何か必要としているかどうか(例えば、受信バッファから取 り込む必要があるバイトデータが存在するかどうか)を見る方法です。割り込 みが使えなければ、シリアルドライバはこのポーリング法を最終的に使いま す。しかし、このポーリングは割り込みの代わりに使うための方法ではありま せん。ポーリングは遅いので実用的ではありませんし、バッファオーバーラン を起こすこともあるからです。ポーリングの目的は、割り込みが 1 つだけ無 くなるか、動作が正しくなかったときに、繰り返し正しい動作を行わせること だったと思います。割り込みが失敗したことを示す際にも便利です。 16 バイトの送信バッファは、16 バイトを転送すると待ちに入り、次のポーリ ングが(数秒後に)起こってからさらに 16 バイトを送りだします。したがっ て、転送は非常に遅く、また細切れになります。受信も遅くなります。なぜな ら、受信バッファが受け取ったバイトデータは、ポーリングが行われるまでの 数秒間はバッファに留まるからです。 入力した文字が表示されるまでに非常に時間がかかるのは、これが理由です。 例えば「AT」という文字列をモデムに送ると、「AT」はシリアルポートを出て モデムに送られます。モデムはシリアルポートを通じて「AT」をスクリーンに エコーバックします。このように、「AT」という文字列はシリアルポートを 2 回通らなければなりません。普通はこの動作が非常に高速なので、キーボード で入力したのと同時に「AT」という文字列が表示されるように見えます。ポー リングのためにシリアルポートが遅い場合には、入力した文字は何秒も待たな いと表示されません。 16 バイトの受信バッファのオーバーランについてはどうでしょうか? これは 外付けモデムを使っている場合に起こります。というのも、モデムはシリアル ポートに高速にデータを送るだけなので、16 バイトのバッファがオーバーラ ンしてしまいます。しかし内蔵モデムの場合にはシリアルポートはモデムと同 じカード上にあるので、受信したバイトデータをこの受信バッファに入れる前 にバッファに空きがあるかどうかが多分チェックされます。この場合には、受 信バッファがオーバーランすることはありませんが、テキストは 16 バイトの まとまりごとに数秒の間隔を置いて表示されます。 外付けモデムであってもオーバーランが起こらないことがあります。数文字 (16 文字以下)しか送られていない場合にはオーバーランは起こりません。 バッファには大抵、これだけの空きがあるからです。しかしこれより多いバイ ト数をモデムから送ろうとすると、画面ではオーバーランが起こります。ただ し、タイミングさえ良ければオーバーランなしに 16 バイト(隙間無し)以上が 通ることもあります。例えば 32 バイトが外付けケーブルからポートに一気に 送られた場合を考えてみましょう。前半の 16 バイトが来た後に、この 16 バ イトをうまく受け取れるよう、ポーリングが起こることもあります。すると次 の 16 バイトまでには空き時間があるでしょうから、32 ビット全体がうまく 通ります。このシナリオ通りになることはあまりありませんが、同様の条件に より 17 バイトから 31 バイトが通ることはもっと高い可能性で起こります。 しかし、データを落としながら 16 バイトのデータのかたまりだけが断続的に 届くということはさらによくあります。 1 バイトのバッファしか持たない古いシリアルポートの場合(あるいは設定を 誤って 1 バイトのバッファのような動作になっている場合)には、前に書いた よりもずっと悪い状況になります。つまり、1 つの文字だけが時々シリアルポ ートを通るといった状態になります。最後に受け取った文字を除くと、受け 取った文字は全てオーバーランを起こします(そして失われます)。この最後の 文字は単なる改行文字であることがよくあります。というのも、改行文字は画 面に一気に送られる文字の中で最後の文字となることが多いからです。した がって、 AT とモデムに入力しても、画面には AT と表示されないこ とがあります。そして数秒後に起こるのは、カーソルが一行下に移動する(改 行文字)ことだけです。筆者には、16 バイトの FIFO バッファが 1 バイトの バッファのように動作した経験があります。 通信プログラムは起動の時に、割り込みが動作していることを期待します。ポ ーリング的なモードの遅い動作を使うようにはなっていません。したがって、 シリアルポートやモデムの設定ミスなど、どんな誤りを引き起こしてもおかし くありません。接続が確立した瞬間を見逃してしまうこともありえます。ログ インするためにスクリプトを使っている場合には、ポーリングの遅延のために ログインが(タイムアウトにより)失敗するかもしれません。 14.4. 割り込みの衝突 2 つのデバイスが同じ IRQ 番号を使っていると、割り込みを共有していると 言われます。条件によっては、この共有はうまく動作します。バージョン 2.2 以降のカーネルは、場合によっては、シリアルポートと別のシリアルポートで 割り込みを共有できます。 PCI バス上のデバイスは、PCI バス上の他のデバ イスと IRQ を共有できます。これ以外で衝突の可能性がある場合でも、同じ IRQ のデバイス 2 つを同時に「使う」ことがなければ、問題は起きないはず です。正確に書くと、「使う」とは(プログラマ言葉で)「オープンする」とい う意味です。以上の例外を除くと、(割り込み共有を可能にする特殊なソフト ウェアとハードウェアを使わない限り)共有は許されておらず、共有を行おう とすると衝突が起こります。 IRQ が衝突している 2 つのプロセスが同時に実行された場合であっても、片 方のデバイスの割り込みがデバイスドライバに捕捉され、そちらだけはうまく 動作することもよくあります。他方のデバイスの割り込みは正しいドライバに 捕捉されないので、割り込みの設定ミスがある時のプロセスとちょうど同じよ うに動作するでしょう。詳しくは ``割り込みの設定ミス'' の章をご覧くださ い。 14.5. 割り込みの問題の解決 上記のように応答が非常に遅い場合のテスト方法の一つは、IRQ を 0 に変更 して(割り込みの代わりに高速なポーリングを用いる)、これで問題が解決する かどうかを調べてください。IRQ=0 によるポーリングは、不正な割り込みによ る「ポーリング」と比べて桁違いに高速です。IRQ=0 で問題が解決するようで あれば、割り込みに何か問題があると考えられます。IRQ=0 はリソースを大量 に消費するので、一時的な修正のためだけに使ってください。割り込みの問題 の原因を見つけるべきであり、いつまでも IRQ=0 を使っていてはいけませ ん。 /proc/interrupts を調べて、他のプロセスが現在その IRQ を使っていないか どうかを見てください。他のシリアルポートがその割り込みを使っているなら ば、"top" (f を入力して TTY 表示を有効にしてください)か "ps -e" を使っ てどのシリアルポートが使われているかを調べてください。setserial に間 違った IRQ が設定されている疑いがある場合には、 ``シリアルポートの現在 の I/O アドレスと IRQ の設定は?'' の節を見てください。 15. UART とは何ですか? 性能にどのような影響を与えるのでしょうか? 15.1. UART 入門 (この節は Modem-HOWTO にもあります。) UART (Universal Asynchronous Receiver Transmitter) とは、PC のマザーボード(あるいは内蔵モデムカー ド)に載っているシリアル用チップのことです。UART の機能は、他の用途の チップが兼用で実現していることもあります。多くの 486 マシンのような古 いコンピュータでは、このチップはディスク I/O コントローラカードに載っ ていました。さらに古いコンピュータの中には、まだ専用のシリアルボードを 載せているものもあります。 UART の目的は、PC のパラレルバスからやってくるバイトデータをシリアルの ビットストリームに変換することです。シリアルポートから出ているケーブル はデータをシリアル(直列)に送るようになっており、データが流れる方向それ ぞれについて 1 つしか線がありません。シリアルポートは一度に 1 ビットず つビットストリームを送ります。逆に、外付けケーブルを経由してシリアルポ ートに入ってきたビットストリームは、コンピュータが処理できるパラレルな バイトデータに変換されます。UART はデータをバイト単位で扱います。この 単位は都合がいいことに ASCII 文字の大きさでもあります。 PC にぶら下がっている端末があるものとします。ユーザが文字を入力する と、端末はその文字をトランスミッタに(UART にも)送ります。トランスミッ タはそのバイトデータをシリアル回線に送り、送信は 1 バイトずつ、特定の 速度で行われます。PC 側では、受信を行う UART がビット列を全て受け取 り、(パラレルの)バイトデータに復元し、これをバッファに入れます。 シリアルとパラレルの変換に加えて、UART は主な処理の副産物(副作用)とし て他の処理もいくつか行います。ビット列を表すために使う電圧も変換(変更) されます。バイトデータが送信される前にそれぞれのバイトに対して追加の ビット(いわゆるスタートビットとストップビット)が加えられます。詳しくは Serial-HOWTO の``電圧の波形''の節を見てください。また、コンピュータ内 部のパラレルバス上のフローレート(バイト/秒)は非常に高いですが、シリア ルポート側の UART から出るフローレートはこれよりもずっと低いです。UART はいくつかの決められたフローレート(速度)の組を持っていて、これをシリア ルポートインタフェースで使うことができます。 15.2. 2 種類の UART UART の基本的な種類は 2 つ(ダム UART と FIFO UART)あります。ダム UART は 8250, 16450, 初期型 16550, 初期型 16650 です。これらは時代遅れのも のですが、これらの動作の仕組みがわかれば、FIFO UART(最近の 16550, 16550A, 16c552, 最近の 16650, 16750, 16C950)の動作を理解するのも容易で す。 16550 については紛らわしい点がいくつかあります。初期モデルにはバグがあ り、(FIFO を持たない)16450 としてしか正しく動作しません。バグが修正さ れた最近のモデルには 16550A という名前が付いていますが、多くのメーカー は名前を変更しておらず、16550 と呼び続けています。現在使われている 16550 の大部分は 16550A のようです。ハードウェアの説明書に 16550 であ ると書かれていても(あるいはラベルにそのように刻印されていても)、Linux は 16550A であると認識してくれます。同様の事情が 16650 にもあります(こ ちらの方が深刻です。というのも、聞いた話ではメーカーがバグを認めなかっ たからです)。Linux は最近の 16650 を 16650V2 として認識します。16650 と認識された場合には残念ながら、1 バイトのバッファしか持っていないよう に動作します。 15.3. FIFO ダムと FIFO(キューの動作がファーストイン・ファーストアウト(First In, First Out)である)の違いを説明するために、まずは UART が 1 バイトのデー タを送受信した場合のことを調べてみましょう。UART 本体は自分を通るデー タに関しては何も行わず、単にデータを送受信するだけです。元々のダム UART の場合は、バイトデータが送受信される度に CPU がシリアルデバイスか ら割り込みを受け取ります。CPU はこれを受けて、受信したバイトデータを UART のバッファから取り出してメモリ上のどこかに置くか、送信すべき次の バイトデータを UART に渡すかのどちらか動作を行います。8250 と 16450 UART には 1 バイトしかバッファがありません。つまり、1 バイトのデータを 送受信する度に CPU に割り込みがかかります。転送速度が低ければこれでも 大丈夫です。しかし転送速度が高速である場合には、UART の処理の負荷が CPU にかかりすぎるため、他の処理をうまく行えるだけの時間がなくなってし まいます。場合によっては、CPU の割り込み処理が間に合わなくなってしま い、バイトデータが上書きされてしまいます。なぜなら、データが入ってくる のが速過ぎるからです。これは「オーバーラン(overrun)」あるいは「オーバ ーフロー(overflow)」と呼ばれます。 これが FIFO UART が役立つ理由です。16550A(あるいは 16550)の FIFO チッ プには 16 バイトの FIFO バッファが付いています。つまり、CPU に割り込み がかかるまでに 14 バイトまでを受け取れます(16 バイトまでを送れます)。 たくさんのバイトデータを待てるだけではなく、CPU は 14 バイト全て(また はそれ以上)のバイトデータを同時に転送できます。これは、バッファを 1 バ イトしか持っていない他の UART に対して特に優れている点です。CPU が受け る割り込みも少なく他の処理に回せますし、データがなくなることもなく皆幸 せになれます。FIFO バッファの割り込みの閾値(トリガレベル)には 14 以下 の値が設定できる点に注意してください。この他には 1, 4, 8 が選べます。 大抵の PC には 16 バイトのバッファを持つ 16550 しか付いていませんが、 高級な UART にはもっと大きなバッファがあります。割り込みはバッファが いっぱいになる直前(例えば 16 バイトのバッファでは 14 バイトの「トリガ レベル」の時点)に発行される点に注意してください。こうすることにより、 割り込みサービスが実行される間にも何バイトかのデータを受け取れる余裕が 残ります。このトリガレベルには、カーネルのソフトウェアが許可した色々な 値を設定できます。トリガレベルを 1 にすると、ダム UART とほぼ同じにな ります(ただし、割り込みを発行した後にもさらに 15 バイトを受け取る空き が残っている点が異なります)。 BBS に入っている時に何か文字を入力した場合、入力した文字はシリアルポー ト経由で送り出されます。入力した文字が画面に表示されるのは、その文字が 電話回線・モデム・シリアルポート経由で画面にエコーバックされているから です。もしシリアルポートに 16 バイトのバッファが付いていて、14 バイト 集まるまで文字を送ってくれないとしたら、文字をたくさん入力しなければ入 力した文字が目で確認できない(画面に表示されない)ことになります。これで はややこしくてたまらないのですが、そんな事態を防ぐために「タイムアウ ト」があります。だからこそ普通は入力した文字が即座に表示されるのです。 UART の受信バッファの場合、この「タイムアウト」は 以下のように動作しま す: 文字が次々とやってくるなら、バッファに例えば 14 個目の文字がバッ ファに来たときにだけ割り込みが発行されます。しかし、ある文字が届いた後 にしばらく次の文字が届かなくてもやはり割り込みが発行されます。この割り 込みはたとえバッファに 14 個文字が入っていなくても発行されます(1 文字 でも入っていれば発行されます)。したがって、このバッファを通して文字を 入力すると、バッファの大きさが実際には 16 バイトであっても(あなたが文 字を打ち込む速さが普通の 100 倍でなければ) 1 バイトのバッファのように 動作します。同様の「タイムアウト」が送信バッファにもあります。 15.4. UART のモデル番号 以下に UART の一覧を示します。TL はトリガレベル(Trigger Level) です。 o 8250, 16450, 初期の 16550: バッファの大きさが 1 バイトである時代遅 れの UART です o 16550, 16550A, 16c552: 16 バイトのバッファがあります (TL=1,4,8,14) o 16650: 32 バイトのバッファがあります。460.8 kbps までの速度に対応 しています o 16750: 64 バイトの送信バッファ、56 バイトの受信バッファがありま す。921.6 kbps までの速度に対応しています o Hayes ESP: 1k バイトのバッファがあります 時代遅れの UART がうまく動作するのは 14.4k より遅いモデム(DTE 速度は 38400 bps まで)の場合だけです。最近のモデムでは、少なくとも 16550 (初 期型 16550 は含みません)が必要です。V.90 規格の 56k モデムの場合に は、16650 を使うと数パーセント速くなることがあります(特に圧縮されてい ないファイルをダウンロードする時)。16650 を使う主な利点はバッファのサ イズが大きいことです。というのも、モデムの圧縮比が高くなければ特に速度 は必要ないからです。一部の 56k 内蔵モデムには 16650 が載っています(筆 者は確かめていません)。 UART でなくインテリジェントなマルチポートボードでは、DSP チップを使っ てさらなるバッファリングと制御を行っています。したがって、CPU の負荷は さらに軽くなっています。例えば、Cyclades 製の Cyclom や Stallion 製の EasyIO ボードは Cirrus Logic CD1400 RISC UART を使って、これ以外の多く のボードは 80186 CPU や特殊な RISC CPU さえ使ってシリアル I/O を処理し ます。 最近の PC のほとんど(486, Pentium 以降のマシン)には 16550A (普通は単に 16550 と呼ばれます)が載っています。本当に古い PC をお使いにの場合は、 既存の 16450 チップを外して、新しく買った 16550A チップと置き換えるこ とによりアップグレードできます。他のタイプのチップが載っていた場合は、 残念ながらあきらめてください。UART がソケット形式ならば、(置き換える チップさえあれば)アップグレードは簡単でしょう。新しいチップと古いチッ プのピン配置は互換です。新しいシリアルボードをインターネットで購入でき るかもしれません(現在はシリアルボードを扱っている小売店はほとんどあり ません)。 16. ピン配置と信号 16.1. ピン配置 シリアルポートのピン配置 (「→」 が PC から外部への方向です) (DCD は CD と記載されることもあります) ピン番号 ピン番号 略称 正式名称 方向 動作および目的 9ピン 25ピン 3 2 TxD Transmit Data → PC からバイトデータを送信する 2 3 RxD Receive Data ← PC がバイトデータを受け取る 7 4 RTS Request To Send → RTS/CTS フロー制御 8 5 CTS Clear To Send ← RTS/CTS フロー制御 6 6 DSR Data Set Ready ← 通信可能になったことを知らせる 4 20 DTR Data Terminal Ready → 通信可能になったことを知らせる 1 8 DCD Data Carrier Detect ← モデムが相手と繋がっていることを示す 9 22 RI Ring Indicator ← 電話のベルが鳴っている状態を示す 5 7 Signal Ground 16.2. 信号は決まった意味を持っていないことがあります 9 本のピンのうち、割り当てが固定されているのは 3 つだけです (transmit(送信), receive(受信), signal ground(接地))。これはハードウェ アに固定されており、変更することはできません。しかし他の信号線はソフト ウェアで制御することができ、ほとんど何にでも使うことができます。しか し、配線は 2 つの状態しか取れません。すなわち正(+12 V)と負(-12 V) で す。正は「オン」であり、負は「オフ」です。例えば、Linux 用のソフトウェ アが DTR に負になるように命令を出すと、ハードウェアは単にこの命令を実 行し、DTR ピンの電圧を -12 V にします。DTR 信号を受け取るモデム(あるい は他のデバイス)は色々な動作をします。モデムの設定によっては、DTR が負 の状態になると電話を切ります。DTR が負(オフ)になったときに無視したり、 他の動作をすることもあります。 同じようなことが 6 本の線全てについて言えます。ハードウェアは信号を送 受信するだけですが、それによってどんな動作が行われるのかは、Linux のソ フトウェアやシリアルポートに接続しているデバイスの設定/設計次第です。 また、ほとんどのピンには通常行われる特定の機能がありますが、これは OS やデバイスドライバの設定によって変わってきます。Linux の場合は、ソース コードを変更すれば、これらの信号線の動作を変えることができます(そうし ている人もいます)。 16.3. シリアルポート間のケーブル接続 シリアルポートからのケーブルは、必ず別のシリアルポートに接続されます。 モデム等の、シリアルポートに接続するデバイスには、内部にシリアルポート が組み込まれています。モデムの場合、ケーブルは必ずストレートケーブル (同じピン同士が接続される)です。モデムは DCE (Data Communications Equipment) と言われ、コンピュータは DTE (Data Terminal Equipment)と言 われます。このように DTE と DCE を繋ぐ場合にはストレートケーブルが使わ れます。DTE 同士を繋ぐにはクロスケーブルを使わなければなりません。この ようなケーブルの結線にはたくさんの種類があります(Text-Terminal-HOWTO の "Direct Cable Connection" 節に書かれている例をご覧ください)。 このように色々なケーブルを使うのには理由があります。その 1 つは、信号 が片方向性を持つからです。ピン 2 が信号を送る場合は、(ピン 2 は信号を 受け取ることはできないので)ピン 2 を同じ種類のデバイスのピン 2 に接続 できないのは明らかです。接続してしまうと、両方のピンが同じ線に互いに信 号を送るのに、どちらも信号を受け取れないという状態になってしまいます。 これを解決する方法は 2 つあります。1 つめの方法は、2 種類の異なる機器 を使う方法であり、最初の機器のピン 2 が 2 番目の機器のピン 2 (これは信 号を受信できます)に信号を送るというものです。これは PC(DTE)をモデム (DCE)に繋ぐ時の方法です。2 つめの方法は、異なる種類の機器を使わずに接 続を行う方法です。すなわち送信ピン 2 を同じ種類の機器のピン 3(受信ピ ン)に繋ぎます。これは 2 台の PC を接続する時や、PC を端末に繋ぐ時の方 法です(DTE 同士の接続)。この目的で使われるケーブルはクロスケーブルと呼 ばれます。この例は 25 ピンコネクタの場合ですが、9 ピンコネクタの場合は ピンの番号はちょうど逆になります。 シリアルのピン指定は元々、ダム端末をモデムに接続するためのものでした。 端末は DTE (Data Terminal Equipment)で、モデムは DCE (Data Communication Equipment)でした。現在は普通は端末ではなく PC が DTE と して使われます(ただし本物の端末もまだ DTE として使われています)。ピン の名前は DTE でも DCE でも同じです。この場合には「受信(receive)」「送 信(transmit)」という言葉は PC (DTE) から見た立場で示されます。PC の送 信ピンからはモデムの「送信」ピンにデータが送られます(しかし実際には、 モデムはこのピンからデータを受け取るので、モデムの立場から見るとこれは 受信ピンと言えます)。 シリアルポートは元々、DTE を DCE に接続するためのものであり、その場合 にはケーブルの結線は単純です。単にストレートケーブルを使ってください。 したがってモデムを使う場合には、ピンの配置を気にする必要はほとんどあり ません。しかし、DTE を DTE に(例えばコンピュータを端末に)繋ぎたいとい う人々がいて、色々な特殊ケーブルが開発され、さまざまな接続方法が考案さ れました。この場合には、ピンの繋げ方は重要です。 16.4. RTS/CTS と DTR/DSR のフロー制御 これは「ハードウェア」のフロー制御です。フロー制御は既に ``フロー制 御''の節で説明していますが、ピンと電圧に関する説明はしていませ ん。Linux は現時点では RTS/CTS によるフロー制御しかサポートしていませ ん(特定のアプリケーション用の特殊ドライバでは DTR/DSR フロー制御をサポ ートしているものもあります)。ここでは RTS/CTS フロー制御しか説明しませ ん。なぜなら DTR/DSR フロー制御の動作も同様だからです。RTS/CTS フロー 制御を行うには、アプリケーションプログラムでハードウェアフロー制御を選 択するか、あるいは「stty crtscts < /dev/ttyS2」というコマンド(あるいは 同様のコマンド) を使う必要があります。これにより、Linux のデバイスドラ イバにおける、ハードウェアによる RTS/CTS フロー制御が有効になります。 それから DTE (PC 等)が入ってくるデータを止めたい時には、RTS をオフにし ます。RTS(「Request To Send」)をオフ(-12 V)にするのは「データをこちら に送らないでくれという要求(Request NOT To Send to me)」(送信停止) とい う意味です。PC が次のバイトデータを受け取る準備ができた時は、RTS をオ ン(+12 V)にすると、バイトデータが再び流れてくるようになります。フロー 制御信号が流れる向きは常に一方向であり、制御されているバイトデータの流 れの逆向きです。DCE 機器(モデム)も同様に動作しますが、停止信号を CTS ピンから送ります。このように、RTS/CTS フロー制御では線を 2 本を使いま す。 この停止信号はどのピンで受信されるのでしょうか? それは DCE-DTE 接続と DTE-DTE 接続で異なります。DCE-DTE 接続の場合には、ストレートケーブルが 使われるので、信号が受信されるのは当然ながら信号が送られたピンと同じ名 前のピンです。この場合は RTS→RTS (PC からモデムの向き)および CTS←CTS(モデムから PC の向き)となります。DTE 同士の接続の場合も説明は 簡単です。常に RTS ピンが送信を行い、CTS ピンが受信を行います。 2 台の PC (PC1 と PC2)がシリアルポート経由で接続される場合を考えてみましょ う。この場合は RTS(PC1)→CTS(PC2) および CTS(PC1)←RTS(PC2) となりま す。言い換えれば、RTS と CTS が交差しています。このようなケーブルは(他 の信号も交差しています)、「クロス」ケーブルと呼ばれます。詳しくは ``シ リアルポート間のケーブル接続''の節をご覧ください。 元々の RTS の使い方は先程の説明と反対なので、時々紛らわしくなります。 この元々の使い方とは「データをそちらに送るという要求(I Request To Send to you)」です。この要求は端末(またはコンピュータ)からモデムに送ること を想定したもので、この要求が受け入れられると、モデムの CTS ピンからコ ンピュータの CTS ピンへ CTS 信号が送り返されます(CTS は「データをこち らに送ってもよい(You are Cleared To Send to me)」という意味です)。最近 の RTS/CTS 双方向フロー制御と異なり、これは片方向のフロー(コンピュー タ(または端末) からモデムの方向)しか保護しません。この元々の使用法 は、(モデムを含めた) 現在の機器ではほとんど使われていないようです。 16.4.1. DTR と DSR のピン RTS と CTS の組合せと同様に、これらのピンも対になっています。DTE 同士 の接続の場合、これらは交差しているでしょう。これらのピンの使用法は 2 通りあります。1 つは RTS/CTS フロー制御の代わりとして使う方法です。DTR ピンは RTS ピンと同様に使えますし、DSR ピンは CTS ピンのように動作しま す。 Linux は DTR/DSR フロー制御はサポートしていませんが、PC の RTS/CTS ピンを DTR/DSR フロー制御を使うデバイスの DSR/DTR ピンに接続す ることにより、このようなフロー制御を行うことができます。DTR フロー制御 は DTR/DSR フロー制御とほぼ同じですが、片方向通信であり、DSR ピンが使 われない点が異なります。多くのテキスト端末や一部のプリンタではこの種の フロー制御が使われています。 DTR, DSR の通常の使用法を以下に示します。DTR がオンになっているデバイ スは、電源が入っており動作準備ができていることを示します。モデムの場合 は、PC がモデムに送る DTR 信号の意味はモデムの設定によって変わってきま す。DTR 信号を PC から stty コマンドを使って手動で送るには、ボーレート を 0 に設定してください。DTR をオフにすることは「ハングアップ」と呼ば れることもありますが、常にそれが行われるわけではありません。 16.5. ポートのオープンを禁止する方法 "stty -clocal" を実行する(あるいは "local" フラグを無効にして getty を 用いる)と、DCD がオン(+12 V)になるまではシリアルポートをオープンできま せん。 17. 電圧の波形 17.1. ビット 1 つを表す電圧 EIA-232 準拠のシリアルポートでは、電圧は二極式(接地電圧に対して正また は負)であり、その大きさは約 12 V です(5 または 10 V のものもありま す)。送信ピンと受信ピンでは +12 V が 0 を表すビット(「space」と呼ばれ ることもあります)で、-12 V が 1 を表すビットです(「mark」と呼ばれるこ ともあります)。これは反転論理として知られています。というのも、普通は 0 を表すビットは偽かつ負であり、1 は真と正を表すからです。送信ピンと受 信ピンは反転論理ですが、他のピン(モデム制御線) は通常の論理を用いてお り、正の電圧が真(または「オン」)であり、負の電圧が偽(または「オフ」)を 表します。電圧 0 は意味を持ちません(その機器の電源が切れているという意 味だけは持ちます)。 電圧に範囲を持たせることもできます。仕様においては、送信される信号の強 さは 5 V と 15 V の間でなければならず、25 V を超えてはなりません。3 V 未満の電圧は未定義です(ただしデバイスによっては電圧が低くても有効であ るとして受け付けます)。電圧はたいてい 11-12 V なのですが、「一般的に 5 V (あるいは 3 V) である」とする誤りをときどき見かけます。ただし Macintosh の EIA-422 ポートを EIA-232 (特殊なケーブルが必要)や EIA-423 としてお使いならば、電圧はまさしくわずか 5 V のはずです。ここでの説明 では 12 V を使うものとします。 通常のコンピュータの論理回路は数 V (かつては 5 V が標準だったこともあ りますが)しか使わないので、3-5 V のコンピュータ回路(TTL)の試験用に設計 されたテスト機器を 12 V のシリアルポートに対して用いると、テスト機器が 壊れてしまうことがあります。 17.2. バイトデータを表す電圧シーケンス 送信ピン(TxD)は、何も送っていないアイドル状態の時には -12 V (mark 状 態)を保持しています。バイトデータを送る際には、送信ピンはスタートビッ トを送るために +12 V (space 状態)となり、スタートビットを送る間(区間) は +12 V を保ちます。次にバイトデータの下位ビットが送られます。0 を表 すビットの場合は、何も変化せず、このバイト区間の間は送信ピンは +12 V のままです。1 を表すビットの場合は、電圧は +12 V から -12 V に変わりま す。次のビット以降も同様に送られます(1 ならば -12 V, 0 ならば +12 V)。 最後のデータビットの後にはパリティビットや、その後の -12 V (mark 状態) のストップビットが送られることもあります。その後は、次のスタートビット までは送信ピンは -12 V(アイドル状態)のままです。 0 V が返ってくること がないことと、そのため同じ極性を持つビットが 2 つ続く場合(0 が続く、あ るいは 1 が続く場合)には、あるビットが終わって次のビットが始まることを 表す簡単な方法が(同期信号以外には)ない点に注意してください。 2 番目のストップビットも -12 V になります。これは最初のストップビット と同じです。これらのビット間の境界を示す信号が無いため、2 番目のストッ プビットの影響は、送信ピンが続けている -12 V のアイドル状態の長さが 2 倍になる以外にはありません。2 番目のストップビットとバイト間の長いアイ ドル時間の区別を付ける方法は、受信側にはありません。したがって、うまく 通信できるのは、通信の片側がストップビットを 1 つ用い、その反対側がス トップビットを 2 つ用いた場合です。ただし、1 つしかストップビットを用 いない方が明らかに高速です。稀ですが、1 1/2 個のストップビットが使われ ることがあります。これは送信ピンが 1 1/2 区間の間 -12 V を保つという意 味です(ストップビットの長さが通常の 5 割増しになったようになります)。 17.3. パリティ検査 文字は普通、7 ビットまたは 8 ビットのデータで送信されます。これにパリ ティビットを追加すると(追加しないこともあります) 1 バイトの長さは 7, 8, 9 ビットのいずれかとなります。一部の端末エミュレータや古い端末で は、9 ビットは使えません。ストップビットを 2 つ使うと 9 ビットが使えな くなる端末もあります(というのも、スタートビットを追加した後の合計の ビット数が 12 ビットと多くなりすぎるからです)。 パリティには「奇数(odd)」、「偶数(even)」、「なし(none)」のいずれかを 設定します(一部の端末やシリアルデバイスでは、mark パリティや space パ リティがオプションとして使えます)。奇数パリティを使うと、バイトデータ 中で値が 1 になっているビットの数が(パリティビットも含めて)奇数となる ようにパリティビットが決められます。ビットがひっくり返って、このような バイトデータが壊れた場合、得られるデータは不正な偶数パリティのデータと なります。このエラーは検出されるので、これが端末が受け取ったバイトデー タであった場合には、文字化けを表す記号を画面に表示できます。偶数パリ ティの動作も同様であり、有効なバイトデータ中の 1 であるビット数が(パリ ティビットも含めて)偶数となるようにします。設定時には通常、文字当たり のビット数はバイト当たりのデータビットの数だけを意味します(正式な ASCII の場合には 7 ですし、各種 ISO 文字集合の場合には 8 です)。 "mark" は値が 1 であるビット(つまり論理値の 1)であり、"space" は値が 0 であるビット(つまり論理値の 0)です。mark パリティの場合には、パリティ ビットは常に値が 1 であるビットです。space パリティの場合には、これは 常に値が 0 であるビットです。mark パリティや space パリティ (「sticky パリティ」とも呼ばれます) は単にバンド幅を無駄にするだけなので、できる 限り使わないようにすべきです。 stty コマンドは sticky パリティを設定で きませんが、シリアルポートのハードウェアはこのパリティに対応してお り、C 言語のプログラムで扱うことができます。「パリティ無し」は、パリ ティビットを追加しないという意味です。9 ビットからなるバイトデータを受 け付けない端末を使う場合、8 ビット文字集合を使うならば「パリティ無し」 を選択しなければなりません。これはパリティビットを入れる空きが無いから です。 17.4. バイトデータの構成 (フレーム分割) EIA-232 ポートを使ったバイトデータのシリアル伝送では、常に低位のビット から先に送られます。PC のシリアルポートは非同期通信を行います。この非 同期通信では、スタートビットとストップビットがバイトデータの始めと終わ りを示します。このような区切り方はフレーム分割と呼ばれ、フレーム分割さ れたバイトデータはフレームと呼ばれることがあります。結果として、1 バイ トごとに 9 個 あるいは 10, 11 個のビットデータが送られます。この中で最 も一般的なのは 10 個です。8-N-1 とは、データビット 8 個、パリティ無 し、ストップビット 1 個という意味です。スタートビットを数に入れると合 計 10 ビットになります。ストップビット 1 つはほぼ例外なく使われます。 110 ビット/秒(300 ビット/秒の時もあります)では、ストップビットが 2 つ 使われていたこともありましたが、現在は 2 つめのストップビットが使われ るのはごく例外の時(あるいは、その設定でもうまく動作するために間違って 使われているけれど、バンド幅を無駄に消費している)だけです。 17.5. 「非同期」通信で同期を行う方法 PC が装備している EIA-232 のシリアルポートは非同期です。つまり実際に は、それぞれのビットを送る時に「時間を刻む」ための「クロック」信号が送 られないということです。送信(受信)用の線には 2 つしか状態がありませ ん。すなわち mark 状態(-12 V) と space 状態(+12 V)です。0 V の状態はあ りません。したがって 1 ビットのシーケンスは、ビットとビットの間を示す マーカーが無い定常的な -12 V だけを使って送られます。受信側で個々の ビットを区別するためには、送信側のクロックと同期しているクロック信号が 必ず必要です。このようなクロックは送信(受信)される各ビットと同期してい る「時間の刻み」を生成します。 非同期の伝送においては、スタートビットとストップビットを使って各バイト をフレーム分割することによって同期を実現します(これはハードウェアが行 います)。受信側は負の電圧の配線上で正のスタートビットを待ち、このビッ トを検出するとクロックを刻み始めます。受信側はこのクロック刻みを使っ て、次の 7, 8, 9 個のビットを読み込む時間を計ります(実際にはこれよりも もう少し複雑です。というのも、普通は 1 ビットからサンプル点をいくつか 取るので、そのために別のタイミング刻みが必要になるからです)。そしてス トップビットが読み込まれると、受信側はクロックを止めて、次のスタート ビットを待ちます。このように、単独のバイトデータを受け取る際には非同期 伝送も実際には同期伝送になりますが、複数のバイトデータの間での同期は行 われません。 18. その他のシリアルデバイス (非同期 EIA-232 以外のもの) 18.1. EIA-232 の後継 ツイストペア(平衡型伝送)技術を用いて高速・長距離を実現するために、たく さんの EIA 規格が今までに作られました。平衡型の伝送は、場合によっては 非平衡型の EIA-232 よりも百倍も速いことがあります。ある速度の場合、距 離(最大ケーブル長)はツイストペアを使った方が何倍も長くできます。ですが PC では「時代遅れな」EIA-232 が使われ続けています。というのも、モデム やマウスはケーブルが短いため、これで十分だからです。この HOWTO 文書が 最新版であり、かつ以下に示す非 EIA-232 を Linux がサポートしていれば、 筆者にお知らせください。 18.2. EIA-422-A (平衡型) と EIA-423-A (非平衡型) EIA-423 は非平衡型の EIA-232 とほとんど同じですが、電圧が 5 V しかない 点が異なります。これは EIA-232 規格に含まれるので、EIA-423 は EIA-232 ポートに接続することができます。この仕様は EIA-232 より多少速い速度を 求めています(ですが長時間動作すると非平衡伝送が衝突を起こすので、これ はほとんど役に立ちません)。 Apple の Macintosh のうち、1998 年の中頃より古いものには EIA-232/EIA-422 ポートが付いており、ツイストペア(平衡型)を送受信(422 として使った時)に使うことができました。これは(仕様上は) EIA-423(これ自 体は EIA-232 より多少高速です) のちょうど 100 倍高速です。 Macintosh は小さくて丸い "ミニ DIN-8" コネクタを使っていました。従来の EIA-232 ポートも付いていましたが、これは 5 V でしか使えませんでした(それでも正 当な EIA-232 です)。これを EIA-232 と同じように使うには、 RxD+ (平衡ペ アの片方の端)を接地した特殊なケーブルを使い、 RxD- を受信ピンとして使 わなければなりません。 TxD- は送信ピンとして使われますが、いくつかの理 由によって TxD+ は接地してはなりません。Macintosh Communications FAQ も参照してください。しか し、Macintosh (およびこれを改良したもの)は PC よりも値段が高いた め、Linux 用のホストコンピュータとしてはあまり使われていません。 18.3. EIA-485 これは EIA-422 (平衡型) に似ています。半二重です。これは point-to- point 接続だけでなく、マルチドロップ LAN (32 ノードまで)にも使うことが できます。コネクタの仕様は存在しません。 18.4. EIA-530 2M ビット/秒(平衡型) の EIA-530-A (平衡型ですが、非平衡型として使うこ ともできます)は EIA-232 を置き換えるためのものでしたが、ほとんど使われ ませんでした。EIA-232 と同じ 25 ピンコネクタを使います。 18.5. EIA-612/613 高速シリアルインタフェース (High Speed Serial Interface, HSSI = EIA-612/613)では 50 ピンのコネクタを使います。約 50 M ビット/秒の速度 が出ますが、数メートルの距離でしか使えません。Linux 用にも HSSI をサポ ートしている PCI カードがあります。このようなカードを販売している会社 が Linux 用のドライバを提供していること(あるいはドライバのありかを示し ていること)もよくあります。この話題については、mini-HOWTO のようなもの が必要でしょう。 18.6. 汎用シリアルバス (Universal Serial Bus, USB) 汎用シリアルバス(USB)は、PCI チップに組み込まれています。新しい PC は USB を備えています。USB は 4 ピンコネクタを持つツイストペアケーブル (2 つの結線は電源供給)を使って 12M ビット/秒の速度で通信できます。ただし 最長 5 メートル(この数字は構成によって変化します)という短い距離でしか 接続できません。 USB を説明するには別の HOWTO 文書が必要です。Linux で USB をサポートす るための作業は現在進行中です(ただし HOWTO 文書はまだありません)。USB は同期通信を行い、ネットワークと同様に特殊なパケットを使って送信を行い ます。ちょうどネットワークと同じように、USB には複数のデバイスを接続す ることができます。USB 上の各デバイスには、排他的な使用を行うための短い 時間のタイムスライスが与えられます。デバイスは、バスを固定の時間間隔で 使用できることが保証されます。他のデバイスが USB バスを使おうとしなけ れば、1 つのデバイスが USB バスを独占することができます。USB を詳しく 説明することは容易ではありません。 18.7. 同期通信と同期性 EIA-232 の非同期通信(など)の他に、同期シリアルポート通信の規格がたくさ んあります。実際は EIA-232 に同期通信の仕様がありますが、これは普通は PC のシリアルポートには付いていません。しかしまずは同期通信がどういう ものかを説明しましょう。 18.7.1. 非同期と同期の定義 非同期(async, asynchronous)とは「同期的でない」という意味です。実際に は非同期信号は、非同期シリアルポートが送受信するデータであり、スタート ビットとストップビットによって範囲が定められたバイト列のストリームで す。同期(sync)とは、非同期でないものほとんど全てです。ですが、これでは 基本的な概念の説明になりませんね。 理論的には、同期通信とは一定の速度でクロック信号の刻みに合わせてバイト 列が順に送られることです。クロック信号を送るための配線やチャンネルが別 になっていることもよくあります。非同期通信の場合には、バイトデータの間 の時間が(キーボードで文字を打ちこむ場合のように)不規則に変化しても送信 ができます。 同期通信あるいは非同期通信のどちらかへの分類が必要となる場合がありま す。非同期シリアルポートでも、多くの場合は一定速度のストリームを送りま す。これは同期通信のように思われるかもしれませんが、それでもスタート ビットやストップビットがあるので(これによりデータを不規則な速度で送信 できます)非同期通信と呼ばれます。別の場合としては、(スタートビットやス トップビットを含まない)バイトデータが、不規則なパケット間隔を持つこと があるパケットに入れられることがあります。これは同期通信です。というの も、各パケットに入っているバイト列は同期させて送信しなければならないか らです。 18.7.2. 同期通信 読者の皆さんは、シリアルポート用の 25 ピンコネクタの未使用のピンが一体 何なのかを疑問に思ったことはないでしょうか? 未使用のピンのほとんどは同 期通信用なのですが、同期通信を PC で行うことは滅多にありません。同期タ イミング信号や同期反転チャネルのためのピンがあります。 EIA-232 の仕様 には同期通信と非同期通信の両方が定義されていますが、PC は 16450, 16550A, 16650 等の UART (Universal Asynchronous Receiver/Transmitter) チップを使っており、同期通信を扱えません。同期通信を行うには USART チップあるいはそれと同等のチップを使う必要があります。 USART の S は同 期(synchronous)を表しています。同期通信はすきま市場なので、同期シリア ルポートは多くの場合かなり高くつきます。 EIA-232 の同期に関する部分の他にも、EIA には同期に関する規格が色々あり ます。EIA-232 では、コネクタの 3 つのピンがクロック(あるいはタイミン グ) 信号のために予約されています。また、ときにはモデムが何らかのタイミ ング信号を生成し、同期モデム (あるいは同じくタイミング信号を生成する 「同期モデムエリミネータ」) なしには同期通信ができないようにすることも あります。 シリアルポートが同期対応であることはほとんどないのですが、 V.42 エラー 訂正を使うモデムを用いた、電話回線上での同期通信はよく行われます。この エラー訂正はスタートビットとストップビットを取り除き、パケット中に日付 バイトを入れるもので、その結果として電話回線上で同期操作を実現します。 19. 他の情報源 19.1. 書籍 1. Axleson, Jan: Serial Port Complete, Lakeview Research, Madison, WI, 1998. 2. Black, Uyless D.: Physical Layer Interfaces & Protocols, IEEE Computer Society Press, Los Alamitos, CA, 1996. 3. Campbell, Joe: The RS-232 Solution, 2nd ed., Sybex, 1982. 4. Levine, Donald: POSIX Programmer's Guide , (ISBN 0-937175-73-0; O'Reilly) 5. Putnam, Byron W.: RS-232 Simplified, Prentice Hall, 1987. 6. Seyer, Martin D.: RS-232 Made Easy, 2nd ed., Prentice Hall, 1991. 7. Stevens, Richard W.: Advanced Programming in the UNIX Environment , (ISBN 0-201-56317-7; Addison-Wesley) 8. Tischert, Michael & Bruno Jennrich: PC Intern, Abacus 1996. Chapter 7: Serial Ports 書籍に関するメモ: 1. "... Complete" には(レジスタを含む)ハードウェアについて詳しく書かれ ていますが、プログラミングについては Windows 向けに書かれています。 2. "Physical Layer ..." は EIA-232 以外の話題もたくさん扱っています。 19.2. シリアルポート用ソフトウェア 最も近いミラーサイトを使うのが好ましいのですが、ここではメインのサイト を紹介します: Serial Software に は、getty やポートモニタを含むシリアルポート用のソフトウェア(Linux 用)があります。 Serial Communications には通信プログラムが あります。 o irqtune はシリアルポートの割り込みの優先度を高くし、性能を向上させ ます。hdparm を使ったハードディスクのチューニングも役に立つと思いま す。 o modemstat と statserial は各種モデム制御線の現在の状態を表示しま す。``シリアルポートの監視/診断用のプログラム''の節を見てください。 19.3. Linux 向けの文書 o setserial(8) stty のマニュアルページ o libc (または glibc) のドキュメント集: "低レベル端末インタフェース" o Modem-HOWTO: シリアルポートに接続するモデムについて o PPP-HOWTO: (シリアルポート接続のモデムを通じた)PPP 接続の手引き o Printing-HOWTO: シリアルプリンタの設定 o Serial-Programming-HOWTO: シリアルポートを使うプログラミングに関す る話題 o Text-Terminal-HOWTO: テキスト端末の動作とインストール・設定方法 o UPS-HOWTO: シリアルポートに接続する UPS センサの設定について o UUCP-HOWTO: UUCP の設定に関する情報 19.4. Usenet のニュースグループ: o comp.os.linux.answers o comp.os.linux.hardware: Linux で使えるハードウェアについて o comp.os.linux.networking: Linux におけるネットワークと通信について o comp.os.linux.setup: Linux のインストールとシステム管理 19.5. シリアルポートに関するメーリングリスト Linux シリアルメーリングリストがあります。参加するには、メール本文が ``subscribe linux-serial'' であるメールを majordomo@vger.rutgers.edu 宛に送ってください。メール本文が ``help'' であるメールを送ると、ヘルプ メッセージが送られてきます。このサーバは、他にも多くの Linux 関連メー リングリストを管理しています。メーリングリストの一覧を入手するに は、``lists'' コマンドを送ってください。 19.6. インターネット上の情報 o Vern Hoxie さんによる Serial Suite は、 Linux のシリアルポートの 扱いに関する資料と、簡単なプログラムの例を集めたものです。'scicom' に "anonymous" としてログインする時には、パスワードとして完全な電子 メールアドレスを使わなければなりません。例えば greg.hankins@cc.gatech.edu などです。 o シリアル通信とマルチポートシリアルボードの議論を行った白書が Cyclades の WWW ページ http://www.cyclades.com から入手できます。 20. 日本語訳について 日本語訳は Linux Japanese FAQ Project が行いました。翻訳に関するご意見 は JF プロジェクト 宛に連絡してください。 改訂履歴を以下に示します。 v1.10j, 30 June 1997 翻訳: 永田靖人 v2.00j, 30 June 1999 v2.01j, 29 September 1999 v2.02j, 19 October 1999 v2.03j, 21 November 1999 v2.04j, 9 December 1999 v2.05j, 22 January 2000 v2.07j, 21 May 2000 翻訳: 藤原輝嘉 校正 & テクニカルチェック: o 川岸良治 o 幸田章宏 o 武井伸光 o 山下義之 以上