Linux裝置模型(中)之上層容器

2021-08-25 20:12:07 字數 4089 閱讀 2168

linux裝置模型是由匯流排(bus_type),裝置(device),驅動(device_driver)這三個資料結構來描述的。在裝置模型中,所有的裝置都通過匯流排來連線。即使有些裝置沒有連線到一根物理上的匯流排,linux為其設定了乙個內部的,虛擬的platform匯流排,來維持匯流排,驅動,裝置的關係。匯流排是處理器與乙個或者多個裝置之間的通道。比如乙個usb控制器通常是乙個pci裝置,裝置模型展示了匯流排和他們所控制的裝置之間的連線。

一般來說可以這麼理解,整個的裝置模型是乙個oo的體系結構,匯流排,裝置,驅動都是其中鮮活存在的物件,kobject是他們的基類,所實現的只是一些公共的介面,kset是同種型別的kobject物件的集合,也可以說是物件的容器。只是因為c語言裡不可能會有c++語言裡類的class繼承等概念,只有通過kobject嵌入到物件結構中來實現。這樣,核心使用kobject將各個物件連線起來組成乙個分層的體系結構。kobject結構中包含了parent成員,指向了另乙個kobject結構,也就是這個分層結構的上一層結點。而kset是通過鍊錶來實現的。

kobject是linux在2.6中新引進的統一的裝置管理模型,目的是對linux的2.6系統所有的裝置進行統一的管理。kobject是組成裝置模型的基本結構。kobject是驅動程式模型中的乙個核心資料結構,與sysfs檔案系統自然的繫結在一起:——每個kobject對應sysfs檔案系統中的乙個目錄。kobject往往被嵌入到裝置驅動程式模型中的元件中,如匯流排,裝置和驅動程式的描述符。kobject的作用是,為所屬「容器」提供

.引用計數器

.維持容器的層次列表或組

.為容器的屬性提供一種使用者態檢視的檢視

kset是同型別kobject結構的乙個集合體,通過kset資料結構可將kobjects組成一棵層次樹。

struct bus_type ; struct bus_type_private ; struct bus_attribute ;

subsys描述該匯流排的子系統,subsys是乙個kset結構,他連線到乙個全域性變數kset bus_subsys中。這樣,每一根匯流排系統都會通過bus_subsys結構連線起來。kset *devices_kset是指向該匯流排所有裝置的集合的指標,kset *drivers_kset是指向該匯流排所有驅動的集合的指標。該匯流排上的裝置和驅動分別用乙個鍊錶連線在一起,分別是klist_devices,klist_drivers。每次都用kset *drivers_kset,kset *devices_kset遍歷所有裝置/驅動很麻煩,用klist比較直接方便。

需要注意的是,匯流排也是裝置,也必須按裝置註冊。這裡的parent是指該裝置所屬的父裝置,struct kobject kobj;表示該裝置並把它連線到結構體系中的kobject。請注意,作為乙個通用準則,device->kobj->parent與&device->parent->kobj是相同的。bus_id是在匯流排上唯一標識該裝置的字串。struct bus_type *bus;標識了該裝置連線在何種型別的匯流排上。struct device_driver *driver;管理該裝置的驅動。void (*release)(struct device *dev);當指向裝置的最後乙個引用被刪除時,核心呼叫該方法。它將從內嵌的kobject的release方法中呼叫。device_private中的knode_parent,knode_driver,knode_bus分別是掛入parent,驅動,匯流排鍊錶中的指標。

struct device_driver ; struct driver_private ; struct driver_attribute ;

name指向驅動的名字,上邊的device中也有乙個名為bus_id的字元陣列。檢視一下,struct bus_type中有乙個match,函式,這個是幹什麼用的呢。裝置有了驅動才可以工作,只有驅動沒有裝置也是不行,驅動和裝置需要關聯上,這就需要這個match函式。驅動和裝置是通過name來管理的,所以在match函式中要比較device的bus_id和driver中的name是否相等。如果相等,就說明驅動和裝置互相找到了,這時device_driver中的probe函式被呼叫。我下邊的例子中是這樣實現的:

static ssize_t show_driver_author(struct device_driver *driver, char *buf)

下面是乙個測試程式:

bus:

#include #include #include #include #include static char *author = "liwanpeng"; static ssize_t show_bus_author(struct bus_type *bus, char *buf) void my_bus_release(struct device *dev) static int virtual_bus_match(struct device *dev, struct device_driver *drv) struct bus_type virtual_bus = ; struct device my_bus = ; export_symbol(my_bus); export_symbol(virtual_bus); static bus_attr(author, s_irugo, show_bus_author, null); static int __init bus_init(void) static void __exit bus_exit(void) module_init(bus_init); module_exit(bus_exit); module_license("gpl");

device:

#include #include #include #include char *author = "liwanpeng"; extern struct bus_type virtual_bus; extern struct device my_bus; static ssize_t show_device_author(struct device *dev, struct device_attribute *attr, char *buf) void virtual_device_release(struct device *dev) struct device virtual_device =; static device_attr(author, s_irugo, show_device_author, null); static int __init device_init(void) static void __exit device_exit(void) module_init(device_init); module_exit(device_exit); module_author("liwanpeng"); module_license("gpl");

driver:

#include #include #include #include #include extern struct bus_type virtual_bus; char *author = "liwanpeng"; static ssize_t show_driver_author(struct device_driver *driver, char *buf) int my_driver_remove(struct device *dev) int my_driver_probe(struct device *dev) struct device_driver virtual_driver = ; static driver_attr(author, s_irugo, show_driver_author, null); static int __init my_driver_init(void) static void __exit my_driver_exit(void) module_init(my_driver_init); module_exit(my_driver_exit); module_license("gpl"); module_author("liwanpeng");

makefile:

ifneq ($(kernelrelease),) obj-m:= driver.o bus.o device.o else kerneldir ?= /lib/modules/$(shell uname -r)/build pwd := $(shell pwd) modules: $(make) -c $(kerneldir) m=$(pwd) modules clear: rm -rf *.o endif

參考:《linux裝置驅動程式(第三版)》

《linux那些事兒之我是usb》

Linux 裝置模型(中)之上層容器

基本概念 匯流排 linux裝置模型是由匯流排 bus type 裝置 device 驅動 device driver 這三個資料結構來描述的。匯流排是處理器和乙個或多個裝置之間的通道。匯流排可以相互插入。裝置模型展示了匯流排和它們所控制的裝置之間的實際連線。bus type 匯流排 linux 裝...

Linux裝置模型

linux裝置驅動模型 我們在寫最簡單的裝置驅動程式的時候,我們將所有的硬體資訊都儲存在了驅動 中,這樣有乙個非常明顯的不足 會導致驅動程式的通用性極差,一旦硬體平台或硬體連線有鎖改變,就一定要修改驅動 為了解決這個問題,linux在2.6版本之後,新增了 匯流排 裝置 驅動 的linux裝置模型,...

linux裝置模型

linux核心的整體架構 linux裝置模型 linux裝置模型 1 基本概念 linux裝置模型 2 kobject linux裝置模型 3 uevent linux裝置模型 4 sysfs linux裝置模型 5 device和device driver linux裝置模型 6 bus linu...