linux 驅動 device,driver ,bus 關係

來源:互聯網
上載者:User

對於Linux驅動開發來說,裝置模型的理解是根本,顧名思義裝置模型是關於裝置的模型,裝置的概念就是匯流排和與其相連的各種裝置了。
裝置是通過匯流排連到電腦上的,需要對應的驅動才能用,可是匯流排是如何發現裝置的,裝置又是如何和驅動對應起來的?
匯流排、裝置、驅動,也就是bus、device、driver,在核心裡都會有它們自己專屬的結構,在include/linux/device.h 裡定義。
首先是匯流排,bus_type.
struct bus_type {
const char   * name;
struct subsystem subsys;//代表自身
struct kset   drivers;   //當前匯流排的裝置驅動**
struct kset   devices; //所有裝置**
struct klist   klist_devices;
struct klist   klist_drivers;
struct bus_attribute * bus_attrs;//匯流排屬性
struct device_attribute * dev_attrs;//裝置屬性
struct driver_attribute * drv_attrs;
int   (*match)(struct device * dev, struct device_driver * drv);//裝置驅動匹配函數
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);
};
下面是裝置device的定義:
struct device {
struct device   * parent; //父裝置,一般一個bus也對應一個裝置。
struct kobject kobj;//代表自身
char bus_id[BUS_ID_SIZE];
struct bus_type * bus;   /* 所屬的匯流排 */
struct device_driver *driver; /* 匹配的驅動*/
void   *driver_data; /* data private to the driver 指向驅動 */
void   *platform_data; /* Platform specific data,由驅動定義並使用*/
///更多欄位忽略了
};
下面是裝置驅動定義:
struct device_driver {
const char   * name;
struct bus_type   * bus;//所屬匯流排
struct completion unloaded;
struct kobject   kobj;//代表自身
struct klist   klist_devices;//裝置列表
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);
};

我們會發現,structbus_type中有成員structksetdrivers 和structksetdevices,同時structdevice中有兩個成員struct bus_type * bus和struct device_driver *driver , structdevice_driver中有兩個成員structbus_type*bus和structklistklist_devices。structdevice中的bus表示這個裝置連到哪個匯流排上,driver表示這個裝置的驅動是什麼,structdevice_driver中的bus表示這個驅動屬於哪個匯流排,klist_devices表示這個驅動都支援哪些裝置,因為這裡device是複數,又是list,更因為一個驅動可以支援多個裝置,而一個裝置只能綁定一個驅動。當然,structbus_type中的drivers和devices分別表示了這個匯流排擁有哪些裝置和哪些驅動。
還有上面device 和driver結構裡出現的kobject 結構是什嗎?kobject 和kset 都是Linux 裝置模型中最基本的元素。一般來說應該這麼理解,整個Linux 的裝置模型是一個OO 的體繫結構,匯流排、裝置和驅動都是其中鮮活存在的對象,kobject 是它們的基類,所實現的只是一些公用的介面,kset 是同種類型kobject 對象的**,也可以說是對象的容器。
那麼匯流排、裝置和驅動之間是如何關聯的呢?
先說說匯流排中的那兩條鏈表是怎麼形成的。核心要求每次出現一個裝置就要向匯流排彙報,或者說註冊,每次出現一個驅動,也要向匯流排彙報,或者說註冊。比如系統初始化的時候,會掃描串連了哪些裝置,並為每一個裝置建立起一個structdevice 的變數,每一次有一個驅動程式,就要準備一個tructdevice_driver 結構的變數。把這些變數統統加入相應的鏈表,device 插入devices 鏈表,driver 插入drivers 鏈表。這樣通過匯流排就能找到每一個裝置,每一個驅動。
裝置和驅動又是如何聯絡?
原來是把每一個要用的裝置在電腦啟動之前就已經插好了,插放在它應該在的位置上,然後電腦啟動,然後作業系統開始初始化,匯流排開始掃描裝置,每找到一個裝置,就為其申請一個structdevice 結構,並且掛入匯流排中的devices 鏈表中來,然後每一個驅動程式開始初始化,開始註冊其struct device_driver 結構,然後它去匯流排的devices 鏈表中去尋找(遍曆),去尋找每一個還沒有綁定驅動的裝置,structdevice 中的structdevice_driver 指標仍為空白的裝置,然後它會去觀察這種裝置的特徵,看是否是他所支援的裝置,如果是,那麼調用一個叫做device_bind_driver
的函數,然後他們就結為了秦晉之好。換句話說,把structdevice 中的structdevice_driverdriver 指向這個驅動,而struct device_driver driver 把struct device 加入他的那structklist klist_devices鏈表中來。就這樣,bus、device 和driver,這三者之間或者說他們中的兩兩之間,就給聯絡上了。知道其中之一,就能找到另外兩個

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.