7

USBWi-Fiアダプター用にCで記述されたLinuxカーネルドライバーコードを理解しようとしています。1456ファイル内の行/drivers/net/wireless/rtl818x/rtl8187/dev.c(誰かがコンテキストのためにカーネルコードを参照したい場合に備えて)は次のようになります。

    priv->map = (struct rtl818x_csr *)0xFF00;

ここで正しいオペランドが何をしているのか知りたいです- (struct rtl818x_csr *)0xFF00;。私はこれを「メモリアドレス0xFF00をタイプにキャストrtl818x_csrしてから割り当てる」と解釈してきましたpriv->map。私の解釈が正しければ、メモリアドレスの何が特別なので0xFF00、ドライバーはそれが後に続くものが常にこのアドレスにあることを確実に知ることができますか?私が興味を持っているもう1つのことは、0xFF00は16ビットしかないということです。メモリアドレスをキャストする場合、32/64ビットを期待します。

誰かがこのコード行で何が起こっているのかを正確に明確にすることができますか?C構文の理解に欠陥があると思います。

4

3 に答える 3

2

デバイスの観点からこれを考慮する必要があります。

rtl8187デバイス用にマップされたアドレス空間内のアドレス0xFF00から始まるのは、ここで定義されたrtl818x_csr構造体と同じ方法で構造化された情報を保持するメモリ範囲です。

したがって、その領域を論理的にマッピングした後、バスの読み取りと書き込みを開始して、デバイスを制御できます。ここのように(3つ以上投稿するのに必要な評判がないため、さらに2つのハイパーリンクをカットする必要がありましたが、ポイントは得られます)。これらはほんの一例です。ファイル全体を読み取ると、読み取りと書き込みがいたるところに散らばっています。

その構造がそのように見える理由と、0xBEEFまたは0xDEADの代わりに0xFF00が使用される理由を理解するには、そのデバイスのデータシートを参照する必要があります。

したがって、カーネルコード、特にデバイスドライバーを調べ始めたい場合は、コードだけでは不十分です。データシートまたは仕様も必要になります。これを見つけるのはかなり難しい場合があります(ベンダーからのオープンドキュメントを求める膨大な数の電子メールスレッドと記事を参照してください)。

とにかく、私はあなたの質問に答えたと思います。ハッピーハッキング!

于 2012-08-01T10:15:11.443 に答える
2

絶対アドレスを構造体へのポインターにキャストすることは、ドライバーが通常の C 構造体としてデバイスの (メモリマップされた) レジスターにアクセスする一般的な方法です。

0xff00Cは数値の符号拡張を行わないため、使用は機能します。

于 2012-08-01T10:00:03.540 に答える
2

0xFF00システムの IO アドレス空間のアドレスです。コードを見ると、アドレスは直接逆参照されることはなく、IO 関数を介してアクセスされます。

たとえば、呼び出しで

rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
                 RTL818X_EEPROM_CMD_CONFIG);

次に、Linux カーネルの低レベル IO 関数を呼び出します。

アドレスは構造体へのポインターにキャストされ、アドレスからのオフセットにアクセスできます。例を次に示します。

0xFF00 + offsetof(struct rtl818x_csr, EEPROM_CMD)

rtl818x_iowrite8上記の呼び出し&priv->map->EEPROM_CMDでは、演算子のために引数を渡すときに逆参照は発生せ&ず、アドレス + オフセットのみが計算されることに注意してください。逆参照は、 inside と呼ばれる内部低レベル関数内でさらに実現されますrtl818x_iowrite8

于 2012-08-01T10:10:18.827 に答える