私は最近、Linuxネットワークドライバを学んでいます。ボード上に同じタイプのネットワークカードがたくさんあると、どのようにカーネルがそれらを動かすのでしょうか?カーネルは同じドライバを何度もロードする必要がありますか?私はそれは不可能だと思う、insmodはそれをしないだろう、私はどのように同じ種類のカードを同時に動作させることができますか?Linuxは、同じドライバを使用して多数のネットワークカードをどのように駆動するのですか?
に関して
私は最近、Linuxネットワークドライバを学んでいます。ボード上に同じタイプのネットワークカードがたくさんあると、どのようにカーネルがそれらを動かすのでしょうか?カーネルは同じドライバを何度もロードする必要がありますか?私はそれは不可能だと思う、insmodはそれをしないだろう、私はどのように同じ種類のカードを同時に動作させることができますか?Linuxは、同じドライバを使用して多数のネットワークカードをどのように駆動するのですか?
に関して
すべてのカードの状態(I/Oアドレス、IRQs、...)は、ドライバ固有の構造に格納され、ドライバの各エントリポイントに(直接的または間接的に)渡されます。カード。そうすれば、同じコードが異なるカードを制御することができます(つまり、カーネルは、制御するデバイスの数に関係なく、ドライバのモジュールのインスタンスを1つだけ保持します)。
例えば、非常に簡単なLCDパワードライバであるdrivers/video/backlight/platform_lcd.c
を見てください。これにはplatform_lcd
という名前の構造体が含まれています。この構造体はこのファイル専用で、LCDの状態(電源が入っているかどうか、および中断されているかどうか)を保存します。この構造の1つのインスタンスは、kzalloc
(つまり、LCDデバイスごとに1つ)を介してドライバのprobe
機能に割り当てられ、platform_set_drvdata
を使用してLCDを表すプラットフォームデバイスに格納されます。それが作業している場合を知っているように、このデバイスのために割り当てられたインスタンスは、他のすべてのドライバ機能の開始時に、再度フェッチされる:
struct platform_lcd *plcd = to_our_lcd(lcd);
to_our_lcd
dev_get_drvdata
(Aに展開それ自体lcd_get_data
に展開platform_set_drvdataの対応部分)を参照してください。include/linux/lcd.h
この関数は、そのために呼び出されたデバイスの状態を知ることができます。
これは非常に単純な例であり、platform_lcd
ドライバはデバイスを直接制御しません(これはプラットフォームデータの関数ポインタに委ねられます)。ハードウェア固有のパラメータ(IRQ、I/Oベースなど)を追加します。 )、Linuxのドライバの99%がどのように動作するのかを知ることができます。
ドライバコードは一度だけロードされ、それは各カードの別のコンテキスト構造を割り当てます。通常、.probe
ファンクションポインタを持つstruct pci_driver
が表示されます。プローブ機能は、PCIサポートコードによってカードごとに1回呼び出され、alloc_etherdev
を呼び出して、必要なプライベートコンテキストのためにスペースのあるネットワークインターフェイスを割り当てます。
返信いただきありがとうございます! – liunx
ありがとう、私はカーネルに複数の同じデバイスを追加する方法を知っていますが、platform_device構造体のid、0,1,2などを増やすだけで、ドライバはこれらのデバイスをうまく検出できます。 – liunx
プラットフォームデバイスの場合、idを-1に設定して、システム内にデバイスのインスタンスを1つしか指定できないようにすることもできます(Linuxは、デバイス名を出力するときにIDを省略します)。 platform_devicesは特定であり、他のバスは異なる方法で動作する可能性があることに注意してください。番号の代わりにアドレスを使用してデバイスを識別することによって、 – Gnurou
良いヒント、もう一度ありがとう! – liunx