溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

linux6.5 udev指的是什么

發(fā)布時間:2023-04-10 11:32:37 來源:億速云 閱讀:108 作者:iii 欄目:建站服務器

本篇內容介紹了“l(fā)inux6.5 udev指的是什么”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

linux 6.5 udev是Linux內核的設備管理器;它主要的功能是管理“/dev”目錄底下的設備節(jié)點,它同時也是用來接替devfs(設備文件系統(tǒng))及hotplug(熱拔插)的功能;在傳統(tǒng)的Linux系統(tǒng)中,“/dev”目錄下的設備節(jié)點為一系列靜態(tài)存在的文件,而“udev”則動態(tài)提供了在系統(tǒng)中實際存在的設備節(jié)點。

linux 6.5 udev是什么?

udev udevadm介紹及l(fā)inux設備重命名和自動掛載應用實例分析

(一)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. At 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目錄底下的設備節(jié)點。它同時也是用來接替devfs(設備文件系統(tǒng))及hotplug(熱拔插)的功能,這意味著它要在添加/刪除硬件時處理/dev目錄以及所有用戶空間的行為,包括加載firmware時。

(1)udev概要:

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

  • udev支持設備的固定命名,而并不依賴于設備插入系統(tǒng)的順序。默認的udev設置提供了存儲設備的固定命名。可以使用其vid(vendor)、pid(device)、設備名稱(model)等屬性或其父設備的對應屬性來確認某一設備。

  • udev完全在用戶空間執(zhí)行,而不是像devfs在內核空間一樣執(zhí)行。結果就是udev將命名策略從內核中移走,并可以在節(jié)點創(chuàng)建前用任意程序在設備屬性中為設備命名。

(2)udev運行方式:

udev是一個通用的內核設備管理器。它以守護進程的方式運行于Linux系統(tǒng),并監(jiān)聽在新設備初始化或設備從系統(tǒng)中移除時,內核(通過netlink socket)所發(fā)出的uevent。
    系統(tǒng)提供了一套規(guī)則用于匹配可發(fā)現(xiàn)的設備事件和屬性的導出值。匹配規(guī)則可能命名并創(chuàng)建設備節(jié)點,并運行配置程序來對設備進行設置。udev規(guī)則可以匹配像內核子系統(tǒng)、內核設備名稱、設備的物理等屬性,或設備序列號的屬性。規(guī)則也可以請求外部程序提供信息來命名設備,或指定一個永遠一樣的自定義名稱來命名設備,而不管設備什么時候被系統(tǒng)發(fā)現(xiàn).

(3)udev系統(tǒng)架構:

udev系統(tǒng)可以分為三個部分:

  • libudev函數(shù)庫,可以用來獲取設備的信息。

  • udevd守護進程,處于用戶空間,用于管理虛擬/dev

  • 管理命令udevadm,用來診斷出錯情況。

系統(tǒng)獲取內核通過netlink socket發(fā)出的信息。早期的版本使用hotplug,并在/etc/hotplug.d/default添加一個鏈接到自身來達到目的。

(二)udevadm 命令介紹

在Linux man page 中它是這么描述的。udevadm - udev management tool 。也就是說udevadm命令是管理udev的一個工具。實際我們如果要實現(xiàn)設備的重命名或是設備的自動掛載,我們也是使用udevadm來查看和跟蹤udev的信息。
    udevadm可以用來監(jiān)視和控制udev運行時的行為,請求內核事件,管理事件隊列,以及提供簡單的調試機制。

(1)udevadm主命令:

  • info      查詢sysfs或者udev的數(shù)據(jù)庫

  • trigger 從內核請求events

  • settle   查看udev事件隊列,如果所有的events已處理則退出

  • control  修改udev后臺的內部狀態(tài)信息

  • monitor 監(jiān)控內核的uevents

  • hwdb    處理硬件數(shù)據(jù)庫索引

  • 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的根節(jié)點

--query=type     從數(shù)據(jù)庫中查詢指定類型的設備。需要--path和--name來指定設備。合法的查詢文件是:設備名,鏈接,路徑,屬性
--path=devpath      設備的路徑
--name=file       設備節(jié)點或者鏈接
--attribute-walk    打印指定設備的所有sysfs記錄的屬性,以用來udev規(guī)則匹配特殊的設備。該選項打印鏈上的所有設備信息,最大可能到sys目錄。
--device-id-of-file=file 打印主/從設備號
--export-db       輸出udev數(shù)據(jù)庫中的內容

(b)監(jiān)控設備事件:

udevadm monitor [options] 監(jiān)聽內核事件和udev發(fā)送的events事件。打印事件發(fā)出的設備??梢酝ㄟ^比較內核或者udev事件的時間戳來分析事件時序。

udevadm monitor --property   輸出事件的屬性
udevadm monitor --kernel --property --subsystem-match=usb    過濾監(jiān)聽符合條件的時間

--kernel  輸出內核事件
--udev  輸出udev規(guī)則執(zhí)行時的udev事件
--property  輸出事件的屬性
--subsystem-match=string  通過子系統(tǒng)或者設備類型過濾事件。只有匹配了子系統(tǒng)值的udev設備事件通過。
--tag-match=string  通過屬性過濾事件,只有匹配了標簽的udev事件通過。

(c)模擬一個udev事件

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

(d)接收內核發(fā)送來的設備事件

udevadm trigger [options]  接收內核發(fā)送來的設備事件。主要用于重放coldplug事件信息
(內核在啟動時已經檢測到了系統(tǒng)的硬件設備,并把硬件設備信息通過sysfs內核虛擬文件系統(tǒng)導出。udev掃描sysfs文件系統(tǒng),根據(jù)硬件設備信息生成熱插拔(hotplug)事件,udev再讀取這些事件,生成對應的硬件設備文件。由于沒有實際的硬件插拔動作,所以這一過程被稱為coldplug。)
--verbose     輸出將要被觸發(fā)的設備列表。
--dry-run      不真的觸發(fā)事件
--type=type     觸發(fā)一個特殊的設備。合法的類型:devices,subsystem,failed.默認是devices
--action=action  被觸發(fā)的事件,默認是change
--subsystem-match=subsystem  觸發(fā)匹配子系統(tǒng)的設備事件。這個選項可以被多次指定,并且支持shell模式匹配。
--attr-match=attribute=value     觸發(fā)匹配sysfs屬性的設備事件。如果屬性值和屬性一起指定,屬性的值可以使用shell模式匹配。如果沒有指定值,會重新確認現(xiàn)有屬性。這個選項可以被多次指定。
--attr-nomatch=attribute=value   不要觸發(fā)匹配屬性的設備事件。如果可以使用模式匹配。也可以多次指定
--property-match=property=value 匹配屬性吻合的設備??梢远啻沃付ㄖС帜J狡ヅ?br/> --tag-match=property       匹配標簽吻合的設備??梢远啻沃付ā?br/> --sysname-match=name     匹配sys設備名相同的設備??梢远啻沃付ㄖС帜J狡ヅ洹?/p>

(e)查看udev事件隊列

udevadm settle [options]  查看udev事件隊列,如果所有事件全部處理完就退出。
--timeout=seconds     等待事件隊列空的最大時間。默認是180秒。如果是0則立即退出。
--seq-start=seqnum     只等待到給定的順序號。
--seq-end=seqnum    只等待到給定順序號之前。
--exit-if-exists=file      如果文件存在就退出
--quiet    不輸出任何信息

(二)應用實例:

使用udev實現(xiàn)USB,SD卡設備的重命名、自動掛載、自動卸載。

該功能的簡單應用可以參考另外一博客《udev 重命名設備節(jié)點名 自動掛載、卸載存儲設備分區(qū)》

在本文中主要記錄在使用時遇到的問題以及注意事項。

(三)注意事項:

(1)設備沖突問題:

在海思平臺,對于有些SD卡或是USB自動掛載有些時候會出現(xiàn)沖突的問題,問題現(xiàn)象就是自動掛載的時候有時候有時候U盤和SD卡自動掛載相互干擾。主要原因點是因為海思的HI35XX的很多設備不具備SDIO總線,所以如果要使用SD的設備,一般都是將SD卡通過讀卡器轉換為USB總線信號。對于對于這類問題,可以通過SD卡的讀卡器ID來區(qū)分是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)監(jiān)控設備事件

udev的一些匹配規(guī)則有些時候比較的莫名其妙,我也沒有找到哪里有比較詳細的說明,網上的介紹都它過于簡單,實際應用的時候還是很多的問題,比如針對上面介紹的設備,如果要寫一條卸載設備的命令,可以使用下面語句:

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"

命令功能可以實現(xiàn),但是這樣會出現(xiàn)于設備沖突的情況,在拔出該設備的時候,會把KERNELS=="*:0:0:1" 的其他設備也卸載掉。

在這個時候,我們可以使用 devadm monitor --property  去監(jiān)控設備拔出的時候它有哪些事件,有哪些屬性可以被捕捉到并且與其他的設備屬性不同以便區(qū)分不同的設備。下面是截取到的一部分數(shù)據(jù):

[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 值的一個組合,可以使用它來區(qū)分不同的設備。最終可以正常卸載設備的命令如下:

ACTION=="remove",SUBSYSTEM=="usb",ENV{PRODUCT}=="5e3/716/9727",RUN+="/bin/umount -l /opt/usb_sd1_1"

“l(fā)inux6.5 udev指的是什么”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經查實,將立刻刪除涉嫌侵權內容。

AI