既存のドライバで遊んでみたい方や、まだサポートされていないカードのドラ イバを自分自身で書いてみたい方には、この情報はとても役に立ちます。もし、 あなたが上に挙げたような方でなければ、この章は飛ばすとよいでしょう。
隙間のないパケットの送受信が既にできていれば、それ以上のビットデータを ネットワークに流すことはできません。現在のイーサネットカードは全て、隙 間なくやってくるパケットを受け取ることができます。Linux の DP8390 ドラ イバ(wd80x3, SMC-Ultra, 3c503, ne2000 等)は、もう少しで隙間なくパケッ トを送信できる所まで来ています(これは現在の割り込みの遅延に依存します)。 また、3c509 と AT1500 のハードウェアは自動的に隙間がないパケットを送信 するので全く問題ありません。
ISA バスは 5.3MB/秒(42Mb/秒)を処理できます。これは 10Mbps のイーサネッ トに対しては十分以上に思われます。100Mbps のカードの場合には、ネットワー クのバンド幅の恩恵を受けるためには高速なバスが明らかに必要です。
利点: 制限付きのシステムリソースを使わず、I/O レジスタを数個使うだけで ある。16M の制限を受けない。
欠点: 普通は転送速度が最も遅い。CPU はずっと待ち状態となり、 インタリーブ処理されるパケットのアクセスは普通は困難であるか、不可能で ある。
利点: 単純かつプログラムド I/O より高速で、パケットへのランダムなアク セスが可能である。可能であれば、Linux のドライバはやってきた IP パケットをカードからコピーする際にそのチェックサムを計算する。 これにより、同等の PIO カードよりも CPU の使用量が少ない。
欠点: メモリ空間をたくさん消費する(DOS ユーザにとっては多いでしょう。 Linux では本質的にはあまり関係ありません)。また、PIO カードより少ない にせよ、それでも CPU をたくさん使う。
利点: 実際のデータ転送の間は CPU が解放される。
欠点: 境界条件のチェック、連続したバッファの割り当て、DMA レジスタのプ ログラミングがあるため、全ての技術の中で一番動作が遅い。希少な DMA チャネルをたくさん使う上に、低位メモリ上にバッファを持たなければならない。
利点: データ転送の間 CPU を解放する。複数のバッファを繋げることができ、 ISA バスでも CPU 時間をあまり無駄にしないか、ほとんど無駄にしない。 バスマスタを行う Linux のドライバの大部分は現在 `copybreak' スキームを 使っている。このスキームでは、大きなパケットはカードから直接カーネルの ネットワークバッファに入れられ、小さなパケットは CPU によってコピーさ れ、CPU は後での処理のためにキャッシュにパケットの内容を知らせる。
欠点: (ISA バスのカードにだけ当てはまる) 低位メモリのバッファと、カード用の DMA チャネルを必要とする。どんなバ スマスタカードでも、バスを食い潰す他のバスマスタカードがあると問題を起 こす。例えば、このようなカードとしては初期の SCSI アダプタがある。 設計が悪い一部のマザーボード用チップセットは、バスマスタカードで問題を 起こす。どんな種類の DMA デバイスも使えない場合としては、 386 のソケットに挿して置き換えるように設計された 486 プロセッサを使う 場合がある。このようなプロセッサは、DMA 周期の各サイクルでキャッシュを フラッシュする。(これには Cx486DLC, Ti486DLC, Cx486SLC, Ti486SLC 等が 含まれる。)
ちゃんと動いてくれるドライバさえあれば、どんなイーサネットカードで も Linux で利用できます。このためにはメーカーがプログラミングに関する 技術的情報を、人生を放棄する書類にサインする必要なしに、一般に向けて公 開することが絶対条件です。文書を得られるかどうか(あなたがコードを書か ないのならば、あなたが本当に欲しいドライバを誰かが書いてくれるかどうか) の良いガイドは、Crynwr さん(旧姓 Clarkson さん)のパケットドライバが入 手できるかどうかです。Russ Nelson さんはこの作戦を実行して、Linux 用の ドライバの開発をサポートするのに大変有用なことを実証しました。ネットサー ファーなら以下の Russ' software の URL を見てください:
ドキュメントを入手できれば、自分でカード用のドライバを書き、それを Linux 上で使うことができます(少なくとも理屈としては)。XT マシン用に設計 されたいくつかの古いハードウェアは Linux などのマルチタスクな環境では うまく動いてくれないということを覚えていてください。XT タイプのものを 使う場合、大量のトラフィックを扱うときに大きな問題が発生することがあり ます。
ほとんどのカードは NDIS や ODI など MS-DOS 用のドライバが付属していま すが、 Linux にはこれらのものは無用です。多くの人は直接リンクしたり、 自動的に変換することを提案していますが、これは不可能に近いのです。 MS-DOS 用のドライバは 16 ビットモードで動作し、ソフトウェア割り込みを使っ てフックしますが、両者とも Linux カーネルでは不可能なものです。Linux 用のドライバの中には MS-DOS 用のものよりも著しく優れたものもあるのです から、こういった非互換性も機能のうちというが本当のところでしょう。例え ば、 8390 シリーズのドライバは MS-DOS の世界にのみ知られているピンポン 転送バッファを利用しています。この非互換性は実際には仕様であり、いくつ かの Linux 用のドライバはMS-DOS 用のそれよりも相当に良いものです。
(ピンポン転送バッファとは少なくとも 2 つの最大サイズのパケットバッファ を転送用パケットに使うということを意味します。一方はカードがもう片方の バッファを転送している間にロードされます。バッファの転送が終るとすぐに 次のバッファが次々に転送されます。このようにして、ほとんどのカードは連 続してやってくるパケットを転送することができるのです。)
さて、プログラミングに関する情報を手に入れ、それがいまだ実装されていな いのだから(... この二つは主要な必要条件です ;-)、どこかのイーサネット カード用にドライバを書くことを決意されましたね。Linux のカーネルソースツリー に含まれている骨組みとなるようなネットワークドライバから始めるべきです。 これは最近のカーネルの /usr/src/linux/drivers/net/skelton.c にあります。 また、以下に挙げる URL の「Kernel Hackers Guide」も見てみると良いでしょ う: KHG
新しくドライバを作る際に、あなたが書かなければならない関数に関するいく つかの注意があります。上記の骨組みドライバと並行してここに書かれて あることを読むと、状況をはっきりさせる手助けになるでしょう。
起動時にカードの存在を検査します。メモリなどから読み込むことによって あまりでしゃばらずに検査するのがベストでしょう。I/O ポートから読み込む こともできます。他のデバイスを kill してしまうかも知れないので、検出時 に I/O ポートに対する初期書き込みは良くありません。いくつかのデバイス の初期化は通常この段階で行われます (I/O 空間 や IRQ を割り当て、 dev->??? フィールドに値を代入します)。あなたはそのカードがどの I/O ポー ト/メモリ に設定できるのか、(もし使われているのであれば) 共有メモリ をどのように有効にするのか、また割り込み発生をどのように選択/有効に するのかを知っている必要があります。
カードが割り込みを発生させるとカーネルによって呼ばれます。これはカード がなぜ割り込みを発生させたのかを調べ、それに応じた処理を行うということ を担当します。通常、割り込みが生じる条件は、データが記録されたり、転送 が終了したり、エラーの状態をレポートする場合などです。この条件に応じて 処理を行うことができるように、関係する割り込み状態を保持するビットを知っ ている必要があります。
dev->hard_start_xmit() に連結されており、カーネルがデバイスに出力す るべきデータが存在する場合に呼ばれます。これによってデータがカードに出 力され、転送が行われます。そのためにはどのようにデータをまとめカードに 出力するか(共有メモリーコピーか、PIO 転送か、DMA か?)、またどのようにし てカード上の正しい位置に出力するか知っている必要があるでしょう。更にい かにしてケーブルへ向けてカードがデータを転送するように指示し転送後割り 込みを発生させるかを知っている必要があります。ハードウェアが次のパケッ トを受け付けることができない場合、dev->tbusy フラグがセットされます。 またパケットを受け付けるためのバッファが空いている場合(通常、転送完了 時の割り込みの間)、dev-tbusy はクリアされ mark_bh(INET_BH) によってよ り上位の層へと伝えられます。
カーネルの割り込みハンドラが受信関数を呼び出すのは、「情報がある」とカー ドが報告してきた時です。受信関数はカードからデータを取得し、sk_buff に保持し netif_rx(sk_buff) によってカーネルに受信したデータが存在する ことを知らせます。データ受信時の割り込み発生を有効にする方法、 関係する受信ステータスビットをチェックする方法、カードからデータを受け 取る方法(転送時と同じく、共有メモリー, PIO, DMA 等のいずれか)を理解し ている必要があるでしょう。
オープン関数は dev->open に連結されており、ifconfig eth0 up
が
実行されたとき - これはデバイスをオンラインにしデータの送信を有効しま
す - ネットワーク層によって呼ばれます。デバイスの自動検出時(IRQ の有効
化など)に行われなかった特殊な初期化処理がここでなされます。
クローズ関数は ifconfig eth0 down
が実行されたときにカードを正常
な状態に設定します。ハードウェアが許可すれば IRQ と DMA チャネルを開放し、
トランシーバのような電源供給元をオフにします。
この部類の関数にはリセット関数のようなものが含まれます。ドライバは最終 手段としてカードをリセットできます。これらは通常、送信がタイムアウトす るなどした場合に行われます。また、カード上に統計的データを保存しておく レジスタが備わっている場合、そのデータを読み込む関数もあります。
もしあなたが 3Com 用のドライバに関して興味を持っているのなら、 3Com か ら技術情報を得ることができます。 Cameron は親切にも、どのようにすれば いいのか教えてくれました。
3Com のイーサネットアダプタは「テクニカル リファレンス」(TRs) の中で ドライバを書く人のために解説されています。これらのマニュアルはボードへ のプログラムインタフェースについて述べていますが、対話的なインスト レーションプログラムやその他エンドユーザが見るようなものについては触れ られていません。
ネットワークアダプタ部門のマーケティング部は無料で TR を公開するように しています。このプログラムを効率良くしておくために、'CardFacts' と呼ば れるものに集約しています。`CardFacts' とは自動化された電話 応対システムです。プッシュホンで電話することによってファックスの形で取 り寄せることができるのです。 TR を手に入れるには、 408-727-7021 の CardFacts へ電話してみてください。ドキュメント番号 9070 の Deveoper's Order Form を依頼しましょう。電話するときには、すでにファックスが準備 されているようにしてください。Order form の書式に従って記入し、 408-764-5004 へファックスしてください。マニュアルは Federal Express の 2nd Day サービスで届くはずです。(訳注 実際にはアメリカ(?)の電話番号で すので、このままダイヤルしないでください)
マニュアルが気前良く出されすぎていると考えている人がいて、彼らはシステ ムが高価すぎる証拠、あるいは時間や手間がかかりすぎている証拠を探そうと しています。今のところ、3Com の顧客はこの点について実際に満足しており、 我々が行ってきた要求のレベルは問題ないと言えます。我々には協力を続けて いくことと、このように節度を保つことも必要です。
AMD LANCE (Local Area Network Controller for Ethernet) は、独自の製品 で 79C960 としても知られている `PCnet-ISA' チップによって置き換えられま した。 AMD が出している比較的新しいチップである 79C960 は現在リリース されている多くの新しいカードの中核をなしているものです。`LANCE' という 名前は使われていない場合が多く、新しいチップを古い名前で読んでいる人も います。 AMD のネットワーク製品部門の Dave Roberts は親切にもこのチッ プに関して次のような情報を公開してくれました。
「機能的には NE1500 に相当するものです。レジスタセットは古い 1500/2100 アーキテクチャの LANCE に等しく、 古い 1500/2100 用ドライバが PCnet-ISA 上で動作可能でしょう。 NE1500 と NE2100 アーキテクチャは基本 的には同じ物です。 もともとの Novell が 2100 と命名しましたが、 そのと きは 10BASE-2 と 10BASE-T の違いを指すものとして使おうとしていたようで す。 10BASE-T のカードは 1500 番台の番号がつけられるはずでした。違いは これだけです。
HP や Racal-Datacom, Allied Telesis, Boca Research, Kingston Technology などを含む多くのメーカーが PCnet-ISA ベースの製品をリリース しています。いくつかの製造メーカーがソフトウェアによってカードの設定を 可能にするような「ジャンパ無し」機能を追加している以外は、これらのカー ドは基本的には同じものです。しかし、ほとんどのカードはこのような「ジャ ンパ無し」機能は持っていません。 AMD が PCnet-ISA 使うカード向けに標準 デザインパッケージというものを提供していて、多くの製造メーカーはそれを 変更なしに利用しているためです。つまり、誰でも PCnet-ISA ベースのカー ド用ドライバを書いてみようという人はデータシートを AMD から取り寄せる ことができるということです。AMD の literature distribution center (800)222-9323 に電話して、 Am79C960, PCnet-ISA データシートに関して聞 いてみてください。なお、これは無料です。
通常のカードであるかどうかを調べる一番簡単な方法は、直接そのカードを見 てみることです。もし、通常のカードであれば、大きなチップと、水晶振動子、 小さな IEEE アドレス PROM、そしておそらくブート ROM のためのソケット、 そしてコネクタ( これは提供されているメディアオプションに依存して 1/2/3 個 と変化します )が付いています。10BASE-2 カードであれば、トランシーバ がいくつか載っているということに注意してください。なお、PCnet-ISA チッ プからは離れたコネクタ周辺に載っていることが多いようです」
カードをいじってみたい人に注意してほしいのは、LANCE カードでも 実装が異なれば「リスタート」の方法も異なるということです。 鳴りやんだところで信号を 拾いあげるものもあれば、鳴り始めた時点で(ちょうど初期化されたかのよう に)信号を拾いはじめるものもあります。
Donald が貢献してくれたことのもう一つは、マルチキャストと無差別モード のフックの実装に関してです。リリースされている ISA 用の全てのカード(つ まりアルファ版ではないもの)のドライバは無差別モードをサポートしていま す。
Donald は以下のように述べています: 「概念的に実装が簡単な無差別モードから始めてみよう。ほとんどのハードウェ アに対してしなくちゃならないのは、レジスタビットを設定することだ。そ うすれば、ワイヤ上の全てのパケットを受け取ることができる。さて、これは だいたいこんな要領だ。いくつかのハードウェアはボードを閉じて (これはい くつかのパケットを落してしまうかも知れない)、再設定し、そしてさらに再 度イーサネットカードを有効にする。 ねえ、簡単だろう。さて、次にこれほどは明白じゃないことをしよう。マルチキャス トだ。マルチキャストをするには二通りのやり方がある:
ここでいくつかのイーサカードやイーサチップが持っている機能を紹介しなけ ればならないだろう:
チップ/カード 無差別モード マルチキャストフィルタ ------------------------------------------------------ Seeq8001/3c501 あり Binary filter (1) 3Com/3c509 あり Binary filter (1) 8390 あり Autodin II six bit hash (2) (3) LANCE あり Autodin II six bit hash (2) (3) i82586 あり Hidden Autodin II six bit hash (2) (4)
これらのチップのどれもが完全なフィルタリングを行わず、そして最終的なフィ ルタリングをするために中間レベルのモジュールが必要であることに注目する こと。また全ての場合において、受信許可したマルチキャストアドレス が変化した場合ハッシュテーブルを再計算するため許可されたマルチキャスト アドレスの完全なリストを保持しなければならないことにも注目するといい」
開発者の一般的な考えは、BPFはカーネルによって提供されるのではなく、(で きればあまり使われない)互換性ライブラリによって提供されるべきであると いうものです。
知らない人のための説明: BPF とはカーネルのネットワーク層にどのパケット が関与しているのかを指定するための機構です。これはネットワークコードの 下位のレベルにおいて専用のスタック言語インタプリタとして実装されて います。アプリケーションはこの言語によって書かれたプログラムをカーネル に渡し、カーネルはやってくるパケットに対してこのプログラムを実行します。 もしカーネルが複数の BPF アプリケーションを持っている場合、それぞれの プログラムはそれぞれのパケットに対して実行されることになります。
問題は、パケットフィルタプログラムによってアプリケーションがどの種類の パケットと本当に関係があるのかを推測することが難しいということです。し たがって、常にフィルタを実行するということが一般的な解決法になります。 マルチキャストアドレスに向けて低いデータ転送量のストリームを抽出するた めに BPF プログラムを登録するアプリケーションを想像してみてください。 ほとんどのイーサネットカードは、多くの不必要なマルチキャストのパケット を無視する 64 のエントリからなるハッシュテーブルとして実装されているハー ドウェア的なマルチキャストアドレスフィルタを持っているため、容易にこ の処理を行ってしまう可能性があります。しかし BPF の場合、カーネルは インタフェースを無差別モード、つまり「全て」のパケットを受信するモード、 に変更しなくてはならず、これらの処理をこのフィルタによって行わなけれ ばなりません。これは動作しますが、この処理はパケットを要求するプロセス へきちんと応答することが非常に難しいのです。