記事「Linux カーネルの全体的なアーキテクチャ」の中で、Wowo は、Linux カーネルは世界中のさまざまな機能を持つほぼすべてのハードウェア デバイスをサポートしており、これも Linux の利点であると述べました。ただし、これにより、Linux カーネル内のコードの半分がデバイス ドライバーになることになり、ハードウェア デバイスの急速なアップグレードに伴い、デバイス ドライバー コードの量も急速に増加しています。私の意見では、この現象は「シンプルであることは美しい」という概念を破壊し、Linux カーネルを非常に肥大化させ、煩雑で、保守を困難なものにしています。ただし、Wowo は、これが Linux のせいではないことも理解しています。Linux はマクロ カーネルであり、デバイスの多様性に直面し、対応するドライバーを実装する必要があるからです。
デバイスの多様性によって引き起こされる Linux ドライバー開発の複雑さを軽減し、デバイスのホットプラグや電源管理などの機能を実装するために、Linux カーネルにはデバイス モデル (ドライバー モデルとも呼ばれる) の概念が導入されています。デバイス モデルはハードウェア デバイスを分類して要約し、一連の標準データ構造とインターフェイスを抽象化します。このようにして、ドライバーの開発は簡単になり、カーネルによって指定されたデータ構造を入力して実装するだけで済みます。
この記事では、デバイス モデルの基本概念から開始し、対応するカーネル コードの分析を通じて、Linux デバイス モデルの実装と使用方法を段階的に説明します。
次の図は、組み込みシステムの一般的なハードウェア トポロジの例です:
ハードウェア トポロジは、Linux デバイス モデルの 4 つの重要な概念のうちの 3 つ、バス、クラス、デバイスを説明します (4 番目はデバイス ドライバーであり、これについては後で説明します)。
バス (バス): Linux は、バスが CPU と 1 つ以上のデバイス間の情報交換のチャネルであると考えています (include/linux/device.h の struct Bus_type のコメントを参照できます)。デバイス モデルの抽象化を容易にするために、すべてのデバイスをバス (CPU 内部バス、仮想バス、または「プラットフォーム バス」のいずれか) に接続する必要があります。
クラス (分類): Linux デバイス モデルにおけるクラスの概念は、オブジェクト指向プログラミングのクラスに非常に似ており、主に類似した機能や属性を持つデバイスを集めて、デバイスの集合を抽象化できます。複数のデバイス間で共有される構造とインターフェイス機能。したがって、同じクラスに属するデバイスに属するドライバーは、これらのパブリック リソースを繰り返し定義する必要がなくなり、クラスから直接継承できるようになります。
Device (デバイス): システム内のすべてのハードウェア デバイスを抽象化し、その名前、属性、下位バス、下位クラス、その他の情報を記述します。
デバイス ドライバー: Linux デバイス モデルは、ドライバーを使用してハードウェア デバイスのドライバーを抽象化します。これには、デバイスの初期化と電源管理に関連するインターフェイス実装が含まれます。 Linux カーネルでのドライバー開発は、基本的にこの抽象化 (指定されたインターフェイス関数の実装) を中心に展開します。
注: プラットフォーム バスとは何ですか?
コンピュータには、それぞれのデバイス コントローラを介して CPU に直接接続されているタイプのデバイスがあり、CPU は通常のアドレス指定操作を通じてそれらのデバイスにアクセス (またはそのコントローラにアクセス) できます。この接続方法は、従来の意味でのバス接続ではありません。ただし、デバイス モデルはユニバーサルである必要があるため、Linux はこれらのデバイスが接続するための架空のプラットフォーム バスを作成します。
Linux デバイス モデルの中心的な考え方は (xxx の手段を通じて xxx の目的を達成する):
\1. Device (struct device) と Device Driver (struct device_driver) の 2 つのデータ構造を使用して、それぞれ「何に使うか」と「どのように使用するか」という 2 つの観点からハードウェア デバイスを記述します。これにより、デバイス ドライバーの作成形式が統一され、ドライバー開発が論述問題から穴埋め形式に変更されるため、デバイス ドライバーの開発が簡素化されます。
\2. また、デバイスとデバイス ドライバーの 2 つのデータ構造を使用して、ハードウェア デバイスのプラグ アンド プレイ (ホットプラグ) を実現します。
Linux カーネルでは、デバイスとデバイス ドライバーが同じ名前である限り、カーネルはデバイス ドライバー構造内の初期化関数 (プローブ) を実行し、デバイスを初期化して使用できるようにします。
ほとんどのホットスワップ可能なデバイスでは、デバイス ドライバーは常にカーネル内に存在します。デバイスが接続されていない場合、そのデバイス構造は存在しないため、そのドライバーは初期化操作を実行しません。デバイスが挿入されると、カーネルはデバイス構造 (ドライバーと同じ名前) を作成し、ドライバーの実行をトリガーします。これがプラグアンドプレイの概念です。
\3. 「バス –> デバイス」タイプのツリー構造 (第 2.1 章の凡例を参照) を通じてデバイス間の依存関係を解決します。この依存関係は、電源のオン/オフ、電源管理などのプロセスで特に重要です。 。
デバイスがバスにマウントされていると仮定すると、デバイスを起動するには、まずそのデバイスがマウントされているバスを起動する必要があります。システム内に多くのデバイスがあり、依存関係が非常に複雑な場合は、カーネル開発者もドライバー開発者もこの関係を維持できないことは明らかです。
デバイス モデルのツリー構造は、この依存関係を自動的に処理できます。デバイスを起動する前に、カーネルはデバイスが他のデバイスまたはバスに依存しているかどうかを確認します。依存している場合は、依存オブジェクトが起動されているかどうかを確認します。そうでない場合は、デバイスの起動条件が整うまで、それらを最初に起動します。会った。ドライバー開発者が行う必要があるのは、デバイス ドライバーを作成するときにデバイスの依存関係をカーネルに通知することです。
\4. クラス構造を使用し、デバイス モデルにオブジェクト指向の概念を導入すると、共通の機能を最大限に抽象化し、ドライバー開発プロセスの重複作業を減らし、作業負荷を軽減できます。
以上がLinuxデバイスモデルの詳細説明(1)_基本概念の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。