Linux内核--usb子系统的分析
drivers/usb/core/usb.c
subsys_init(usb_init);
module_exit(usb_exit);
我们 看到一个subsys_initcall,它也是一个宏,我们可以把它理解为module_init,只不过这部分代码比较核心,开发者们把它看做一个子系统,而不仅仅是一个模块。usbcore这个模块它代表的不是某一个设备,而是所有usb设备赖以生存的模块,Linux中,像这样一个类别的设备驱动被鬼节为一个子系统。比如PCI子系统、SCSI子系统,基本上,drivers/目录西面的每一个目录就算为一个子系统,因为他们代表了一类设备。
subsys_initcall(usb_init)的意思就是告诉我们usb_init是usb子系统真正的初始化函数,而usb_exit()将是整个usb子系统的结束时的清理函数。
我们需要从usb_init函数开始分析:
static int __init usb_init(void)
__init标记:它对于内核来说就是一种暗示,表明这个函数仅仅在初始化期间使用,在模块被装载之后,它占用的资源就会释放掉,用作别用。__init的定义在include/linux/init.h中
#define __init__section(.init.text) __cold notrace
__attribute__、__section__等等都是GNUC的扩展,GNUC作为能够编译内核的唯一编译器。通常编译器将函数放在.text段,变量放在.data或.bss段,使用section属性,可以让编译器将函数或变量放在指定的段中。__init的定义便表示将它修饰的代码放在.init.text段中。连接器可以把相同段的代码或数据安排在一起,比如__init修饰的所有代码都被放在.init.text段中,初始化结束后就可以释放这部分内存。
设备模型:
总线、设备、驱动:(bus、device、driver)定义在include/linux/device.h
struct bus_type {
const char *name;
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, struct kobj_uevent_env *env);
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); struct dev_pm_ops *pm; struct bus_type_private *p;
};
struct device_driver {
const char *name;
struct bus_type *bus; struct module *owner;
const char *mod_name; /* used for built-in modules */ 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);
struct attribute_group **groups; struct dev_pm_ops *pm; struct driver_private *p;
};
struct device {
struct device *parent; struct device_private *p; struct kobject kobj;
const char *init_name; /* initial name of the device */
struct device_type *type; struct semaphore sem; /* semaphore to synchronize calls to
* its driver.
*/ struct bus_type *bus; /* type of bus device is on */
struct device_driver *driver; /* which driver has allocated this
device */
void *driver_data; /* data private to the driver */
void *platform_data; /* Platform specific data, device
core doesn't touch it */
struct dev_pm_info power; #ifdef CONFIG_NUMA
int numa_node; /* NUMA node this device is close to */
#endif
u64 *dma_mask; /* dma mask (if dma'able device) */
u64 coherent_dma_mask;/* Like dma_mask, but for
alloc_coherent mappings as
not all hardware supports
64 bit addresses for consistent
allocations such descriptors. */ 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 mem
override */
/* arch specific additions */
struct dev_archdata archdata; dev_t devt; /* dev_t, creates the sysfs "dev" */ spinlock_t devres_lock;
struct list_head devres_head; struct klist_node knode_class;
struct class *class;
struct attribute_group **groups; /* optional groups */ void (*release)(struct device *dev);
};
struct device中的bus表示这个设备连到那个总线上,driver表示这个设备的驱动是什么,struct device_driver中的bus表示这个驱动属于那个总线,klist_devices表示这个驱动都支持哪些设备,因为这里device是复数,又是list,更因为一个驱动可以支持多个设备,而一个设备只能绑定一个驱动。当然struct bus_type中的drivers和devices分别表示了这个总线拥有哪些设备和哪些驱动。
kobjece和kset是Linux设备模型中最基本的元素,存在的意义是把总线、设备和驱动这样的对象连接到设备模型上。
整个linux的设备模型是一个OO的体系结构,总线、设备和驱动都是其对象,kobject是它们的基类,所实现的知识一些公共的接口,kset是同种类型kobject对象的集合,也可以说是对象的容器。因为在c里不可能有c++里的class继承、组合等概念,只有通过kobject嵌入到对象结构里来实现。这样,内核使用kobject将各个对象连接起来组成一个分层的结构体系。kobject结构里包含了parent成员,指向了另外一个kobject结构,也就是这个分层结构的上一层结点。而kset是通过链表来实现的,struct bus_type结构中的成员drivers和devices表示了一条总线拥有两条链表,一条是设备链表,一条是驱动链表。我们知道了总线对应的数据结构,就可以找到这条总线关联了多少设备,又有哪些驱动来支持这类设备。
Linux内核--usb子系统的分析的更多相关文章
- 浅谈 Linux 内核无线子系统
浅谈 Linux 内核无线子系统 本文目录 1. 全局概览 2. 模块间接口 3. 数据路径与管理路径 4. 数据包是如何被发送? 5. 谈谈管理路径 6. 数据包又是如何被接收? 7. 总结一下 L ...
- Linux 内核无线子系统
Linux 内核无线子系统 浅谈 Linux 内核无线子系统 Table of Contents 1. 全局概览 2. 模块间接口 3. 数据路径与管理路径 4. 数据包是如何被发送? 5. 谈谈管理 ...
- (转)浅谈 Linux 内核无线子系统
前言 Linux 内核是如何实现无线网络接口呢?数据包是通过怎样的方式被发送和接收呢? 刚开始工作接触 Linux 无线网络时,我曾迷失在浩瀚的基础代码中,寻找具有介绍性的材料来回答如上面提到的那些高 ...
- Linux内核--网络栈实现分析(十一)--驱动程序层(下)
本文分析基于Linux Kernel 1.2.13 原创作品,转载请标明http://blog.csdn.net/yming0221/article/details/7555870 更多请查看专栏,地 ...
- Linux内核--网络栈实现分析(七)--数据包的传递过程(下)
本文分析基于Linux Kernel 1.2.13 原创作品,转载请标明http://blog.csdn.net/yming0221/article/details/7545855 更多请查看专栏,地 ...
- linux内核SPI总线驱动分析(一)(转)
linux内核SPI总线驱动分析(一)(转) 下面有两个大的模块: 一个是SPI总线驱动的分析 (研究了具体实现的过程) 另一个是SPI总线驱动的编写(不用研究具体的实现过程) ...
- Linux内核--网络栈实现分析(二)--数据包的传递过程--转
转载地址http://blog.csdn.net/yming0221/article/details/7492423 作者:闫明 本文分析基于Linux Kernel 1.2.13 注:标题中的”(上 ...
- Linux内核态抢占机制分析(转)
Linux内核态抢占机制分析 http://blog.sina.com.cn/s/blog_502c8cc401012pxj.html 摘 要]本文首先介绍非抢占式内核(Non-Preemptive ...
- linux内核中链表代码分析---list.h头文件分析(一)【转】
转自:http://blog.chinaunix.net/uid-30254565-id-5637596.html linux内核中链表代码分析---list.h头文件分析(一) 16年2月27日17 ...
随机推荐
- Delphi中实现MDI子窗体(转)
Delphi中实现MDI子窗体 用MDI实现浏览子窗口,具有窗口管理功能,同屏观看多个网页的内容 ① 多文档窗体(MDI) MDI窗体是一种具有主子结构的窗体体系,微软的Word便是其中的一 ...
- WebGoat学习——跨站脚本攻击(Cross‐Site Scripting (XSS))
跨站脚本攻击(Cross‐Site Scripting (XSS)) XSS(Cross Site Script)跨站脚本攻击.是指攻击者向被攻击Web 页面里插入恶意html代码,当用户浏览该页之时 ...
- [转载]我读过最好的Epoll模型讲解
转载来自:http://blog.csdn.net/mango_song/article/details/42643971 首先我们来定义流的概念,一个流可以是文件,socket,pipe等等可以进行 ...
- 在Mac OS X 10.9上安装 Thrift 0.9.1
Thrift 0.9.1 官方文档中对于Mac OS X上的安装描述适合 10.8,但不适用于10.9. Homebrew macport 默认都不能在 10.9上安装Thrift 0.9.1成功 ...
- Oracle 游标使用(转)
这个文档几乎包含了oracle游标使用的方方面面,全部通过了测试 ; ; dbms_output.put_line(sql) loop dbms_output.put_line( ; ; ; r_te ...
- InternetOpenA
[ilink32 Error] Error: Unresolved external 'InternetOpenA' referenced from ..\WIN32\DEBUG\NATIVEXML ...
- C#UDP(接收和发送源码)源码完整
C#UDP(接收和发送源码)源码完整 最近做了一个UDP的服务接收和发送的东西.希望能对初学的朋友一点帮助. 源码如下: 一.逻辑--UdpServer.cs using System;using S ...
- C++11无限制的unions
[C++11无限制的unions] 在标准 C++ 中,并非任意的类型都能做为 union 的成员.比方说,带有 non-trivial 构造函数的类型就不能是 union 的成员.在新的标准里,移除 ...
- stm32F4各个库文件的作用分析
system_stm32f4xx.c:This file contains the system clock configuration for STM32F4xx devices. /** **** ...
- NSDate和NSString
+(NSDate*) convertDateFromString:(NSString*)uiDate { NSDateFormatter *formatter = [[NSDateFormatter ...