天天看點

linux裝置模型bus,device,driver,linux驅動模型 -- bus,device,device_driver之間的關系

Linux 裝置驅動模型中,按照層次的組織結構,抽象成總線(struct bus_type),裝置(struct device),驅動(struct device_driver)的層次組織形式,這是最原始的抽象結構,在此基礎之上,根據不同類型的總線/裝置/驅動,有形成了更高層次的組織結構,如virtio總線(struct bus_type virtio_bus),virtio裝置(struct virtio_device),virtio驅動(struct virtio_driver)等。

不同的抽象層次構成一顆網狀的樹,linux核心通過驅動模型:kobject,kset來組織樹的結構。

上圖說明了總線通過兩個資料結構:devices_ket和driver_kset來管理注冊在此總線上的所有的裝置和驅動,為了友善周遊,linux增加了klist_devices和klist_drivers用來實作裝置和驅動的周遊。

了解linux驅動模型,最重要的是了解裝置與驅動的比對過程,即在何時,驅動與裝置如何實作比對?

總結起來,裝置的注冊時機為調用device_register(),将devices注冊到總線的devices_kset上,同理,驅動的注冊為調用driver_register将驅動注冊到總線的drivers_kset上。

下圖對照說明了Device和Driver的注冊過程。

linux裝置模型bus,device,driver,linux驅動模型 -- bus,device,device_driver之間的關系

裝置與驅動的比對主要有以下幾個點:

(1)如果總線的match函數非空,調用總線的match函數

(2)如果總線的probe函數非空,調用總線的probe函數,然後會在總線的probe函數中調用驅動的probe函數

(3)如果總線的probe函數為空,則直接調用驅動的probe函數

另外,bus_for_each_drv()是對BUS上所有的Driver都進行__device_attach()操作;同樣的,bus_for_each_dev()是對BUS上所有的Device都進行__driver_attach()操作。

那麼,這些函數的執行時機在哪呢?

隻要有device或device_driver被注冊到總線上,都會執行上面的過程。