大家好,我是ST。
今天主要和大家聊一聊,sysfs設(shè)備驅(qū)動(dòng)管理。
第一:sysfs設(shè)備驅(qū)動(dòng)管理簡(jiǎn)介
sysfs是非持久性虛擬文件系統(tǒng),它提供系統(tǒng)的全局視圖,并通過(guò)它們的kobiect顯示內(nèi)核對(duì)象的層次結(jié)構(gòu)(拓?fù)?。每個(gè)kobiect顯示為錄和目錄中的文件,目錄代表相關(guān)kobject導(dǎo)出的內(nèi)核變量。這些文件稱為屬性,可以讀取或?qū)懭?。如果任何已注?cè)的kobiect在sysfs中創(chuàng)建目錄,則目錄的創(chuàng)建位置取決于kobiec的父項(xiàng)(它也是kobiect)。這些目錄自然創(chuàng)建為kobject父項(xiàng)的子目錄。這向用戶空間出顯示了內(nèi)部對(duì)象的層次結(jié)構(gòu)。sysfs 中的頂級(jí)目錄表示對(duì)象層次結(jié)構(gòu)的共同祖先,即對(duì)象所屬的子系統(tǒng)。
對(duì)系統(tǒng)上的每個(gè)塊設(shè)備,block 都包含一個(gè)錄,目錄下包含設(shè)備上分區(qū)的子目錄。bus 包含系統(tǒng)上注冊(cè)的總線。dev 以原始方式(無(wú)層次結(jié)構(gòu))包含已注冊(cè)的設(shè)備節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)都是/sys/devices目錄中慎實(shí)設(shè)備的符號(hào)鏈接。devices 給出系統(tǒng)內(nèi)設(shè)備的拓?fù)浣Y(jié)構(gòu)視圖。firmware 顯示系統(tǒng)相關(guān)的低層子系統(tǒng)樹(shù),如ACPI、EFI、 0F (DT) 。fs 列出系統(tǒng)上實(shí)際使用的文件系統(tǒng)。kernel 保存內(nèi)核配置選項(xiàng)和狀態(tài)信息。module是加載的模塊列表。
●kernel_ kobj :對(duì)應(yīng)于/sys/kernel.
●power_ kobj :對(duì)應(yīng)于/sys/power。
●firmware_ kobj :對(duì)應(yīng)于/sys/firmware,導(dǎo)出在drivers/baselirmware.c源文件中。
●hvpervisor_ kobj:對(duì)應(yīng)于/sys/hypervisor,導(dǎo)出在drivers/base hypervisor.c中。
●fs_ kobj :對(duì)應(yīng)于/sys/fs, 導(dǎo)出在fs/namespace.c文件中。
然而,class/、 dev/ 、devices/ 是在啟動(dòng)期間由內(nèi)核源代碼內(nèi)drivers_ base/core.c 中的devices_ init 函數(shù)創(chuàng)建的,block/ 在block/genhd.c中創(chuàng)建,bus/ 在drivers/base/bus.c中被創(chuàng)建為kset.
kobject綠被添加到sysfs (使用 kobject_ _add) 時(shí),其添加位置取決于kobject的父項(xiàng)。如果其父指針已設(shè)置,則它將被添加為父錄內(nèi)的子錄。如果父指針為NULL,則將其添加為kset->kobj內(nèi)的子錄。如果其父和kset字段都未設(shè)置,它將映射到sysfs內(nèi)的根目錄(/sys)。
第二:sysfs設(shè)備驅(qū)動(dòng)管理相關(guān)注冊(cè)接口
Linux系統(tǒng)中一切皆文件。
設(shè)備文件在哪里呢?它在/dev錄下,也在/sys錄下。它們直接有什么區(qū)別呢?
●/dev錄:該目錄下面的文件是真實(shí)的設(shè)備文件,是應(yīng)用層通過(guò)mknod創(chuàng)建的文件,通常系統(tǒng)中是由udev在運(yùn)行時(shí)創(chuàng)建的。我們通常使用open、write、 ioctl 等函數(shù)操作設(shè)備,通常就是操作/dev目錄下面的文件,它會(huì)間接調(diào)用到底層的驅(qū)動(dòng)函數(shù)。
●/sys目錄:這是由內(nèi)核在運(yùn)行時(shí)導(dǎo)出的,目的就是通過(guò)文件系統(tǒng)展示出設(shè)備、 驅(qū)動(dòng)和總線等層次關(guān)系。這也是這章節(jié)的重點(diǎn)。那么先通過(guò)下圖看一下 sysfs文件系統(tǒng)是如何搭建起來(lái)的,圖中左邊是初始化流程,右邊是對(duì)應(yīng)sysfs文件系統(tǒng)的目錄結(jié)構(gòu)。
可以看到sysfs并不單純是設(shè)備驅(qū)動(dòng)相關(guān)的,還包括了內(nèi)核模塊,內(nèi)核參數(shù)以及電源等諸多管理,當(dāng)然這些在某個(gè)角度上也可以視為設(shè)備或者驅(qū)動(dòng)模塊。不過(guò)它們不是我們分析的重點(diǎn),我們著重需要分析的主要是設(shè)備驅(qū)動(dòng)相關(guān)的,這圖只是給了我們心中一個(gè)譜,知道它都有些什么,在哪里初始化的。
這里不準(zhǔn)備直接通過(guò)sysfs文件目錄層次結(jié)構(gòu)進(jìn)行分析sysfs對(duì)設(shè)備驅(qū)動(dòng)的管理。我們從設(shè)備、驅(qū)動(dòng)和總線等的注冊(cè)添加和流程進(jìn)行分析sysfs文件目錄層次構(gòu)造的。它們主要的注冊(cè)函數(shù)分別為device_register、driver_register、bus_register,還有免不了的class_register。
第三:device_register主要功能
通過(guò)上圖的device_register調(diào)用棧,可以看到設(shè)備主要的初始化都是在/sys/devices/***/下面創(chuàng)建一個(gè)自己名字的目錄(例如xxx-device),然后在里面創(chuàng)建自己的屬性文件接口。同時(shí)它會(huì)創(chuàng)建一個(gè)subsystem的鏈接,指向bus或者class,表示它歸屬的類型,掛在bus下面意味著它是由某個(gè)bus管控著,如果掛在class下面,這只是一個(gè)視角問(wèn)題,其實(shí)質(zhì)也是表示它具備某些共同屬性,乃至管理操作屬性上的一致。然后在/sys/bus或者/sys/class下面就沒(méi)有必要?jiǎng)?chuàng)建重復(fù)的東西了,直接創(chuàng)建一個(gè)鏈接指向device,意味著從它們的目錄去看,可以看到bus或者class都管著哪些設(shè)備。經(jīng)過(guò)device_register后,創(chuàng)建的目錄和鏈接關(guān)系如下:
這里的文件及目錄的管理方式起本質(zhì)是數(shù)據(jù)結(jié)構(gòu)的管理思想,目錄可以視為結(jié)構(gòu)體,文件是數(shù)據(jù)結(jié)構(gòu)成員,而鏈接文件是數(shù)據(jù)指針。上圖實(shí)際上就是這幾個(gè)數(shù)據(jù)結(jié)構(gòu)除了自身的初始化外,然后就是建立結(jié)構(gòu)之間的關(guān)聯(lián)關(guān)系。
第四:driver_register都做了些什么?
那么通過(guò)接著看一下driver_register都做了些什么?
driver_register如上圖調(diào)用關(guān)系,可以看到它比device的注冊(cè)做的事情少多了。它主要是在/sys/bus/xxx-bus/drivers目錄下創(chuàng)建自己名字的目錄,然后在里面初始化驅(qū)動(dòng)屬性文件。同時(shí)創(chuàng)建鏈接指向module,表示該驅(qū)動(dòng)是由哪個(gè)內(nèi)核模塊提供功能,同樣module也反向指向驅(qū)動(dòng),表示它提供的是什么樣的驅(qū)動(dòng)能力,當(dāng)然只有驅(qū)動(dòng)模塊才會(huì)有指向驅(qū)動(dòng)的鏈接。經(jīng)過(guò)driver_register后,其構(gòu)成的目錄和鏈接關(guān)系如下:
第五:bus_register都做了些什么?
通過(guò)上圖可以看到,它主要是在/sys/bus目錄下面創(chuàng)建以自己名字命令的bus目錄(這里名字舉例為xxx-bus),然后會(huì)創(chuàng)建好devices和drivers給與它管理的設(shè)備和驅(qū)動(dòng)進(jìn)行注冊(cè),同時(shí)創(chuàng)建驅(qū)動(dòng)的探測(cè)drivers_probe和drivers_autoprobe屬性文件,以提供給用戶觸發(fā)去探測(cè)。當(dāng)然還少不了uevent事件文件的創(chuàng)建,最后還有一些bus自己特有的屬性。注冊(cè)完bus后,將會(huì)生成目錄結(jié)構(gòu)如下:
最后看一下class_register都做了些什么?
??
class_register的行為比較簡(jiǎn)單,僅僅是在/sys/class下面創(chuàng)建一個(gè)自己命名的目錄,主要是提供給設(shè)備注冊(cè)掛入鏈接。掛鏈接的動(dòng)作在device_register里面完成。
總結(jié):通過(guò)以上圖像大概對(duì)sysfs文件系統(tǒng)上的設(shè)備驅(qū)動(dòng)注冊(cè)和大概的關(guān)系邏輯關(guān)系,有了基本的了解。如果通過(guò)tree命令去查看/sys肯定會(huì)發(fā)現(xiàn)/sys/devices目錄下面的PCI、USB等設(shè)備的文件夾層層疊疊,這就涉及到了它們具體內(nèi)部的一個(gè)管理關(guān)系了,這里不再敘述。
審核編輯:湯梓紅
評(píng)論
查看更多