首頁  >  文章  >  運維  >  linux 6.5 udev是什麼

linux 6.5 udev是什麼

藏色散人
藏色散人原創
2023-04-10 11:00:171018瀏覽

linux 6.5 udev是Linux核心的裝置管理員;它主要的功能是管理「/dev」目錄底下的裝置節點,它同時也是用來接替devfs(裝置檔案系統)及hotplug(熱拔插)的功能;在傳統的Linux系統中,「/dev」目錄下的設備節點為一系列靜態存在的文件,而「udev」則動態提供了在系統中實際存在的設備節點。

linux 6.5 udev是什麼

本教學操作環境:linux 6.5系統、Dell G3電腦。

linux 6.5 udev是什麼?

udev udevadm介紹及linux設備重新命名與自動掛載應用實例分析

(一)UDEV介紹

#    udev在維基百科的定義是:udev (userspace /dev) is a device manager for the Linux kernel. As the successor of devfsd and hotplug, udev primarily manages device nodes in the /dev directory. Atmanages device nodes in the /dev directory. Atmanages device nodes in the /dev directory. the same time, udev also handles all user space events raised when hardware devices are added into the system or removed from it, including firmware loading as required by certain devices。用中文來說就是:udev是Linux核心的裝置管理員。它主要的功能是管理/dev目錄底下的設備節點。它同時也是用來接替devfs(裝置檔案系統)及hotplug(熱拔插)的功能,這意味著它要在新增/移除硬體時處理/dev目錄以及所有使用者空間的行為,包括載入firmware時。

(1)udev概要:

    在傳統的Linux系統中,/dev目錄下的裝置節點為一系列靜態存在的文件,而udev則是動態提供了在系統中實際存在的設備節點。雖然devfs提供了類似功能,但udev有比devfs更加好的地方:

  • udev支援裝置的固定命名,而並不依賴裝置插入系統的順序。預設的udev設定提供了儲存設備的固定命名。可以使用其vid(vendor)、pid(device)、裝置名稱(model)等屬性或其父設備的對應屬性來確認某一設備。
  • udev完全在使用者空間執行,而不是像devfs在核心空間一樣執行。結果就是udev將命名策略從核心移走,並且可以在節點創建前用任意程式在設備屬性中為設備命名。

(2)udev運作方式:

    udev是通用的核心裝置管理員。它以守護程序的方式運行於Linux系統,並監聽在新設備初始化或設備從系統中移除時,核心(透過netlink socket)發出的uevent。
    系統提供了一套規則用來符合可發現的裝置事件和屬性的匯出值。匹配規則可能命名並建立設備節點,並運行配置程式來對設備進行設定。 udev規則可以符合像核心子系統、核心裝置名稱、裝置的物理等屬性,或裝置序號的屬性。規則也可以請求外部程式提供資訊來命名設備,或指定永遠一樣的自訂名稱來命名設備,而不管設備何時被系統發現.

(3)udev系統架構:

udev系統可以分成三個部分:

  • libudev函數庫,可以用來取得裝置的資訊。
  • udevd守護進程,處於使用者空間,用於管理虛擬/dev
  • 管理指令udevadm,用來診斷出錯情況。

系統取得核心透過netlink socket發出的資訊。早期的版本使用hotplug,並在/etc/hotplug.d/default添加一個連結到自身來達到目的。

(二)udevadm 指令介紹

    在Linux man page 中它是這樣描述的。 udevadm - udev management tool 。也就是說udevadm指令是管理udev的一個工具。實際我們如果要實現設備的重命名或是設備的自動掛載,我們也是使用udevadm來查看和追蹤udev的資訊。
    udevadm可以用來監控和控制udev運行時的行為,請求核心事件,管理事件佇列,以及提供簡單的偵錯機制。

(1)udevadm主指令:

  • info      查詢sysfs或udev的資料庫
  • trigger 從核心請求events
  • #settle   檢視udev事件佇列,如果所有的events已處理則退出
  • control  修改udev後台的內部狀態資訊
  • monitor 監控核心的uevents
  • hwdb    處理硬體資料庫索引
  • #test偵錯

(2)指令應用:

(a)檢視裝置資訊:

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     裝置節點或連結
--attribute-walk      sysfs記錄的屬性,以用來udev規則來匹配特殊的設備。此選項列印鏈上的所有設備訊息,最大可能到sys目錄。
--device-id-of-file=file 列印主/從設備號碼

--export-db       輸出udev資料庫中的內容

(b)監控設備事件:

    udevadm monitor [options] 監聽核心事件和udev所傳送的events事件。列印事件發出的設備。可以透過比較內核或udev事件的時間戳來分析事件時序。

udevadm monitor --property   输出事件的属性
udevadm monitor --kernel --property --subsystem-match=usb    过滤监听符合条件的时间

--kernel  輸出核心事件
--udev  輸出udev規則執行時的udev事件
--property  輸出事件的屬性
--subsystem-match=string  透過子系統或設備類型過濾事件。只有符合了子系統值的udev設備事件通過。

--tag-match=string  透過屬性過濾事件,只有符合了標籤的udev事件通過。

(c)模擬一個udev事件

    udevadm test [options] devpath  模擬一個udev事件,列印出debug訊息。

(d)接收核心傳送來的裝置事件


    udevadm trigger [options]  接收核心傳送的裝置事件。主要用於重播coldplug事件資訊
(核心在啟動時已經偵測到了系統的硬體設備,並把硬體設備資訊透過sysfs核心虛擬檔案系統匯出。udev掃描sysfs檔案系統,根據硬體裝置資訊產生熱插拔(hotplug)事件,udev再讀取這些事件,產生對應的硬體設備檔案。由於沒有實際的硬體插拔動作,所以這一過程被稱為coldplug。)
--verbose     輸出將要被觸發的設備列表。
--dry-run      不真的觸發事件
--type=type     觸發一個特殊的設備。合法的類型:devices,subsystem,failed.預設是devices
--action=action  被觸發的事件,預設是change
--subsystem-match=subsystem  觸發匹配子系統的裝置事件。這個選項可以被多次指定,並且支援shell模式匹配。
--attr-match=attribute=value     觸發符合sysfs屬性的裝置事件。如果屬性值和屬性一起指定,屬​​性的值可以使用shell模式來匹配。如果沒有指定值,會重新確認現有屬性。這個選項可以被多次指定。
--attr-nomatch=attribute=value   不要觸發符合屬性的裝置事件。如果可以使用模式匹配。也可以多次指定
--property-match=property=value 匹配屬性吻合的裝置。可以多次指定支援模式符合
--tag-match=property       匹配標籤吻合的裝置。可以多次指定。

--sysname-match=name     符合具有相同的sys裝置名稱。可以多次指定支援模式匹配。

(e)查看udev事件佇列


udevadm settle [options]  查看udev事件佇列,如果所有事件全部處理完就退出。
--timeout=seconds     等待事件佇列空的最大時間。預設是180秒。如果是0則立即退出。
--seq-start=seqnum     只等待到給定的順序號。
--seq-end=seqnum    只等待到給定順序號之前。
--exit-if-exists=file      若檔案存在就退出

--quiet    不輸出任何資訊

(二)應用實例:

    使用任何資訊

(二)應用實例:

    使用SD卡裝置的重新命名、自動掛載、自動卸載。 ######    此功能的簡單應用程式可參考另一部落格《udev 重新命名裝置節點名稱自動掛載、卸載儲存裝置分割區》######    在本文中主要記錄在使用時所遇到的問題以及注意事項。 ###

(三)注意事项:

(1)设备冲突问题:

    在海思平台,对于有些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网卡

(2)多属性匹配问题

    对于一个设备如果要匹配他的多个属性,或者是同一个属性,它在不同的层级中有不同的值,那么这个时候需要使用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"

(3)监控设备事件

    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中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
上一篇:linux vcs是什麼下一篇:linux vcs是什麼