udev是什么udev 是Linux kernel 2.6系列的設備管理器。它主要的功能是管理/dev目錄底下的設備節點。它同時也是用來接替devfs及hotplug的功能,這意味著它要在添加/刪除硬件時處理/dev目錄以及所有用戶空間的行為,包括加載firmware時。 udev系統由三個部分組成: libudev函數庫,可以用來獲取設備的信息,/usr/include/libudev.h。 udevd守護進程,處于用戶空間,用于管理虛擬/dev 管理命令udevadm,用來診斷出錯情況,/usr/bin/udevadm。 udev運行方式udev是一個通用的內核設備管理器。它以守護進程的方式運行于Linux系統,并監聽在新設備初始化或設備從系統中移除時,內核(通過netlinksocket)所發出的uevent。 系統提供了一套規則用于匹配可發現的設備事件和屬性的導出值。匹配規則可能命名并創建設備節點,并運行配置程序來對設備進行設置。udev規則可以匹配像內核子系統、內核設備名稱、設備的物理等屬性,或設備序列號的屬性。規則也可以請求外部程序提供信息來命名設備,或指定一個永遠一樣的自定義名稱來命名設備,而不管設備什么時候被系統發現。下一部分介紹怎么通過編寫udev規則文件來管理udev設備 Udev工作流程 udev規則文件編寫主要的udev配置文件是/etc/udev/udev.conf。這個文件通常很短,可能只是包含幾行#開頭的注釋,然后有如下選項: udev_root=“/dev/” udev_rules=“/etc/udev/rules.d/” udev_log=“err“ 其中udev_rules非常重要,表示udev規則存儲的目錄,這個目錄存儲的是以.rules結束的文件。每一個文件處理一系列規則來幫助udev分配名字給設備文件以保證能被內核識別。/etc/udev/rules.d下面可能有好幾個udev規則文件,這些文件一部分是udev包安裝的,另外一部分則是可能是別的硬件或者軟件包生成的。 下面介紹udev規則文件的語法。
udev鍵/值對操作符
udev常用的匹配賦值鍵
libudev說明前面大致了解了udev相關的功能和原理,下面將描述如何通過libudev來實現相關功能。 libudev提供了在本地系統上檢測、枚舉設備的各種API函數。 Libudev使用過程如下 (參考: http://blog.csdn.net/coroutines/article/details/38067805) 1. 初始化 首先調用udev_new,創建一個udev library context。udev library context采用引用記數機制,創建的context默認引用記數為1,使用udev_ref和udev_unref增加或減少引用記數,如果引用記數為0,則釋放內部資源。 2. 枚舉設備 使用udev_enumrate_new創建一個枚舉器,用于掃描系統已接設備。使用udev_enumrate_ref和udev_enumrate_unref增加或減少引用記數。 使用udev_enumrate_add_match/nomatch_xxx系列函數增加枚舉的過濾器,過濾關鍵字以字符表示,如"block"設備。 使用udev_enumrate_scan_xxx系列函數掃描/sys目錄下,所有與過濾器匹配的設備。掃描完成后的數據結構是一個鏈表,使用udev_enumerate_get_list_entry獲取鏈表的首個結點,使用udev_list_entry_foreach遍歷整個鏈表。 3. 監控設備插拔 udev的設備插拔基于netlink實現。 使用udev_monitor_new_from_netlink創建一個新的monitor,函數的第二個參數是事件源的名稱,可選"kernel"或"udev"。基于"kernel"的事件通知要早于"udev",但相關的設備結點未必創建完成,所以一般應用的設計要基于"udev"進行監控。 使用udev_monitor_filter_add_match_subsystem_devtype增加一個基于設備類型的udev事件過濾器,例如: "block"設備。 使用udev_monitor_enable_receiving啟動監控過程。監控可以使用udev_monitor_get_fd獲取一個文件描述符,基于返回的fd可以執行poll操作,簡化程序設計。 插拔事件到達后,可以使用udev_monitor_receive_device獲取產生事件的設備映射。調用udev_device_get_action可以獲得一個字符串:"add"或者"remove",以及"change", "online", "offline"等,但后三個未知什么情況下會產生。 4、獲取設備信息 使用udev_list_entry_get_name可以得到一個設備結點的sys路徑,基于這個路徑使用udev_device_new_from_syspath可以創建一個udev設備的映射,用于獲取設備屬性。獲取設備屬性使用udev_device_get_properties_list_entry,返回一個存儲了設備所有屬性信息的鏈表,使用udev_list_entry_foreach遍歷鏈表,使用udev_list_entry_get_name和udev_list_entry_get_value獲取屬性的名稱和值。
liudev識別移動設備首先得知道什么是usb設備的VID和PID。 據USB規范的規定,所有的USB設備都有供應商ID(VID)和產品識別碼(PID),主機通過不同的VID和PID來區別不同的設備,VID和PID都是兩個字節長,其中,供應商ID(VID)由供應商向USB執行論壇申請,每個供應商的VID是唯一的,PID由供應商自行決定,理論上來說,不同的產品、相同產品的不同型號、相同型號的不同設計的產品最好采用不同的PID,以便區別相同廠家的不同設備。 上面提到,分別調用udev_new,udev_monitor_new_from_netlink, udev_monitor_filter_add_match_subsystem_devtype,dev_monitor_enable_receiving,dev_monitor_get_fd,udev_monitor_receive_device函數來監控插入的設備。如下圖所示 然后通過udev_device_get_sysattr_value(dev,"idVendor")判斷VID是否是該設備的VID,通過udev_device_get_sysattr_value(dev,"idProduct")來判斷PID是否是該設備的PID,如果都符合,那么就能識別出這個設備,然后進行相應的操作。 |
|