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 712 Word 2
//导出Wordprocedure TFrm_Computing.ExportWord(aFileName: string; aFileType: string);var wordApp, WordD ...
- 十六进制字符串转化成字符串输出HexToStr(Delphi版、C#版)
//注意:Delphi2010以下版本默认的字符编码是ANSI,VS2010的默认编码是UTF-8,delphi版得到的字符串须经过Utf8ToAnsi()转码才能跟C#版得到的字符串显示结果一致. ...
- LR之录制SQL脚本
1.选择协议 ①MS SQL serve ②ODBC 一般情况下选ODBC 2.录制步骤
- 发现第三方资源,chrome控制台
for(var i=0,tags=document.querySelectorAll('iframe[src],frame[src],script[src],link[rel=stylesheet], ...
- oracle 查看表的相关信息
1.查看当前用户的表 SELECT * FROM user_tables; 2.查看指定用户的表 SELECT * FROM all_tables WHERE owner = 'SYS';
- HTML 学习进度备忘
书签:”HTML 高级教程“及后面的内容尚未学习,另外跳过的内容有待跟进 __________________ 学习资源:W3School. 开始时间:2013.11.20 简述:此网址做为学习教程相 ...
- 线程局部变量ThreadLocal的原理及使用范围_1
线程局部变量ThreadLocal的原理及使用范围 使用原理 每个Thread中都有一个ThreadLocalMap成员, 该成员是ThreadLocal的内部类ThreadLocalMap类型.每使 ...
- anible包模块管理
ansible使用包管理模块 一般使用的包管理模块的RPM,和YUM 参数 必填 默认 选择 说明 Conf_file No YUM的配置文件 Disable_dbg_check No No Yes/ ...
- 离线树状数组 hihocoder 1391 Countries
官方题解: // 离线树状数组 hihocoder 1391 Countries #include <iostream> #include <cstdio> #include ...
- AI教程
AI制作铅笔图案笔刷 在下面的步骤中,我们将学习如何在Adobe Illustrator中创建铅笔笔刷.首先你要建立一个简单的网格,以及如何使用基本的工具和形状创建主要的形状.然后,学习如何保 ...