linux 6.5 udev は、Linux カーネルのデバイス マネージャーです。その主な機能は、「/dev」ディレクトリの下のデバイス ノードを管理することです。また、devfs (デバイス ファイル システム) とホットプラグ ( hot plug) Insert) 機能; 従来の Linux システムでは、「/dev」ディレクトリ内のデバイス ノードは一連の静的に存在するファイルですが、「udev」はシステム内に実際に存在するデバイス ノードを動的に提供します。
#このチュートリアルの動作環境: Linux 6.5 システム、Dell G3 コンピューター。
Linux 6.5 udev とは何ですか?
udev udevadm の概要と Linux デバイスの名前変更と自動マウントのアプリケーション例の分析
Wikipedia での udev の定義は次のとおりです: udev (ユーザースペース /dev) は、Linux カーネルのデバイス マネージャーです。devfsd および hotplug の後継として、udev は主に /dev ディレクトリ内のデバイス ノードを管理します。同時に、udev は、特定のデバイスで必要とされるファームウェアのロードなど、ハードウェア デバイスがシステムに追加または削除されたときに発生するすべてのユーザー空間イベントも処理します。中国語: udev は、Linux カーネルのデバイス マネージャーです。その主な機能は、/dev ディレクトリの下のデバイス ノードを管理することです。また、devfs (デバイス ファイル システム) と hotplug (ホット プラグ) の機能を引き継ぐためにも使用されます。つまり、ファームウェアのロード時を含むハードウェアの追加/削除時に、/dev ディレクトリとすべてのユーザー空間の動作を処理する必要があります。
従来の Linux システムでは、/dev ディレクトリ内のデバイス ノードは一連の静的ファイルですが、udev は動的に提供されます。システム内に実際に存在するデバイス ノード。 devfs も同様の機能を提供しますが、udev には devfs よりも優れた利点があります。
udev は、ユニバーサル カーネル デバイス マネージャーです。 Linux システム上でデーモンとして実行され、新しいデバイスが初期化されるとき、またはデバイスがシステムから削除されるときに、カーネルによって (ネットリンク ソケット経由で) 発行される uevents をリッスンします。
システムは、検出可能なデバイス イベントと属性のエクスポートされた値を照合するための一連のルールを提供します。一致ルールでは、デバイス ノードに名前を付けて作成し、構成プログラムを実行してデバイスを構成できます。 udev ルールは、カーネル サブシステム、カーネル デバイス名、デバイスの物理プロパティ、デバイスのシリアル番号などの属性と一致します。ルールでは、デバイスに名前を付けるための情報を外部プログラムに要求したり、デバイスがシステムによっていつ検出されたかに関係なく、常に同じになるカスタム名を指定したりすることもできます。システム アーキテクチャ:
libudev 関数ライブラリ。デバイス情報を取得するために使用できます。
(2) udevadm コマンドの概要
udevadm info --query=all --name=sda 查询sda的所有信息 udevadm info --query=path --name=sda 查看sda的path udevadm info --attribute-walk --name=/dev/nvme0n1 查看nvme0n1的所有父设备一直到sysfs的根节点
--query=type 指定されたタイプを問い合わせます。データベースからデバイスを取得します。デバイスを指定するには、--path と --name が必要です。正当なクエリ ファイルは次のとおりです: デバイス名、リンク、パス、属性
--path=devpath デバイスパス
--name=file デバイスノードまたはリンク
--attribute-walk 指定されたデバイスに関するすべての情報を出力します。特定のデバイスを udev ルールと照合するために sysfs によって記録されるデバイスのプロパティ。このオプションは、可能な限り sys ディレクトリに至るまで、チェーン上のすべてのデバイス情報を出力します。
--device-id-of-file=file マスター/スレーブ デバイス番号を出力します。
--export-db udev データベースの内容を出力します。
udevadm Monitor [オプション] カーネルイベントおよび udev によって送信されたイベントを監視します。印刷イベントの発行元のデバイス。イベントのタイミングは、カーネルまたは udev イベントのタイムスタンプを比較することで分析できます。
udevadm monitor --property 输出事件的属性 udevadm monitor --kernel --property --subsystem-match=usb 过滤监听符合条件的时间
--kernel カーネル イベントを出力します
--udev udev ルールが実行されるときに udev イベントを出力します
--property イベント プロパティを出力します
--subsystem-match=string サブシステムまたはデバイス経由タイプフィルターイベント。サブシステム値と一致する udev デバイス イベントのみが渡されます。
--tag-match=string イベントを属性でフィルタリングし、タグに一致する udev イベントのみを通過させます。
udevadm test [options] devpath udev イベントをシミュレートし、デバッグ情報を出力します。
udevadm Trigger [オプション] カーネルから送信されたデバイスイベントを受信します。主にコールドプラグ イベント情報を再生するために使用されます
(カーネルは起動時にシステムのハードウェア デバイスを検出し、sysfs カーネル仮想ファイル システムを通じてハードウェア デバイス情報をエクスポートしました。udev は sysfs ファイル システムをスキャンし、ハードウェア デバイスに基づいてホット プラグを生成します) information. Hotplug events, udev then read these events and generated precision hardware device files. 実際のハードウェアの接続と取り外しのアクションはないため、このプロセスは coldplug と呼ばれます。)
--verbose 出力はデバイス リストをトリガーします。
--dry-run 実際にはイベントをトリガーしません
--type=type 特別なデバイスをトリガーします。有効なタイプ: デバイス、サブシステム、失敗。デフォルトは devices
--action=action。トリガーされたイベント。デフォルトはchange
--subsystem-match=subsystem。一致するサブシステムをトリガーするデバイス イベント。このオプションは複数回指定でき、シェル パターン マッチングをサポートします。
--attr-match=attribute=value sysfs 属性と一致するデバイス イベントをトリガーします。属性値が属性と一緒に指定されている場合、シェル パターンを使用して属性値を照合できます。値が指定されていない場合、既存のプロパティが再検証されます。このオプションは複数回指定できます。
--attr-nomatch=attribute=value 属性に一致するデバイス イベントをトリガーしません。可能であればパターンマッチングを使用してください。
--property-match=property=value を複数回指定して、一致するプロパティを持つデバイスを照合することもできます。パターン マッチングをサポートするには、複数回指定できます。
--tag-match=property 一致するタグを持つデバイスを照合します。複数指定可能です。
--sysname-match=name 同じsysデバイス名を持つデバイスを照合します。サポートパターンマッチングは複数指定可能です。
udevadm Set [オプション] udevイベントキューを表示し、すべてのイベントが処理されたら終了します。
--timeout=秒 イベントキューが空になるまで待機する最大時間。デフォルトは 180 秒です。 0の場合はすぐに終了します。
--seq-start=seqnum 指定されたシーケンス番号になるまでのみ待機します。
--seq-end=seqnum 指定されたシーケンス番号になるまでのみ待機します。
--exit-if-exists=file ファイルが存在する場合は終了します
--quiet 情報を出力しません
udevを使用して実装しますUSB、SD カード デバイスの名前変更、自動マウント、自動アンマウント。
この機能の簡単な応用については、別のブログ「udev renames device node names to activate storage devicepartitions」を参照してください。
この記事では、主に使用中に発生した問題を記録します。 . と注意事項。
在海思平台,对于有些SD卡或是USB自动挂载有些时候会出现冲突的问题,问题现象就是自动挂载的时候有时候有时候U盘和SD卡自动挂载相互干扰。主要原因点是因为海思的HI35XX的很多设备不具备SDIO总线,所以如果要使用SD的设备,一般都是将SD卡通过读卡器转换为USB总线信号。对于对于这类问题,可以通过SD卡的读卡器ID来区分是USB还是SD卡设备。
在海思平台可以使用下面命令查看USB设备信息:
lsusb:
~ # lsusb Bus 001 Device 002: ID 1c9e:9b3c Bus 001 Device 003: ID 05e3:0610 Bus 001 Device 001: ID 1d6b:0002 Bus 002 Device 001: ID 1d6b:0001 Bus 001 Device 008: ID 0951:1642 Bus 001 Device 009: ID 05e3:0716 Bus 001 Device 006: ID 0bda:8176 ~ #
cat device
~ # cat /sys/kernel/debug/usb/devices T: Bus=02 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=12 MxCh= 2 B: Alloc= 0/900 us ( 0%), #Int= 0, #Iso= 0 D: Ver= 1.10 Cls=09(hub ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=1d6b ProdID=0001 Rev= 3.10 S: Manufacturer=Linux 3.10.0 ohci_hcd S: Product=HIUSB OHCI S: SerialNumber=hiusb-ohci C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr= 0mA I:* If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub E: Ad=81(I) Atr=03(Int.) MxPS= 2 Ivl=255ms T: Bus=01 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=480 MxCh= 2 B: Alloc= 0/800 us ( 0%), #Int= 5, #Iso= 0 D: Ver= 2.00 Cls=09(hub ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=1d6b ProdID=0002 Rev= 3.10 S: Manufacturer=Linux 3.10.0 ehci_hcd S: Product=HIUSB EHCI S: SerialNumber=hiusb-ehci C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr= 0mA I:* If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub E: Ad=81(I) Atr=03(Int.) MxPS= 4 Ivl=256ms T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=1c9e ProdID=9b3c Rev= 3.18 S: Manufacturer=LONGSUNG S: Product=USB Modem C:* #Ifs= 5 Cfg#= 1 Atr=80 MxPwr=500mA I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=option E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=83(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=85(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=GobiNet E: Ad=89(I) Atr=03(Int.) MxPS= 8 Ivl=32ms E: Ad=88(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms T: Bus=01 Lev=01 Prnt=01 Port=01 Cnt=02 Dev#= 3 Spd=480 MxCh= 4 D: Ver= 2.00 Cls=09(hub ) Sub=00 Prot=02 MxPS=64 #Cfgs= 1 P: Vendor=05e3 ProdID=0610 Rev=32.98 S: Product=USB2.0 Hub C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=100mA I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=01 Driver=hub E: Ad=81(I) Atr=03(Int.) MxPS= 1 Ivl=256ms I:* If#= 0 Alt= 1 #EPs= 1 Cls=09(hub ) Sub=00 Prot=02 Driver=hub E: Ad=81(I) Atr=03(Int.) MxPS= 1 Ivl=256ms T: Bus=01 Lev=02 Prnt=03 Port=00 Cnt=01 Dev#= 8 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=0951 ProdID=1642 Rev= 1.00 S: Manufacturer=Kingston S: Product=DT 101 G2 S: SerialNumber=001CC0EC32F7BB40F71300BF C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=200mA I:* If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms T: Bus=01 Lev=02 Prnt=03 Port=02 Cnt=02 Dev#= 9 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=05e3 ProdID=0716 Rev=97.27 S: Manufacturer=Genesys S: Product=USB Reader S: SerialNumber=000000000013 C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=500mA I:* If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms T: Bus=01 Lev=02 Prnt=03 Port=03 Cnt=03 Dev#= 6 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=0bda ProdID=8176 Rev= 2.00 S: Manufacturer=Realtek S: Product=802.11n WLAN Adapter S: SerialNumber=00e04c000001 C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=500mA I:* If#= 0 Alt= 0 #EPs= 4 Cls=ff(vend.) Sub=ff Prot=ff Driver=rtl8192cu E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=84(I) Atr=03(Int.) MxPS= 64 Ivl=125us ~ #
查看上面信息可以知道USB相关的设备有:
Product=HIUSB EHCI #海思USB总线
Product=USB Modem #上网模块
Product=USB2.0 Hub #USB HUB
Product=DT 101 G2 # U盘
Product=USB Reader # usb 读卡器
Product=802.11n WLAN Adapter #USB网卡
对于一个设备如果要匹配他的多个属性,或者是同一个属性,它在不同的层级中有不同的值,那么这个时候需要使用GOTO功能。比如在一个设备中要重名名一个USB设备,它的命令如下:
KERNEL=="sd*",KERNELS=="*:0:0:1",ATTRS{scsi_level}=="0" ,ATTRS{product}=="USB Reader",ATTRS{idVendor}=="05e3",ATTRS{idProduct}=="0716",SYMLINK+="usbsda%n",OPTIONS="ignore_remove"
这里涉及到多个属性ATTRS 值的匹配,另外该USB因为有些经过了usbHUB,所以他的idVendor 和 idProduct 有多个,就有总线的,也有HUB的,还有USB设备的,这样的情况下是匹配不上设备的。具体是什么原因我没有找到一个合理的解释,但是我又一个可用的解决方案,那就是使用GOTO。将上面命令改成如下就可以了。
KERNEL=="sd*",KERNELS=="*:0:0:1",ATTRS{scsi_level}=="0" GOTO="hisi_end" ATTRS{product}=="USB Reader",ATTRS{idVendor}=="05e3",ATTRS{idProduct}=="0716",SYMLINK+="usbsda%n",OPTIONS="ignore_remove" LABEL="hisi_end"
udev的一些匹配规则有些时候比较的莫名其妙,我也没有找到哪里有比较详细的说明,网上的介绍都它过于简单,实际应用的时候还是很多的问题,比如针对上面介绍的设备,如果要写一条卸载设备的命令,可以使用下面语句:
ACTION=="remove",KERNELS=="*:0:0:1",ATTRS{idVendor}=="05e3",ATTRS{idProduct}=="0716",RUN+="/bin/umount -l /opt/usb_sd1_1"
但是在实际使用的时候,他们匹配不上,ACTION=="remove",KERNELS=="*:0:0:1"与ATTRS{idVendor}=="05e3",ATTRS{idProduct}=="0716" 不能同时使用,如果直接改成:
ACTION=="remove",KERNELS=="*:0:0:1",RUN+="/bin/umount -l /opt/usb_sd1_1"
命令功能可以实现,但是这样会出现于设备冲突的情况,在拔出该设备的时候,会把KERNELS=="*:0:0:1" 的其他设备也卸载掉。
在这个时候,我们可以使用 devadm monitor --property 去监控设备拔出的时候它有哪些事件,有哪些属性可以被捕捉到并且与其他的设备属性不同以便区分不同的设备。下面是截取到的一部分数据:
[10:00:33]KERNEL[1555639338.737818] remove /devices/platform/hiusb-ehci.0/usb1/1-2/1-2.3 (usb) [10:00:33]UDEV_LOG=3 [10:00:33]ACTION=remove [10:00:33]DEVPATH=/devices/platform/hiusb-ehci.0/usb1/1-2/1-2.3 [10:00:33]SUBSYSTEM=usb [10:00:33]DEVNAME=bus/usb/001/007 [10:00:33]DEVTYPE=usb_device [10:00:33]PRODUCT=5e3/716/9727 [10:00:33]TYPE=0/0/0 [10:00:33]BUSNUM=001 [10:00:33]DEVNUM=007 [10:00:33]SEQNUM=1024 [10:00:33]MAJOR=189 [10:00:33]MINOR=6
从上面可以看出,拔出的时候有个PRODUCT ,它是 idVendor 和 idProduct 值的一个组合,可以使用它来区分不同的设备。最终可以正常卸载设备的命令如下:
ACTION=="remove",SUBSYSTEM=="usb",ENV{PRODUCT}=="5e3/716/9727",RUN+="/bin/umount -l /opt/usb_sd1_1"
相关推荐:《Linux视频教程》
以上がLinux 6.5 udevとは何ですかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。