linux裝置模型分析之(一):裝置模型核心
linux裝置模型分析之(二):裝置模型的基石
linux裝置模型分析之(三):sysfs
linux裝置模型分析之(四):class
linux裝置模型分析之(五):uevent
uevent是kobject的一部分,用於在kobject狀態發生改變時,例如增加、移除等,通知使用者空間程式。使用者空間程式收到這樣的事件後,會做相應的處理。
該機制通常是用來支援熱拔插裝置的,例如滑鼠插入後,滑鼠相關的驅動軟體會動態建立用於表示該滑鼠的device結構(相應的也包括其中的kobject),並告知使用者空間程式,為該滑鼠動態的建立裝置節點。
uevent的機制是比較簡單的,裝置模型中任何裝置有事件需要上報時,呼叫uevent提供的介面。uevent模組準備好上報事件的格式後,可以通過兩個途徑把事件上報到使用者空間:一種是通過kmod模組,直接呼叫使用者空間的可執行檔案;另一種是通過netlink通訊機制,將事件從核心空間傳遞給使用者空間。
其中,netlink是一種socket,專門用來進行核心空間和使用者空間的通訊;kmod是管理核心模組的工具集,類似busybox,我們熟悉的lsmod,insmod等是指向kmod的鏈結。
kobject事件有:
任何kobject需要上報事件時,都要呼叫它所從屬的kset的uevent_ops操作介面,因此,如果乙個kobject不屬於任何kset時,是不允許傳送事件。enum kobject_action
;
前面有提到過,在利用kmod向使用者空間上報event事件時,會直接執行使用者空間的可執行檔案。而在linux系統,可執行檔案的執行,依賴於環境變數,因此kobj_uevent_env用於組織此次事件上報時的環境變數。struct kset
;struct kset_uevent_ops
;
kobject_uevent函式執行流程如下:struct kobj_uevent_env
;
怎麼指定處理uevent的使用者空間程式?在kobject_uevent函式中,會呼叫到init_uevent_ar**函式:
可見,可在編譯核心時,通過config_uevent_helper_path配置項,靜態指定。#ifdef config_uevent_helper
char uevent_helper[uevent_helper_path_len]
= config_uevent_helper_path;
#endif
static
intinit_uevent_ar**
(struct kobj_uevent_env *env,
const
char
*subsystem)
也可以動態指定如(/sbin/mdev為使用者空間程式):
mdevmdev是構建在linux的sysfs之上的,是乙個使用者程式,它能夠根據系統中的硬體裝置的狀態動態更新裝置檔案。mdev是busybox自帶的乙個簡化版的udev,它比udev占用的記憶體更小,因此更適合嵌入式系統的應用。echo /sbin/mdev > /sys/kernel/uevent_helper
或echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev原理
(1)執行mdev -s命令時,mdev會掃瞄/sys/class這個目錄下所有class,如/sys/class/block。block class下的裝置有dev屬性檔案的話,則以包含該dev屬性檔案的目錄名為裝置檔名,在/dev目錄下建立相應的裝置檔案。
如下圖,block class下有多個裝置:
看看loop0這個裝置有沒dev屬性檔案:
dev屬性檔案儲存著主次裝置號,7為主裝置號,0為次裝置號,如果執行mdev -s命令,那麼在/dev目錄下會生成name為loop0的裝置檔案:
(2)當mdev因uevnet事件被呼叫時,mdev通過由uevent事件傳遞給它的環境變數獲取到:引起該uevent事件的裝置action及該裝置所在的路徑device path(對於上面舉動例子,路徑為sys/class/block/loop0/)。
然後判斷引起該uevent事件的action是什麼。若該action是add,即有新裝置加入到系統中,不管該裝置是虛擬裝置還是實際物理裝置,mdev都會通過device path路徑下的dev屬性檔案獲取到裝置編號,然後以device path路徑最後乙個目錄(即包含該dev屬性檔案的目錄)作為裝置名,在/dev目錄下建立相應的裝置檔案。若該action是remove,即裝置已從系統中移除,則刪除/dev目錄下以device path路徑最後乙個目錄名稱作為檔名的裝置檔案。如果該action既不是add也不是remove,mdev則什麼都不做。
由上面可知,如果我們想在裝置加入到系統中或從系統中移除時,由mdev自動地建立和刪除裝置檔案,那麼就必須做到以下兩點:
在/sys/class 的某class目錄下,建立乙個以裝置名device_name作為名稱的目錄
並且在該device_name目錄下還必須包含乙個dev屬性檔案,該dev屬性檔案以」major:minor\n」形式儲存裝置號。
回想起驅動程式中想自動建立裝置檔案,那麼:
呼叫class_create函式在/sys/class目錄下建立乙個class;
在這個class下呼叫device_create函式建立裝置
如下乙個例子:
Linux裝置模型分析之(二) 裝置模型的基石
linux裝置模型分析之 一 裝置模型核心 linux裝置模型分析之 二 裝置模型的基石 linux裝置模型分析之 三 sysfs linux裝置模型分析之 四 class linux裝置模型分析之 五 uevent linux裝置模型通過sysfs檔案系統將裝置 驅動 匯流排組織成拓撲結構以目錄結...
linux裝置模型之kobject
kobject 結構 在linux核心裡,kobject是組成linux裝置模型的基礎,乙個kobject對應sysfs裡的 乙個目錄。從物件導向的角度來說,kobject可以看作是所有裝置物件的基類,因為c 語言並沒有物件導向的語法,所以一般是把kobject內嵌到其他結構體裡來實現類似的 作用,...
Linux裝置模型分析之基本資料結構
linux隨著硬體裝置的發展及核心版本的演進,裝置模型也變得越來月複雜,早先看了 linux裝置驅動程式 覺得一頭霧水,又看了許多資料和高手的帖子,總算有了一定認識,下面寫出來和linux核心愛好者分享一下。一 底層資料結構 kobject 和kset1 kobject 核心物件 linux2.6 ...