日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

Linux那些事儿 之 戏说USB(10)模型,又见模型

發布時間:2023/11/27 生活经验 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux那些事儿 之 戏说USB(10)模型,又见模型 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
上文說usb_init給我們留下了一些岔路口,每條都像是不歸路,讓人不知道從何處開始,也看不到路的盡頭。趁著徘徊彷徨的檔兒,咱們還是先聊一下linux的設備模型。
顧名而思義就知道設備模型是關于設備的模型,對咱們寫驅動的和不寫驅動的人來說,設備的概念就是總線和與其相連的各種設備了。電腦城的IT工作者都會知道設備是通過總線連到計算機上的,而且還需要對應的驅動才能用,可是總線是如何發現設備的,設備又是如何和驅動對應起來的,它們經過怎樣的艱辛才找到命里注定的那個他,它們的關系如何,白頭偕老型的還是朝三暮四型的,這些問題就不是他們關心的了,是咱們需要關心的。經歷過高考千錘百煉的咱們還能夠驚喜的發現,這些疑問的中心思想中心詞匯就是總線、設備和驅動,沒錯,它們都是咱們這里要聊的linux設備模型的名角。
總線、設備、驅動,也就是bus、device、driver,既然是名角,在內核里都會有它們自己專屬的結構,在include/linux/device.h里定義。
struct bus_type {const char		*name;const char		*dev_name;struct device		*dev_root;struct device_attribute	*dev_attrs;	/* use dev_groups instead */const struct attribute_group **bus_groups;const struct attribute_group **dev_groups;const struct attribute_group **drv_groups;int (*match)(struct device *dev, struct device_driver *drv);int (*uevent)(struct device *dev, struct kobj_uevent_env *env);int (*probe)(struct device *dev);int (*remove)(struct device *dev);void (*shutdown)(struct device *dev);int (*online)(struct device *dev);int (*offline)(struct device *dev);int (*suspend)(struct device *dev, pm_message_t state);int (*resume)(struct device *dev);const struct dev_pm_ops *pm;const struct iommu_ops *iommu_ops;struct subsys_private *p;struct lock_class_key lock_key;
};

struct device {struct device		*parent;struct device_private	*p;struct kobject kobj;const char		*init_name; /* initial name of the device */const struct device_type *type;struct mutex		mutex;	/* mutex to synchronize calls to* its driver.*/struct bus_type	*bus;		/* type of bus device is on */struct device_driver *driver;	/* which driver has allocated thisdevice */void		*platform_data;	/* Platform specific data, devicecore doesn't touch it */void		*driver_data;	/* Driver data, set and get withdev_set/get_drvdata */struct dev_pm_info	power;struct dev_pm_domain	*pm_domain;#ifdef CONFIG_PINCTRLstruct dev_pin_info	*pins;
#endif#ifdef CONFIG_NUMAint		numa_node;	/* NUMA node this device is close to */
#endifu64		*dma_mask;	/* dma mask (if dma'able device) */u64		coherent_dma_mask;/* Like dma_mask, but foralloc_coherent mappings asnot all hardware supports64 bit addresses for consistentallocations such descriptors. */unsigned long	dma_pfn_offset;struct device_dma_parameters *dma_parms;struct list_head	dma_pools;	/* dma pools (if dma'ble) */struct dma_coherent_mem	*dma_mem; /* internal for coherent memoverride */
#ifdef CONFIG_DMA_CMAstruct cma *cma_area;		/* contiguous memory area for dmaallocations */
#endif/* arch specific additions */struct dev_archdata	archdata;struct device_node	*of_node; /* associated device tree node */struct acpi_dev_node	acpi_node; /* associated ACPI device node */dev_t			devt;	/* dev_t, creates the sysfs "dev" */u32			id;	/* device instance */spinlock_t		devres_lock;struct list_head	devres_head;struct klist_node	knode_class;struct class		*class;const struct attribute_group **groups;	/* optional groups */void	(*release)(struct device *dev);struct iommu_group	*iommu_group;bool			offline_disabled:1;bool			offline:1;
};

struct device_driver {const char		*name;struct bus_type		*bus;struct module		*owner;const char		*mod_name;	/* used for built-in modules */bool suppress_bind_attrs;	/* disables bind/unbind via sysfs */const struct of_device_id	*of_match_table;const struct acpi_device_id	*acpi_match_table;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);const struct attribute_group **groups;const struct dev_pm_ops *pm;struct driver_private *p;
};

沒有人會監督我節省紙張,所以就都貼出來了,有沒有發現它們的共性是什么?對,都很復雜很長,那是因為還沒有見到更復雜更長的。不妨把它們看成藝術品,linux整個內核都是藝術品,既然是藝術,當然不會讓你那么容易的就看懂了,不然怎么稱大師稱名家。這么想想咱們就會比較的寬慰了,阿Q是魯迅對咱們80后最大的貢獻。

我知道進入了21世紀,最缺的就是耐性,房價股價都讓咱們沒有耐性,內核的代碼也讓人沒有耐性。不過做為最沒有耐性的一代人,因為都被壓扁了,還是要平心凈氣的掃一下上面的結構,我們會發現struct device結構中有兩個成員struct bus_type和struct device_driver,struct device_driver結構中有成員struct bus_type。

憑一個男人的直覺,我們可以知道,struct device中的bus表示這個設備連到哪個總線上,driver表示這個設備的驅動是什么,struct device_driver中的bus表示這個驅動屬于哪個總線。


kobject和kset都是linux設備模型中最基本的元素,總線、設備、驅動是西瓜,kobjcet、klist是種瓜的人。kobject和kset不會在意自己自己的得失,它們存在的意義在于把總線、設備和驅動這樣的對象連接到設備模型上。

一般來說應該這么理解,整個linux的設備模型是一個OO的體系結構,總線、設備和驅動都是其中鮮活存在的對象,kobject是它們的基類,所實現的只是一些公共的接口,kset是同種類型kobject對象的集合,也可以說是對象的容器。只是因為C里不可能會有C++里類的class繼承、組合等的概念,只有通過kobject嵌入到對象結構里來實現。這樣,內核使用kobject將各個對象連接起來組成了一個分層的結構體系,就好像通過馬列主義將我們13億人也連接成了一個分層的社會體系一樣。kobject結構里包含了parent成員,指向了另一個kobject結構,也就是這個分層結構的上一層結點。而kset是通過鏈表來實現的。

那么klist那?其實它就包含了一個鏈表和一個自旋鎖,我們暫且把它看成鏈表也無妨,本來在2.6.11版本里,struct device_driver結構的devices成員就是一個鏈表類型。

還是先說說總線中的那兩條鏈表是怎么形成的吧。復旦人甲說這要求每次出現一個設備就要向總線匯報,或者說注冊,每次出現一個驅動,也要向總線匯報,或者說注冊。比如系統初始化的時候,會掃描連接了哪些設備,并為每一個設備建立起一個struct device的變量,每一次有一個驅動程序,就要準備一個struct device_driver結構的變量。把這些變量統統加入相應的鏈表,device 插入devices 鏈表,driver插入drivers鏈表。這樣通過總線就能找到每一個設備,每一個驅動。然而,假如計算機里只有設備卻沒有對應的驅動,那么設備無法工作。反過來,倘若只有驅動卻沒有設備,驅動也起不了任何作用。

現在,總線上的兩條鏈表已經有了,這個三角關系三個邊已經有了兩個,剩下的那個那?鏈表里的device和driver又是如何聯系那?先有device還是先有driver?偷懶一下,仍然摘引復旦人甲的話吧。很久很久以前,在那激情燃燒的歲月里,先有的是device,每一個要用的device在計算機啟動之前就已經插好了,插放在它應該在的位置上,然后計算機啟動,然后操作系統開始初始化,總線開始掃描設備,每找到一個設備,就為其申請一個struct device結構,并且掛入總線中的devices鏈表中來,然后每一個驅動程序開始初始化,開始注冊其struct device_driver結構,然后它去總線的devices鏈表中去尋找(遍歷),去尋找每一個還沒有綁定driver的設備,即struct device中的struct device_driver指針仍為空的設備,然后它會去觀察這種設備的特征,看是否是他所支持的設備,如果是,那么調用一個叫做device_bind_driver的函數,然后他們就結為了秦晉之好。換句話說,把struct device中的struct device_driver driver指向這個driver,而struct device_driver driver把struct device加入他的那張struct klist klist_devices鏈表中來。就這樣,bus、device和driver,這三者之間或者說他們中的兩兩之間,就給聯系上了。

但現在情況變了,在這紅蓮綻放的日子里,在這櫻花傷逝的日子里,出現了一種新的名詞,叫熱插拔。device可以在計算機啟動以后在插入或者拔出計算機了。因此,很難再說是先有device還是先有driver了。因為都有可能。device可以在任何時刻出現,而driver 也可以在任何時刻被加載,所以,出現的情況就是,每當一個struct device誕生,它就會去bus的drivers鏈表中尋找自己的另一半,反之,每當一個一個struct device_driver誕生,它就去bus的devices鏈表中尋找它的那些設備。如果找到了合適的,那么ok,和之前那種情況一下,調用device_bind_driver綁定好.如果找不到,沒有關系,等待吧,等到曇花再開,等到風景看透,心中相信,這世界上總有一個人是你所等的,只是還沒有遇到而已。

總結

以上是生活随笔為你收集整理的Linux那些事儿 之 戏说USB(10)模型,又见模型的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。