- 青島雅思—專家談雅思考試發(fā)展趨勢(shì)
- 河南2011上半年自考網(wǎng)上報(bào)名入口 點(diǎn)擊進(jìn)入
- 2011年廣東省護(hù)士資格考試報(bào)名現(xiàn)場確認(rèn)時(shí)間
- 2011上半年樂山五通橋區(qū)會(huì)計(jì)從業(yè)考試報(bào)名3月10日-4月1
- 哈爾濱香坊區(qū)2011護(hù)士資格考試報(bào)名現(xiàn)場確認(rèn)時(shí)間
- 2011什邡第一次會(huì)計(jì)從業(yè)資格考試報(bào)名3月1日-4月15日
- 2011什邡第二次會(huì)計(jì)從業(yè)資格考試報(bào)名7月1日-9月16日
- 2011年中山市護(hù)士資格考試報(bào)名工作的通知
- 長安大學(xué)2011考研成績查詢?nèi)肟?點(diǎn)擊進(jìn)入
- 西華大學(xué)2011考研成績查詢?nèi)肟?點(diǎn)擊進(jìn)入
- 中國地質(zhì)大學(xué)(武漢)2011考研成績3月3日查詢
- 中南民族大學(xué)2011考研成績查詢3月4日開始
- 沈陽建筑大學(xué)2011考研成績查詢?nèi)肟?點(diǎn)擊進(jìn)入
- 沈陽工業(yè)大學(xué)2011考研成績查詢?nèi)肟?點(diǎn)擊進(jìn)入
Linux中總線、設(shè)備、驅(qū)動(dòng)是如何關(guān)聯(lián)的?
來源:求學(xué)問校網(wǎng) 發(fā)表時(shí)間:2011-08-31 瀏覽 102 次
作者:武漢華嵌技術(shù)部
對(duì)于Linux驅(qū)動(dòng)開發(fā)來說,設(shè)備模型的理解是根本,顧名思義設(shè)備模型是關(guān)于設(shè)備的模型,設(shè)備的概念就是總線和與其相連的各種設(shè)備了。
電腦城的IT 工作者都會(huì)知道設(shè)備是通過總線連到計(jì)算機(jī)上的,而且還需要對(duì)應(yīng)的驅(qū)動(dòng)才能用,可是總線是如何發(fā)現(xiàn)設(shè)備的,設(shè)備又是如何和驅(qū)動(dòng)對(duì)應(yīng)起來的?
總線、設(shè)備、驅(qū)動(dòng),也就是bus、device、driver,在內(nèi)核里都會(huì)有它們自己專屬的結(jié)構(gòu),在include/linux/device.h 里定義。
首先是總線,bus_type.
struct bus_type {
const char * name;
struct subsystem subsys;//代表自身
struct kset drivers; //當(dāng)前總線的設(shè)備驅(qū)動(dòng)集合
struct kset devices; //所有設(shè)備集合
struct klist klist_devices;
struct klist klist_drivers;
struct bus_attribute * bus_attrs;//總線屬性
struct device_attribute * dev_attrs;//設(shè)備屬性
struct driver_attribute * drv_attrs;
int (*match)(struct device * dev, struct device_driver * drv);//設(shè)備驅(qū)動(dòng)匹配函數(shù)
int (*uevent)(struct device *dev, char **envp,
int num_envp, char *buffer, int buffer_size);//熱拔插事件
int (*probe)(struct device * dev);
int (*remove)(struct device * dev);
void (*shutdown)(struct device * dev);
int (*suspend)(struct device * dev, pm_message_t state);
int (*resume)(struct device * dev);
};
下面是設(shè)備device的定義:
struct device {
struct device * parent; //父設(shè)備,一般一個(gè)bus也對(duì)應(yīng)一個(gè)設(shè)備。
struct kobject kobj;//代表自身
char bus_id[BUS_ID_SIZE];
struct bus_type * bus; /* 所屬的總線 */
struct device_driver *driver; /* 匹配的驅(qū)動(dòng)*/
void *driver_data; /* data private to the driver 指向驅(qū)動(dòng) */
void *platform_data; /* Platform specific data,由驅(qū)動(dòng)定義并使用*/
///更多字段忽略了
};
下面是設(shè)備驅(qū)動(dòng)定義:
struct device_driver {
const char * name;
struct bus_type * bus;//所屬總線
struct completion unloaded;
struct kobject kobj;//代表自身
struct klist klist_devices;//設(shè)備列表
struct klist_node knode_bus;
struct module * owner;
int (*probe) (struct device * dev);
int (*remove) (struct device * dev);
void (*shutdown) (struct device * dev);
int (*suspend) (struct device * dev, pm_message_t state);
int (*resume) (struct device * dev);
};
我們會(huì)發(fā)現(xiàn),structbus_type中有成員structksetdrivers 和structksetdevices,同時(shí)structdevice中有兩個(gè)成員struct bus_type * bus和struct device_driver *driver , structdevice_driver中有兩個(gè)成員structbus_type*bus和structklistklist_devices。structdevice中的bus表示這個(gè)設(shè)備連到哪個(gè)總線上,driver表示這個(gè)設(shè)備的驅(qū)動(dòng)是什么,structdevice_driver中的bus表示這個(gè)驅(qū)動(dòng)屬于哪個(gè)總線,klist_devices表示這個(gè)驅(qū)動(dòng)都支持哪些設(shè)備,因?yàn)檫@里device是復(fù)數(shù),又是list,更因?yàn)橐粋€(gè)驅(qū)動(dòng)可以支持多個(gè)設(shè)備,而一個(gè)設(shè)備只能綁定一個(gè)驅(qū)動(dòng)。當(dāng)然,structbus_type中的drivers和devices分別表示了這個(gè)總線擁有哪些設(shè)備和哪些驅(qū)動(dòng)。
還有上面device 和driver結(jié)構(gòu)里出現(xiàn)的kobject 結(jié)構(gòu)是什么?kobject 和kset 都是Linux 設(shè)備模型中最基本的元素。一般來說應(yīng)該這么理解,整個(gè)Linux 的設(shè)備模型是一個(gè)OO 的體系結(jié)構(gòu),總線、設(shè)備和驅(qū)動(dòng)都是其中鮮活存在的對(duì)象,kobject 是它們的基類,所實(shí)現(xiàn)的只是一些公共的接口,kset 是同種類型kobject 對(duì)象的集合,也可以說是對(duì)象的容器。
那么總線、設(shè)備和驅(qū)動(dòng)之間是如何關(guān)聯(lián)的呢?
先說說總線中的那兩條鏈表是怎么形成的。內(nèi)核要求每次出現(xiàn)一個(gè)設(shè)備就要向總線匯報(bào),或者說注冊(cè),每次出現(xiàn)一個(gè)驅(qū)動(dòng),也要向總線匯報(bào),或者說注冊(cè)。比如系統(tǒng)初始化的時(shí)候,會(huì)掃描連接了哪些設(shè)備,并為每一個(gè)設(shè)備建立起一個(gè)structdevice 的變量,每一次有一個(gè)驅(qū)動(dòng)程序,就要準(zhǔn)備一個(gè)tructdevice_driver 結(jié)構(gòu)的變量。把這些變量統(tǒng)統(tǒng)加入相應(yīng)的鏈表,device 插入devices 鏈表,driver 插入drivers 鏈表。這樣通過總線就能找到每一個(gè)設(shè)備,每一個(gè)驅(qū)動(dòng)。
設(shè)備和驅(qū)動(dòng)又是如何聯(lián)系?
原來是把每一個(gè)要用的設(shè)備在計(jì)算機(jī)啟動(dòng)之前就已經(jīng)插好了,插放在它應(yīng)該在的位置上,然后計(jì)算機(jī)啟動(dòng),然后操作系統(tǒng)開始初始化,總線開始掃描設(shè)備,每找到一個(gè)設(shè)備,就為其申請(qǐng)一個(gè)structdevice 結(jié)構(gòu),并且掛入總線中的devices 鏈表中來,然后每一個(gè)驅(qū)動(dòng)程序開始初始化,開始注冊(cè)其struct device_driver 結(jié)構(gòu),然后它去總線的devices 鏈表中去尋找(遍歷),去尋找每一個(gè)還沒有綁定驅(qū)動(dòng)的設(shè)備,structdevice 中的structdevice_driver 指針仍為空的設(shè)備,然后它會(huì)去觀察這種設(shè)備的特征,看是否是他所支持的設(shè)備,如果是,那么調(diào)用一個(gè)叫做device_bind_driver 的函數(shù),然后他們就結(jié)為了秦晉之好。換句話說,把structdevice 中的structdevice_driverdriver 指向這個(gè)驅(qū)動(dòng),而struct device_driver driver 把struct device 加入他的那structklist klist_devices鏈表中來。就這樣,bus、device 和driver,這三者之間或者說他們中的兩兩之間,就給聯(lián)系上了。知道其中之一,就能找到另外兩個(gè)。
但現(xiàn)在情況變了,出現(xiàn)了一種新的名詞,叫熱插拔。設(shè)備可以在計(jì)算機(jī)啟動(dòng)以后在插入或者拔出計(jì)算機(jī)了。設(shè)備可以在任何時(shí)刻出現(xiàn),而驅(qū)動(dòng)也可以在任何時(shí)刻被加載,所以,出現(xiàn)的情況就是,每當(dāng)一個(gè)structdevice 誕生,它就會(huì)去bus 的drivers鏈表中尋找自己的另一半,反之,每當(dāng)一個(gè)struct device_driver 誕生,它就去bus的devices 鏈表中尋找它的那些設(shè)備。如果找到了合適的,那么OK,和之前那種情況一下,調(diào)device_bind_driver 綁定好。如果找不到,沒有關(guān)系,等待吧!
對(duì)于Linux驅(qū)動(dòng)開發(fā)來說,設(shè)備模型的理解是根本,顧名思義設(shè)備模型是關(guān)于設(shè)備的模型,設(shè)備的概念就是總線和與其相連的各種設(shè)備了。
電腦城的IT 工作者都會(huì)知道設(shè)備是通過總線連到計(jì)算機(jī)上的,而且還需要對(duì)應(yīng)的驅(qū)動(dòng)才能用,可是總線是如何發(fā)現(xiàn)設(shè)備的,設(shè)備又是如何和驅(qū)動(dòng)對(duì)應(yīng)起來的?
總線、設(shè)備、驅(qū)動(dòng),也就是bus、device、driver,在內(nèi)核里都會(huì)有它們自己專屬的結(jié)構(gòu),在include/linux/device.h 里定義。
首先是總線,bus_type.
struct bus_type {
const char * name;
struct subsystem subsys;//代表自身
struct kset drivers; //當(dāng)前總線的設(shè)備驅(qū)動(dòng)集合
struct kset devices; //所有設(shè)備集合
struct klist klist_devices;
struct klist klist_drivers;
struct bus_attribute * bus_attrs;//總線屬性
struct device_attribute * dev_attrs;//設(shè)備屬性
struct driver_attribute * drv_attrs;
int (*match)(struct device * dev, struct device_driver * drv);//設(shè)備驅(qū)動(dòng)匹配函數(shù)
int (*uevent)(struct device *dev, char **envp,
int num_envp, char *buffer, int buffer_size);//熱拔插事件
int (*probe)(struct device * dev);
int (*remove)(struct device * dev);
void (*shutdown)(struct device * dev);
int (*suspend)(struct device * dev, pm_message_t state);
int (*resume)(struct device * dev);
};
下面是設(shè)備device的定義:
struct device {
struct device * parent; //父設(shè)備,一般一個(gè)bus也對(duì)應(yīng)一個(gè)設(shè)備。
struct kobject kobj;//代表自身
char bus_id[BUS_ID_SIZE];
struct bus_type * bus; /* 所屬的總線 */
struct device_driver *driver; /* 匹配的驅(qū)動(dòng)*/
void *driver_data; /* data private to the driver 指向驅(qū)動(dòng) */
void *platform_data; /* Platform specific data,由驅(qū)動(dòng)定義并使用*/
///更多字段忽略了
};
下面是設(shè)備驅(qū)動(dòng)定義:
struct device_driver {
const char * name;
struct bus_type * bus;//所屬總線
struct completion unloaded;
struct kobject kobj;//代表自身
struct klist klist_devices;//設(shè)備列表
struct klist_node knode_bus;
struct module * owner;
int (*probe) (struct device * dev);
int (*remove) (struct device * dev);
void (*shutdown) (struct device * dev);
int (*suspend) (struct device * dev, pm_message_t state);
int (*resume) (struct device * dev);
};
我們會(huì)發(fā)現(xiàn),structbus_type中有成員structksetdrivers 和structksetdevices,同時(shí)structdevice中有兩個(gè)成員struct bus_type * bus和struct device_driver *driver , structdevice_driver中有兩個(gè)成員structbus_type*bus和structklistklist_devices。structdevice中的bus表示這個(gè)設(shè)備連到哪個(gè)總線上,driver表示這個(gè)設(shè)備的驅(qū)動(dòng)是什么,structdevice_driver中的bus表示這個(gè)驅(qū)動(dòng)屬于哪個(gè)總線,klist_devices表示這個(gè)驅(qū)動(dòng)都支持哪些設(shè)備,因?yàn)檫@里device是復(fù)數(shù),又是list,更因?yàn)橐粋€(gè)驅(qū)動(dòng)可以支持多個(gè)設(shè)備,而一個(gè)設(shè)備只能綁定一個(gè)驅(qū)動(dòng)。當(dāng)然,structbus_type中的drivers和devices分別表示了這個(gè)總線擁有哪些設(shè)備和哪些驅(qū)動(dòng)。
還有上面device 和driver結(jié)構(gòu)里出現(xiàn)的kobject 結(jié)構(gòu)是什么?kobject 和kset 都是Linux 設(shè)備模型中最基本的元素。一般來說應(yīng)該這么理解,整個(gè)Linux 的設(shè)備模型是一個(gè)OO 的體系結(jié)構(gòu),總線、設(shè)備和驅(qū)動(dòng)都是其中鮮活存在的對(duì)象,kobject 是它們的基類,所實(shí)現(xiàn)的只是一些公共的接口,kset 是同種類型kobject 對(duì)象的集合,也可以說是對(duì)象的容器。
那么總線、設(shè)備和驅(qū)動(dòng)之間是如何關(guān)聯(lián)的呢?
先說說總線中的那兩條鏈表是怎么形成的。內(nèi)核要求每次出現(xiàn)一個(gè)設(shè)備就要向總線匯報(bào),或者說注冊(cè),每次出現(xiàn)一個(gè)驅(qū)動(dòng),也要向總線匯報(bào),或者說注冊(cè)。比如系統(tǒng)初始化的時(shí)候,會(huì)掃描連接了哪些設(shè)備,并為每一個(gè)設(shè)備建立起一個(gè)structdevice 的變量,每一次有一個(gè)驅(qū)動(dòng)程序,就要準(zhǔn)備一個(gè)tructdevice_driver 結(jié)構(gòu)的變量。把這些變量統(tǒng)統(tǒng)加入相應(yīng)的鏈表,device 插入devices 鏈表,driver 插入drivers 鏈表。這樣通過總線就能找到每一個(gè)設(shè)備,每一個(gè)驅(qū)動(dòng)。
設(shè)備和驅(qū)動(dòng)又是如何聯(lián)系?
原來是把每一個(gè)要用的設(shè)備在計(jì)算機(jī)啟動(dòng)之前就已經(jīng)插好了,插放在它應(yīng)該在的位置上,然后計(jì)算機(jī)啟動(dòng),然后操作系統(tǒng)開始初始化,總線開始掃描設(shè)備,每找到一個(gè)設(shè)備,就為其申請(qǐng)一個(gè)structdevice 結(jié)構(gòu),并且掛入總線中的devices 鏈表中來,然后每一個(gè)驅(qū)動(dòng)程序開始初始化,開始注冊(cè)其struct device_driver 結(jié)構(gòu),然后它去總線的devices 鏈表中去尋找(遍歷),去尋找每一個(gè)還沒有綁定驅(qū)動(dòng)的設(shè)備,structdevice 中的structdevice_driver 指針仍為空的設(shè)備,然后它會(huì)去觀察這種設(shè)備的特征,看是否是他所支持的設(shè)備,如果是,那么調(diào)用一個(gè)叫做device_bind_driver 的函數(shù),然后他們就結(jié)為了秦晉之好。換句話說,把structdevice 中的structdevice_driverdriver 指向這個(gè)驅(qū)動(dòng),而struct device_driver driver 把struct device 加入他的那structklist klist_devices鏈表中來。就這樣,bus、device 和driver,這三者之間或者說他們中的兩兩之間,就給聯(lián)系上了。知道其中之一,就能找到另外兩個(gè)。
但現(xiàn)在情況變了,出現(xiàn)了一種新的名詞,叫熱插拔。設(shè)備可以在計(jì)算機(jī)啟動(dòng)以后在插入或者拔出計(jì)算機(jī)了。設(shè)備可以在任何時(shí)刻出現(xiàn),而驅(qū)動(dòng)也可以在任何時(shí)刻被加載,所以,出現(xiàn)的情況就是,每當(dāng)一個(gè)structdevice 誕生,它就會(huì)去bus 的drivers鏈表中尋找自己的另一半,反之,每當(dāng)一個(gè)struct device_driver 誕生,它就去bus的devices 鏈表中尋找它的那些設(shè)備。如果找到了合適的,那么OK,和之前那種情況一下,調(diào)device_bind_driver 綁定好。如果找不到,沒有關(guān)系,等待吧!
武漢電腦培訓(xùn)培訓(xùn)相關(guān)新聞
武漢電腦培訓(xùn)相關(guān)課程
- 襄陽室內(nèi)設(shè)計(jì)培訓(xùn)學(xué)校
- 襄陽廣告設(shè)計(jì)培訓(xùn)學(xué)校
- 襄陽辦公文秘培訓(xùn)襄陽辦公應(yīng)用培訓(xùn)
- 襄陽園林景觀設(shè)計(jì)培訓(xùn)學(xué)校
- 襄陽建筑cad培訓(xùn)襄陽室內(nèi)cad培訓(xùn)襄陽家俱cad培訓(xùn)
- 襄陽建筑cad培訓(xùn)室內(nèi)cad培訓(xùn)
- 襄陽機(jī)械cad培訓(xùn)
- 襄陽2020年全國計(jì)算機(jī)等級(jí)考試報(bào)名和培訓(xùn)
- 襄陽建筑設(shè)計(jì)培訓(xùn)學(xué)校
- 襄陽3dmax培訓(xùn)襄陽cad培訓(xùn)襄陽vray培訓(xùn)襄陽ps培訓(xùn)
- 襄陽網(wǎng)頁設(shè)計(jì)培訓(xùn)襄陽網(wǎng)站制作培訓(xùn)
- 襄陽影視廣告動(dòng)漫設(shè)計(jì)培訓(xùn)
- 襄陽大眾室內(nèi)設(shè)計(jì)培訓(xùn)高級(jí)學(xué)校
- 襄陽家具Cad培訓(xùn)襄陽室內(nèi)Cad培訓(xùn)
武漢電腦培訓(xùn)相關(guān)機(jī)構(gòu)
武漢最新資訊
- 青島雅思—專家談雅思考試發(fā)展趨勢(shì)
- 河南2011上半年自考網(wǎng)上報(bào)名入口 點(diǎn)…
- 2011年廣東省護(hù)士資格考試報(bào)名現(xiàn)場確…
- 2011上半年樂山五通橋區(qū)會(huì)計(jì)從業(yè)考試…
- 哈爾濱香坊區(qū)2011護(hù)士資格考試報(bào)名現(xiàn)…
- 2011什邡第一次會(huì)計(jì)從業(yè)資格考試報(bào)名…
- 2011什邡第二次會(huì)計(jì)從業(yè)資格考試報(bào)名…
- 2011年中山市護(hù)士資格考試報(bào)名工作的…
- 長安大學(xué)2011考研成績查詢?nèi)肟?點(diǎn)擊…
- 西華大學(xué)2011考研成績查詢?nèi)肟?點(diǎn)擊…
武漢推薦課程導(dǎo)航
雅思 | 口語 | 日語 | 韓語 | 德語 | 四六級(jí) | 商務(wù)英語 | 平面設(shè)計(jì) | 游戲動(dòng)漫 | 影視制作 | 室內(nèi)外設(shè)計(jì) | 動(dòng)畫設(shè)計(jì) | 網(wǎng)頁設(shè)計(jì) | 等級(jí)考試軟件工程 | 美容培訓(xùn) | 手機(jī)維修 | 廚師面點(diǎn) | 會(huì)計(jì)職稱 | 心理咨詢 | 人力資源