console= パラメータに r オプションを付けて、 Linux カーネルに CTS/RTS のフロー制御をさせることができます。 例えば、速度が 9600bps、データが 8 ビット、 パリティ無し、CTS/RTS のフロー制御、というシリアルリンクは、 Figure A-1 で示すように設定します。
Figure A-1. CTS/RTS フロー制御を行なう、カーネルの console パラメータ
console=9600n8r |
Linux カーネルは常にデータを送出するだけなので、 CTS/RTS フロー制御は、 "Clear to Send" がアサートされていないことを確認する という実装になっています。 この部分のコードは、 /usr/src/linux/drivers/char/serial.c にあります。 関連部分は Figure A-2 にあります。
Figure A-2. コンソールの CTS/RTS フロー制御用カーネルソースコード
static inline void wait_for_xmitr(struct async_struct *info) { … /* Wait for flow control if necessary */ if (info->flags & ASYNC_CONS_FLOW) { tmout = 1000000; while (--tmout && ((serial_in(info, UART_MSR) & UART_MSR_CTS) == 0)); } } |
tmout 値を 1000000 にしてループすることで、 CTS ラインがアサート状態になるまで、1 秒ほど待つことになります。
このコードでは、 RS-232 の "Data Set Ready" と "Data Carrier Detect" の両ステータスラインからのステータスを無視しています。 しかし、こうしてしまうと、多くの不都合が出てきます。
RS-232 ケーブルを抜いていたり、 ターミナルサーバーのポートがアイドル状態の場合、 このコードは、約 1 秒間 CTS がアサートされるのを待ちますが、 その間にコンソールにはあらゆる文字が書き込まれます。 そうなると、マシンのブート時に、 コンソールに大量の文字が書き込まれることになり、 その結果リブートが非常に長時間かかってしまいます。
"Clear to Send" のアサートが有効なのは、 "Data Carrier Detect" と "Data Set Ready" がアサートされる場合だけです。 このコードは、電源が入っていないデバイスのことを考慮すべきです。 デバイスに電源が入っていないと、 CTR がフロート状態になります。
百万回のループ後、"Clear to Send" がアサートされていなければ、 とにかく文字を送出します。よって、 マルチドロップの RS-232 ラインでは、 このカーネルは使えません。 それどころか、文字落ちが起こるでしょう。
"Data Carrier Detect" がアサートされていなくても、 文字は送出されます。 ですから、接続されているモデムはコマンドモードになるかも知れません。 もし任意のテキストをコンソールメッセージ中に入れることができれば、 このことがセキュリティ上の欠陥になってしまいます。 多くのコンソールメッセージには、 ユーザーイベントから派生したエラーテキストが入っていますから、 コンソールメッセージ中に AT&F を入れて、モデムの自動応答設定を外すのは、そう難しいことではないでしょう。
こういうバグがあるので、この HOWTO では、 カーネルレベルのフロー制御は、もうお奨めしません。 筆者は、現在報告されているバグすべてを修復するパッチを持っており、 カーネル本体にこのパッチを取り込んでもらおうとしています。 カーネルのこのバグが修正されてしまえば、 この HOWTO では、 再度カーネルレベルのフロー制御をお奨めしたいと思います。