深入分析系統(tǒng)中設(shè)備驅(qū)動管理sysfs文件系統(tǒng)
第一:sysfs設(shè)備驅(qū)動管理簡介
? ? sysfs是非持久性虛擬文件系統(tǒng),它提供系統(tǒng)的全局視圖,并通過它們的kobiect顯示內(nèi)核對象的層次結(jié)構(gòu)(拓?fù)?。每個kobiect顯示為錄和目錄中的文件,目錄代表相關(guān)kobject導(dǎo)出的內(nèi)核變量。這些文件稱為屬性,可以讀取或?qū)懭?。如果任何已注冊的kobiect在sysfs中創(chuàng)建目錄,則目錄的創(chuàng)建位置取決于kobiec的父項(它也是kobiect)。這些目錄自然創(chuàng)建為kobject父項的子目錄。這向用戶空間出顯示了內(nèi)部對象的層次結(jié)構(gòu)。sysfs 中的頂級目錄表示對象層次結(jié)構(gòu)的共同祖先,即對象所屬的子系統(tǒng)。
? ? 對系統(tǒng)上的每個塊設(shè)備,block 都包含一個錄,目錄下包含設(shè)備上分區(qū)的子目錄。bus 包含系統(tǒng)上注冊的總線。dev 以原始方式(無層次結(jié)構(gòu))包含已注冊的設(shè)備節(jié)點,每個節(jié)點都是/sys/devices目錄中慎實設(shè)備的符號鏈接。devices 給出系統(tǒng)內(nèi)設(shè)備的拓?fù)浣Y(jié)構(gòu)視圖。firmware 顯示系統(tǒng)相關(guān)的低層子系統(tǒng)樹,如ACPI、EFI、 0F (DT) 。fs 列出系統(tǒng)上實際使用的文件系統(tǒng)。kernel 保存內(nèi)核配置選項和狀態(tài)信息。module是加載的模塊列表。
●kernel_ kobj :對應(yīng)于/sys/kernel.
●power_ kobj :對應(yīng)于/sys/power。
●firmware_ kobj :對應(yīng)于/sys/firmware,導(dǎo)出在drivers/baselirmware.c源文件中。
●hvpervisor_ kobj:對應(yīng)于/sys/hypervisor,導(dǎo)出在drivers/base hypervisor.c中。
●fs_ kobj :對應(yīng)于/sys/fs, 導(dǎo)出在fs/namespace.c文件中。
? ? 然而,class/、 dev/ 、devices/ 是在啟動期間由內(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) 時,其添加位置取決于kobject的父項。如果其父指針已設(shè)置,則它將被添加為父錄內(nèi)的子錄。如果父指針為NULL,則將其添加為kset->kobj內(nèi)的子錄。如果其父和kset字段都未設(shè)置,它將映射到sysfs內(nèi)的根目錄(/sys)。
第二:sysfs設(shè)備驅(qū)動管理相關(guān)注冊接口
Linux系統(tǒng)中一切皆文件。
設(shè)備文件在哪里呢?它在/dev錄下,也在/sys錄下。它們直接有什么區(qū)別呢?
●/dev錄:該目錄下面的文件是真實的設(shè)備文件,是應(yīng)用層通過mknod創(chuàng)建的文件,通常系統(tǒng)中是由udev在運行時創(chuàng)建的。我們通常使用open、write、 ioctl 等函數(shù)操作設(shè)備,通常就是操作/dev目錄下面的文件,它會間接調(diào)用到底層的驅(qū)動函數(shù)。
●/sys目錄:這是由內(nèi)核在運行時導(dǎo)出的,目的就是通過文件系統(tǒng)展示出設(shè)備、 驅(qū)動和總線等層次關(guān)系。這也是這章節(jié)的重點。那么先通過下圖看一下 sysfs文件系統(tǒng)是如何搭建起來的,圖中左邊是初始化流程,右邊是對應(yīng)sysfs文件系統(tǒng)的目錄結(jié)構(gòu)。

? ? 可以看到sysfs并不單純是設(shè)備驅(qū)動相關(guān)的,還包括了內(nèi)核模塊,內(nèi)核參數(shù)以及電源等諸多管理,當(dāng)然這些在某個角度上也可以視為設(shè)備或者驅(qū)動模塊。不過它們不是我們分析的重點,我們著重需要分析的主要是設(shè)備驅(qū)動相關(guān)的,這圖只是給了我們心中一個譜,知道它都有些什么,在哪里初始化的。
這里不準(zhǔn)備直接通過sysfs文件目錄層次結(jié)構(gòu)進行分析sysfs對設(shè)備驅(qū)動的管理。我們從設(shè)備、驅(qū)動和總線等的注冊添加和流程進行分析sysfs文件目錄層次構(gòu)造的。它們主要的注冊函數(shù)分別為device_register、driver_register、bus_register,還有免不了的class_register。
【文章福利】小編推薦自己的Linux內(nèi)核技術(shù)交流群:【749907784】整理了一些個人覺得比較好的學(xué)習(xí)書籍、視頻資料共享在群文件里面,有需要的可以自行添加哦?。。。ê曨l教程、電子書、實戰(zhàn)項目及代碼)? ? ?


第三:device_register主要功能

??通過上圖的device_register調(diào)用棧,可以看到設(shè)備主要的初始化都是在/sys/devices/***/下面創(chuàng)建一個自己名字的目錄(例如xxx-device),然后在里面創(chuàng)建自己的屬性文件接口。同時它會創(chuàng)建一個subsystem的鏈接,指向bus或者class,表示它歸屬的類型,掛在bus下面意味著它是由某個bus管控著,如果掛在class下面,這只是一個視角問題,其實質(zhì)也是表示它具備某些共同屬性,乃至管理操作屬性上的一致。然后在/sys/bus或者/sys/class下面就沒有必要創(chuàng)建重復(fù)的東西了,直接創(chuàng)建一個鏈接指向device,意味著從它們的目錄去看,可以看到bus或者class都管著哪些設(shè)備。經(jīng)過device_register后,創(chuàng)建的目錄和鏈接關(guān)系如下:

? ??這里的文件及目錄的管理方式起本質(zhì)是數(shù)據(jù)結(jié)構(gòu)的管理思想,目錄可以視為結(jié)構(gòu)體,文件是數(shù)據(jù)結(jié)構(gòu)成員,而鏈接文件是數(shù)據(jù)指針。上圖實際上就是這幾個數(shù)據(jù)結(jié)構(gòu)除了自身的初始化外,然后就是建立結(jié)構(gòu)之間的關(guān)聯(lián)關(guān)系。
第四:driver_register都做了些什么?
? ? 那么通過接著看一下driver_register都做了些什么?

? ??driver_register如上圖調(diào)用關(guān)系,可以看到它比device的注冊做的事情少多了。它主要是在/sys/bus/xxx-bus/drivers目錄下創(chuàng)建自己名字的目錄,然后在里面初始化驅(qū)動屬性文件。同時創(chuàng)建鏈接指向module,表示該驅(qū)動是由哪個內(nèi)核模塊提供功能,同樣module也反向指向驅(qū)動,表示它提供的是什么樣的驅(qū)動能力,當(dāng)然只有驅(qū)動模塊才會有指向驅(qū)動的鏈接。經(jīng)過driver_register后,其構(gòu)成的目錄和鏈接關(guān)系如下:

第五:bus_register都做了些什么?

通過上圖可以看到,它主要是在/sys/bus目錄下面創(chuàng)建以自己名字命令的bus目錄(這里名字舉例為xxx-bus),然后會創(chuàng)建好devices和drivers給與它管理的設(shè)備和驅(qū)動進行注冊,同時創(chuàng)建驅(qū)動的探測drivers_probe和drivers_autoprobe屬性文件,以提供給用戶觸發(fā)去探測。當(dāng)然還少不了uevent事件文件的創(chuàng)建,最后還有一些bus自己特有的屬性。注冊完bus后,將會生成目錄結(jié)構(gòu)如下:

最后看一下class_register都做了些什么?
??

??
? class_register的行為比較簡單,僅僅是在/sys/class下面創(chuàng)建一個自己命名的目錄,主要是提供給設(shè)備注冊掛入鏈接。掛鏈接的動作在device_register里面完成。
總結(jié):通過以上圖像大概對sysfs文件系統(tǒng)上的設(shè)備驅(qū)動注冊和大概的關(guān)系邏輯關(guān)系,有了基本的了解。如果通過tree命令去查看/sys肯定會發(fā)現(xiàn)/sys/devices目錄下面的PCI、USB等設(shè)備的文件夾層層疊疊,這就涉及到了它們具體內(nèi)部的一個管理關(guān)系了,這里不再敘述。
原文作者:嵌入式開發(fā)愛好者
