######I.はじめに######
2.1 USB コントローラーがデバイスの挿入を検出します
モジュールは最初に、デバイスの製造元 ID、製品 ID、カテゴリ コード、その他の情報を含むデバイス記述子を検出します。
一致するドライバーがすでに存在する場合、usbcore
モジュールはドライバーをロードします。一致するドライバーがない場合は、ほとんどの USB デバイスをサポートできるユニバーサル ドライバーをロードしようとします。
2.3 ドライバーが USB サブシステムに登録されます
デバイス ノードの作成は、udev
デーモン プロセスを通じて行われます。このデーモン プロセスは、システム内のデバイスのプラグインおよびアンプラグ イベントを監視し、対応するデバイス ノードを自動的に作成または削除します。デバイス ノードが作成されると、カーネルはデバイスへのアクセス権をユーザー空間プログラムに割り当てることができます。
新しいデバイスが挿入されたことがドライバーに通知されると、ドライバーはデバイスを初期化します。初期化には、デバイスの転送速度の設定、メモリ バッファの割り当てなどが含まれる場合があります。デバイスの初期化が完了すると、ドライバーは USB サブシステムにデバイスの準備ができたことを報告します。
最後に、ユーザー空間プログラムはデバイス ノードを開いてデバイスと通信できます。デバイス ノードの権限は、通常、root ユーザーまたは関連するグループ内のユーザーのみにアクセスを許可するように設定されています。ユーザー空間プログラムは、read
や write
などのシステム コールを使用して、デバイスにコマンドを送信し、データを受信できます。
このプロセスを通じて、Linux システムは自動的にデバイスを識別し、対応するドライバーをロードして、デバイスが正常に動作できるようにします。これは、USB デバイスを接続するときに、ドライバーを手動でインストールしたり、デバイスを直接使用し始めるためにその他の操作を実行したりする必要がない理由でもあります。
USB デバイスを接続すると、Linux システムは上記の手順を自動的に実行して、デバイスを自動的に識別し、対応するドライバーをロードして、デバイスが正常に動作できるようにします。コードレベルからプロセスを分析してみましょう。
以下では、いくつかのサンプルコードを通じて、Linux システムにおける USB デバイスの識別とロードのプロセスを説明します。これらのサンプル コードは原理を説明するためのものであり、実際のコードはさらに複雑になります。
USB デバイスがシステムに接続されると、割り込み信号が生成され、プロセッサ上の USB コントローラー割り込みラインによって捕捉され、カーネルの USB サブシステムによって処理されます。以下は、USB デバイスのプラグインおよびアンプラグ イベントを検出する方法を示すサンプル コードです:
リーリーこのコードは、USB デバイスにアクセスするために使用される C 言語ライブラリである libusb ライブラリを使用します。 USB デバイスにアクセスするための API だけでなく、USB サブシステムの初期化と USB バスのスキャンのための API も提供します。
デバイスが接続されていることが検出されると、USB サブシステムは適切なドライバーをロードしようとします。以下は、USB ストレージ デバイス (USB フラッシュ ドライブなど) のサポートを担当するサンプル ドライバー コードです。 リーリー
このコードは、USB ストレージ デバイスの挿入および取り外しイベントを処理できる単純なドライバーを示します。ドライバーをロードするとき、カーネルは、ロードされたドライバーのリストからデバイスに一致するドライバーを検索します。一致するドライバーが見つかった場合、カーネルはそのドライバーを使用してデバイスを管理します。一致するドライバーが見つからない場合、カーネルはドライバーをロードしません。
上記のサンプル コードでは、カーネルの
usb_get_descriptor() 関数を使用してデバイス記述子を取得し、printk()
関数を使用してデバイス情報をカーネル ログに記録します。
ドライバーはデバイス初期化関数を呼び出してカーネルに登録しますが、デバイスの初期化と登録のプロセスはデバイスによって異なるため、コードのこの部分はここでは省略されています。
一旦设备已经被注册到内核,用户空间程序就可以通过设备节点来访问设备。在Linux系统中,设备节点是一种特殊的文件,可以通过标准文件I/O函数来访问。下面是一个示例代码,演示如何打开并读取USB存储设备:
#include #include #include int main() { // 打开设备节点 int fd = open("/dev/sdb", O_RDONLY); if (fd printf("Failed to open device\n"); return 1; } // 读取设备数据 char buf[1024]; ssize_t n = read(fd, buf, sizeof(buf)); if (n printf("Failed to read device\n"); close(fd); return 1; } // 关闭设备节点 close(fd); return 0; }
这段代码使用了标准的文件I/O函数来访问设备节点。在这个例子中,设备节点的路径是/dev/sdb
,这是一个典型的USB存储设备节点。接下来,程序将设备节点作为文件打开,并使用read()
函数从设备中读取数据。一旦完成数据的读取,程序将关闭设备节点并退出。
Linux系统识别USB设备的过程可以分为四个步骤:设备连接、驱动匹配、设备注册和设备访问。当用户将USB设备插入计算机时,内核将通过USB总线来检测设备的插入事件,并尝试查找与设备匹配的驱动程序。一旦找到了匹配的驱动程序,驱动程序将被加载并启动,它将尝试对设备进行初始化,并将其注册到内核。一旦设备已经被注册到内核,用户空间程序就可以通过设备节点来访问设备。
在Linux系统中,驱动程序是非常重要的组成部分,它们负责管理和控制系统中的各种设备。对于USB设备而言,内核提供了一个通用的USB驱动框架,它可以自动检测和加载驱动程序,并为用户提供了一个简单而强大的USB设备访问接口。通过深入理解USB驱动程序的工作原理,我们可以更好地理解Linux系统中设备管理的内部机制,这对于开发和调试设备驱动程序非常有帮助。
以上がLinux は接続した USB デバイスをどのように識別するのでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。