使用 udev 进行动态内核设备管理(转自suse文档)
第?12?章使用?udev?進行動態內核設備管理?
目錄
12.1.?/dev?目錄12.2. 內核?uevents?和?udev12.3. 驅動程序、內核模塊和設備12.4. 引導和啟動設備設置12.5. 監視正在運行的?udev?守護程序12.6. 使用?udev?規則影響內核設備事件處理12.7. 永久設備命名12.8.?udev?使用的文件12.9. 更多信息內核幾乎可以添加或刪除運行系統中的任何設備。設備狀態的更改(無論插入還是刪除設備)需要傳播給用戶空間。插入或者識別設備后需要進行配置。某個設備已識別狀態的任何更改都需要通知給此設備的用戶。udev?可提供所需的基礎結構來動態維護?/dev?目錄中的設備節點文件和符號鏈接。udev?規則提供了將外部工具插入內核設備事件處理的方式。這使您能夠自定義?udev?設備處理,例如通過添加特定腳本來作為內核設備處理的一部分執行,或者請求并導入額外數據以在設備處理期間評估。
12.1.?/dev?目錄?
/dev?目錄中的設備節點提供對相應的內核設備的訪問。使用?udev?時,/dev?目錄反映內核的當前狀態。每個內核設備都有相應的設備文件。如果設備從系統斷開,則刪除此設備節點。
/dev?目錄的內容保存在臨時文件系統中,所有文件都是在每個系統啟動時提供的。手動創建或修改的文件在重引導時是有意不保存的。無論相應內核設備的狀態如何都出現在?/dev?目錄中的靜態文件和目錄,可以放置在?/lib/udev/devices?目錄中。系統啟動時,此目錄的內容復制到?/dev?目錄,它們與?/lib/udev/devices?中的文件具有相同的所有權和許可權限。
12.2.?內核?uevents?和?udev?
必需的設備信息由?sysfs?文件系統導出。對于內核檢測到并已初始化的設備,將創建一個帶有該設備名稱的目錄。它包含帶有特定于設備屬性的屬性文件。
每次添加或刪除設備時,內核都會發送 uevent 來向?udev?通知更改。一旦啟動,udev?守護程序便會讀取和分析?/etc/udev/rules.d/*.rules?文件中提供的所有規則,并將它們保留在內存中。如果更改、添加或刪除了規則文件,則守護程序可以使用命令?udevadm control reload_rules?重新裝載所有規則在內存中的表示形式。運行?/etc/init.d/boot.udev reload?時也會執行此操作。有關?udev?規則及其語法的更多細節,請參見第?12.6?節 “使用?udev?規則影響內核設備事件處理”。
每個接收到的事件都根據所提供的規則集進行匹配。這些規則可以增加或更改事件環境鍵、為要創建的設備節點請求特定名稱、添加指向該節點的符號鏈接或者添加設備節點創建后運行的程序。從內核 netlink 套接字接收驅動程序核心?uevent。
12.3.?驅動程序、內核模塊和設備?
設備的內核總線驅動程序探測。對于每個檢測到的設備,內核都會在驅動程序核心將 uevent 發送到?udev?守護程序時創建內部設備結構。總線設備通過特殊格式的 ID 來標識自己,這可以識別設備的類型。通常,這些 ID 由供應商和產品 ID 以及其他特定于子系統的值組成。每個總線都有自己對于這些 ID 的方案,稱為?MODALIAS。內核獲取設備信息,由此組成一個?MODALIAS?ID 字符串,并將該字符串與事件一起發送。對于 USB 鼠標,如下所示:
MODALIAS=usb:v046DpC03Ed2000dc00dsc00dp00ic03isc01ip02每個設備驅動程序都帶有它可以處理的設備的已知別名列表。這個列表包含在內核模塊文件中。程序 depmod 讀取 ID 列表并在內核的?/lib/modules?目錄中為所有當前可用的模塊創建文件?modules.alias。使用這種基礎結構,模塊的裝載就如為每個帶有?MODALIAS?關鍵字的事件調用?modprobe?一樣簡單。如果調用?modprobe $MODALIAS,它將組成該設備的設備別名與模塊提供的別名相匹配。如果找到匹配的項,則裝載該模塊。所有這些操作均由?udev?自動觸發。
12.4.?引導和啟動設備設置?
在?udev?守護程序運行之前的引導進程中發生的所有設備事件都會丟失,因為處理這些事件的基礎結構保存在 root 文件系統中,并且此時不可用。為了彌補此損失,內核提供了一個?uevent?文件,該文件位于 sysfs 文件系統每個設備的設備目錄中。通過將?add?寫入到該文件,內核將再次發送引導時丟失的相同事件。/sys?觸發器中所有?uevent?文件的簡單循環將再次觸發所有事件來創建設備節點并執行設備設置。
例如,在引導期間出現的 USB 鼠標可能不會由早期引導邏輯初始化,因為驅動程序在那時不可用。此設備發現的事件丟失并且不能為該設備查找內核模塊。不用手動搜索可能連接的設備,udev?會在 root 文件系統可用后直接從內核請求所有設備事件,以便 USB 鼠標設備的事件可以再次運行。現在它在裝入的 root 文件系統上找到內核模塊,因此可以初始化 USB 鼠標。
在用戶空間,設備冷插入序列和運行時期間發現的設備之間沒有明顯的區別。在這兩種情況下,使用相同的規則來匹配并且運行相同的配置程序。
12.5.?監視正在運行的?udev?守護程序?
程序?udevadm monitor?可以用于將驅動程序核心事件和 udev 事件處理的計時可視化。
UEVENT[1185238505.276660] add /devices/pci0000:00/0000:00:1d.2/usb3/3-1 (usb) UDEV [1185238505.279198] add /devices/pci0000:00/0000:00:1d.2/usb3/3-1 (usb) UEVENT[1185238505.279527] add /devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0 (usb) UDEV [1185238505.285573] add /devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0 (usb) UEVENT[1185238505.298878] add /devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input10 (input) UDEV [1185238505.305026] add /devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input10 (input) UEVENT[1185238505.305442] add /devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input10/mouse2 (input) UEVENT[1185238505.306440] add /devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input10/event4 (input) UDEV [1185238505.325384] add /devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input10/event4 (input) UDEV [1185238505.342257] add /devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input10/mouse2 (input)UEVENT?行顯示內核已經通過 netlink 發送的事件。UDEV?行顯示已經完成的 udev 事件處理程序。計時以微秒為單位顯示。UEVENT?和?UDEV?之間的時間是 udev 用于處理此事件或者 udev 守護程序延遲執行從而同步此事件與相關以及已運行的事件的時間。例如,硬盤分區的事件總是等待主磁盤設備事件完成,因為分區事件可能依賴于主磁盤事件從硬件查詢的數據。
udevadm monitor --env?顯示完整的事件環境:
ACTION=add DEVPATH=/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input10 SUBSYSTEM=input SEQNUM=1181 NAME="Logitech USB-PS/2 Optical Mouse" PHYS="usb-0000:00:1d.2-1/input0" UNIQ="" EV=7 KEY=70000 0 0 0 0 REL=103 MODALIAS=input:b0003v046DpC03Ee0110-e0,1,2,k110,111,112,r0,1,8,amlsfwudev 也將消息發送給 syslog。用于控制將哪些消息發送到系統日志的默認系統日志優先級在?udev?配置文件?/etc/udev/udev.conf?中指定。可以使用?udevadm control log_priority=level/number?更改正在運行的守護程序的日志優先權。
12.6.?使用?udev?規則影響內核設備事件處理?
udev?規則可以與內核添加到事件本身的屬性或者內核導出到?sysfs?的任何信息匹配。規則還可以從外部程序請求其他信息。根據提供的規則匹配每個事件。所有規則都位于?/etc/udev/rules.d?目錄下。
規則文件中的每一行至少包含一個關鍵字值對。有兩種類型的關鍵字,匹配關鍵字和指派關鍵字。如果所有匹配關鍵字與它們的值匹配,則應用此規則并將指派關鍵字指派給特定的值。匹配規則可以指定設備節點的名稱、添加指向該節點的符號鏈接或者運行作為事件處理一部分的特定程序。如果找不到匹配的規則,則使用默認設備節點名來創建設備節點。udev?手冊頁中描述了有關規則語法和提供用來與數據匹配或導入數據的關鍵字的詳細信息。以下示例規則提供了?udev?規則語法的基本介紹。這些示例規則全部取自?/etc/udev/rules.d/50-udev-default.rules?下的?udev?默認規則集。
例?12.1.?示例?udev?規則?
# console KERNEL=="console", MODE="0600", OPTIONS="last_rule"# serial devices KERNEL=="ttyUSB*", ATTRS{product}=="[Pp]alm*Handheld*", SYMLINK+="pilot"# printer SUBSYSTEM=="usb", KERNEL=="lp*", NAME="usb/%k", SYMLINK+="usb%k", GROUP="lp"# kernel firmware loader SUBSYSTEM=="firmware", ACTION=="add", RUN+="firmware.sh"console?規則由三個鍵構成:一個匹配鍵 (KERNEL) 和兩個賦值鍵(MODE、OPTIONS)。KERNEL?匹配規則搜索設備列表以查找類型為?console?的所有項。只有完全匹配才有效,才能觸發執行此規則。在這種情況下,MODE?關鍵字為設備節點指派特殊權限,僅為此設備的擁有者指派讀寫權限。OPTIONS?關鍵字將該規則標記為此類型的所有設備最后采用的規則。匹配此特殊設備類型的任何后續規則都不產生任何影響。
50-udev-default.rules?中不再提供?serial devices?規則,但該規則仍然值得考慮。該規則由兩個匹配關鍵字(KERNEL?和?ATTRS)和一個賦值關鍵字 (SYMLINK) 構成。KERNEL?關鍵字搜索類型為?ttyUSB?的所有設備。該關鍵字使用?*?通配符匹配這些設備中的幾個。第二個匹配關鍵字?ATTRS?檢查任何?ttyUSB?設備的?sysfs?中的?product屬性文件是否包含特定字符串。賦值關鍵字 (SYMLINK) 將符號鏈接添加至該設備的?/dev/pilot?下。此關鍵字中使用的運算符 (+=) 告知 udev 進一步執行此操作,即使前面或后面的規則添加其他符號鏈接。由于此規則包含兩個匹配關鍵字,因此僅當兩個條件都滿足時,才應用。
printer?規則處理 USB 打印機,其中包含兩個匹配關鍵字(SUBSYSTEM?和?KERNEL),并且必須同時應用這兩個關鍵字,才能應用整個規則。三個賦值鍵處理該設備類型的命名 (NAME)、符號設備鏈接 (SYMLINK) 的創建,以及此設備類型的組成員資格 (GROUP)。在?KERNEL?關鍵字中使用通配符?*?將使其匹配若干?lp?打印機設備。NAME?和?SYMLINK?關鍵字中都使用了替換項,以便按內部設備名稱擴展這些字符串。例如,指向第一個?lp?USB 打印機的符號鏈接為?/dev/usblp0。
kernel firmware loader?規則用于使 udev 在運行時期間通過外部助手腳本裝載其他固件。SUBSYSTEM?匹配關鍵字搜索?firmware?子系統。ACTION?關鍵字檢查是否添加了屬于?firmware?子系統的任何設備。RUN+=?關鍵字觸發執行?firmware.sh?腳本,以便找到應裝載的固件。
所有規則具有一些共同的特征:
-
每個規則由一個或多個以逗號分隔的關鍵字值對構成。
-
關鍵字的運算由運算符確定。udev 規則支持多個不同的運算符。
-
每個給定值必須用引號引起來。
-
規則文件的每一行代表一個規則。如果一個規則超過一行,請使用?\?合并不同行,就像在殼層語法中一樣。
-
udev?規則支持與?*、??和?[]?模式匹配的外殼式模式。
-
udev 規則支持替換。
12.6.1.?在?udev?規則中使用運算符?
創建可以從若干不同運算符選擇的關鍵字,具體取決于希望創建的關鍵字類型。匹配關鍵字通常僅用于查找匹配或明顯不匹配搜索值的值。匹配關鍵字包含以下運算符之一:
==比較等于性。如果關鍵字包含搜索模式,則匹配該模式的所有結果均有效。
比較不等于性。如果關鍵字包含搜索模式,則匹配該模式的所有結果均有效。
賦值關鍵字可以使用下面的任何運算符:
=為關鍵字指派值。如果關鍵字以前由一列值構成,關鍵字將重置,并且僅指派一個值。
為包含一列項的關鍵字添加一個值。
指派最終值。不允許后面的規則進行任何后續更改。
12.6.2.?在?udev?規則中使用替換項?
udev 規則支持使用占位符和替換項。請按照在其他任何腳本中的相同方式使用。在?udev?規則中可使用以下替換項:
%r、$root設備目錄?/dev(默認)。
DEVPATH?的值。
KERNEL?的值或內部設備名稱。
設備號。
設備文件的臨時名稱。
設備的主編號。
設備的次編號。
sysfs?屬性的值(由?attribute?指定)。
環境變量的值(由?variable?指定)。
PROGRAM?的輸出。
%?字符。
$?字符。
12.6.3.?使用?udev?匹配關鍵字?
匹配關鍵字描述應用?udev?規則之前必須滿足的條件。以下匹配關鍵字可用:
ACTION事件操作的名稱,如?add?或?remove(添加或刪除設備時)。
事件設備的設備路徑,如?DEVPATH=/bus/pci/drivers/ipw3945,用于搜索與 ipw3945 驅動程序有關的所有事件。
事件設備的內部(內核)名稱。
事件設備的子系統,如?SUBSYSTEM=usb(用于與 USB 設備有關的所有事件)。
事件設備的 sysfs 屬性。例如,要匹配?vendor?屬性文件名中包含的字符串,可以使用?ATTR{vendor}=="On[sS]tream"。
讓?udev?向上搜索設備路徑以查找匹配的設備名稱。
讓?udev?向上搜索設備路徑以查找匹配的設備子系統名稱。
讓?udev?向上搜索設備路徑以查找匹配的設備驅動程序名稱。
讓?udev?向上搜索設備路徑以查找具有匹配的?sysfs?屬性值的設備。
環境變量的值,如?ENV{ID_BUS}="ieee1394,用于搜索與該 FireWire 總線 ID 有關的所有事件。
讓?udev?執行外部程序。程序必須返回退出碼零,才能成功。程序的輸出(打印到 stdout)可用于?RESULT關鍵字。
匹配上次?PROGRAM?調用的輸出字符串。在與?PROGRAM?關鍵字相同的規則中包含該關鍵字,或在后面的一個中。
12.6.4.?使用?udev?指派關鍵字?
與上述匹配鍵相比,賦值鍵未描述必須滿足的條件。它們將值、名稱和操作指派給由?udev?維護的設備節點。
NAME將創建的設備節點的名稱。在一個規則設置節點名稱之后,將對該節點忽略帶有?NAME?關鍵字的其他所有規則。
與要創建的節點有關的符號鏈接名稱。多個匹配的規則可添加要使用設備節點創建的符號鏈接。也可以通過使用空格字符分隔符號鏈接名稱,在一個規則中為一個節點指定多個符號鏈接。
新設備節點的權限。此處指定的值重寫已編譯的任何值。
指定要寫入事件設備的?sysfs?屬性的值。如果使用?==?運算符,也將使用該關鍵字匹配 sysfs 屬性的值。
告知?udev?將變量導出到環境。如果使用?==?運算符,也將使用該關鍵字匹配環境變量。
告知?udev?向程序列表添加要為該設備執行的程序。請記住,將此程序限制于很短的任務,以免妨礙此設備的后續事件。
添加?GOTO?可跳至的標簽。
告知?udev?跳過一些規則,繼續執行具有按?GOTO?關鍵字引用的標簽的規則。
將變量裝載入外部程序輸出之類的事件環境中。udev 導入不同類型的若干變量。如果未指定任何類型,udev?將嘗試根據文件許可權限的可執行位來自行確定類型。
-
program?告知 udev 執行外部程序并導入其輸出。
-
file?告知 udev 導入文本文件。
-
parent?告知 udev 從父設備導入儲存的關鍵字。
告知?udev?等待要為某個設備創建的指定?sysfs?文件。例如,WAIT_FOR_SYSFS="ioerr_cnt"?通知?udev?等待?ioerr_cnt?文件創建完成。
OPTION?關鍵字可能有若干值:
-
last_rule?告知 udev 忽略后面的所有規則。
-
ignore_device?告知 udev 完全忽略此事件。
-
ignore_remove?告知 udev 忽略后面針對設備的所有刪除事件。
-
all_partitions?告知 udev 為塊設備上的所有可用分區創建設備節點。
12.7.?永久設備命名?
動態設備目錄和?udev?規則基礎結構可以為所有磁盤設備提供固定名稱,而不考慮它們的識別順序或設備使用的連接。內核創建的每個相應的塊設備由工具根據有關特定總線、驅動器類型或者文件系統的特殊知識進行檢查。除了動態內核提供的設備節點名,udev?還維護各種指向該設備的永久符號鏈接:
/dev/disk |-- by-id | |-- scsi-SATA_HTS726060M9AT00_MRH453M4HWHG7B -> ../../sda | |-- scsi-SATA_HTS726060M9AT00_MRH453M4HWHG7B-part1 -> ../../sda1 | |-- scsi-SATA_HTS726060M9AT00_MRH453M4HWHG7B-part6 -> ../../sda6 | |-- scsi-SATA_HTS726060M9AT00_MRH453M4HWHG7B-part7 -> ../../sda7 | |-- usb-Generic_STORAGE_DEVICE_02773 -> ../../sdd | `-- usb-Generic_STORAGE_DEVICE_02773-part1 -> ../../sdd1 |-- by-label | |-- Photos -> ../../sdd1 | |-- SUSE10 -> ../../sda7 | `-- devel -> ../../sda6 |-- by-path | |-- pci-0000:00:1f.2-scsi-0:0:0:0 -> ../../sda | |-- pci-0000:00:1f.2-scsi-0:0:0:0-part1 -> ../../sda1 | |-- pci-0000:00:1f.2-scsi-0:0:0:0-part6 -> ../../sda6 | |-- pci-0000:00:1f.2-scsi-0:0:0:0-part7 -> ../../sda7 | |-- pci-0000:00:1f.2-scsi-1:0:0:0 -> ../../sr0 | |-- usb-02773:0:0:2 -> ../../sdd | |-- usb-02773:0:0:2-part1 -> ../../sdd1 `-- by-uuid|-- 159a47a4-e6e6-40be-a757-a629991479ae -> ../../sda7|-- 3e999973-00c9-4917-9442-b7633bd95b9e -> ../../sda6`-- 4210-8F8C -> ../../sdd112.8.?udev?使用的文件?
/sys/*Linux 內核提供的虛擬文件系統,用于導出所有當前已知設備。此信息由?udev?用于在?/dev?中創建設備節點
動態創建的設備節點和引導時從?/lib/udev/devices/*?復制的靜態內容
以下文件和目錄包含?udev?基礎結構的關鍵元素:
/etc/udev/udev.conf主?udev?配置文件。
udev 事件匹配規則.
靜態?/dev?內容。
從?udev?規則調用的幫助程序。
12.9.?更多信息?
有關?udev?基礎結構的更多信息,請參見以下手冊頁:
udev有關?udev、關鍵字、規則和其他重要配置問題的常規信息。
udevadm?可用于控制?udev?的運行時行為、請求內核事件、管理事件隊列,以及提供簡單的調試機制。
有關?udev?事件管理守護程序的信息。
轉載于:https://www.cnblogs.com/erhu-67786482/p/11204966.html
總結
以上是生活随笔為你收集整理的使用 udev 进行动态内核设备管理(转自suse文档)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: WebCast《实战ASP.NET AJ
- 下一篇: HihoCoder - 1175 拓扑排