Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2099872
  • 博文数量: 361
  • 博客积分: 10828
  • 博客等级: 上将
  • 技术积分: 4161
  • 用 户 组: 普通用户
  • 注册时间: 2010-01-20 14:34
文章分类

全部博文(361)

文章存档

2011年(132)

2010年(229)

分类: LINUX

2011-03-05 11:30:37

一 介绍

在2.4和更早的Linux内核中,并没有统一的数据库来描述系统中存在什么设备,以及他们之间是如何联系起来的。这样带来的影响是:
1 用户必须在日志消息中用grep来找出内核有没有检测到有特定的设备连接。也没有直接的方法供应用程序使用,来列出哪些设备被内核检测到,或者是否有驱动与设备相联系。
2 不太可能实施适当的电源管理,因为这需要设备是如何连接到系统的信息。比如,在一个USB控制器关闭之前,所有链接到这个控制器的USB外围设备都将被关闭。

为了克服这些问题,在2.5以后的内核中,提供了一个维护设备模型的框架(Framework)。这篇文章将描述这个设备模型框架。这篇文章的目的 是提供一个设备模型框架的“鸟瞰图”,并不详细讨论。其中的每个子组件的详细信息可以在很多其他的书籍,文章,以及Linux源代码中找到。

在设备模型的创建和维护中,有5个软件组件扮演着重要角色。它们是:
·设备模型核心
·通用总线驱动
·总线控制器驱动
·设备驱动
·类别驱动

二 设备模型核心

设备模型核心定义了一套结构体和函数。结构体规定了设备模型的创建块,函数则负责更新和维护设备模型。

设备模型核心定义的一些重要结构体如下:
·struct bus_type
·struct device
·struct device_driver
·struct class

struct bus_type用来描述总线类型,如:PCI, USB, I2C等等。struct device用来描述具体的设备,如:Intel AC97音频控制器,Intel PRO/100以太网控制器,PS/2鼠标等等。struct device_driver用来描述能驱动特定设备的内核驱动。struct class用来描述一类设备,如:声音,输入,图像等等。不管它们是怎么连接到系统的。

同时,设备模型核心定义了函数来注册和注销上述结构体的实体。这些函数如下:
·bus_register()
·bus_unregister()
·device_register()
·device_unregister()
·driver_register()
·driver_unregister()
·class_register()
·class_unregister()
实现设备模型核心的文件是:include/linux/device.h,drivers/base/*.c。

三 通用总线驱动

内核支持的每一条总线都有一个通用的总线驱动。通用总线驱动分配一个struct bus_type结构体并将它注册到总线类型的内核链表上,注册用bus_register()完成。(bus_type_register()将是个更恰当的名字!)

bus_type结构体的重要成员如下所示:
bus_type
|– name (string)
|– !klist_devices (klist)
|– !klist_drivers (klist)
|– match (fp)
|– suspend (fp)
|– resume (fp)

用“!”标注的部分是设备模型核心私有的,不能被通用总线驱动直接访问。
·name成员提供一个人可读的总线类型。例如:pci, usb, mdio。
·klist_drivers成员是一串能处理一个总线上各种设备的驱动列表。
·klist_devices成员是系统中挂接在特定类型总线上的设备列表。这个列表由device_register()函数更新,它是在总线控制器渠道扫描到设备连接时调用的(在初始化或外围小设备热插拔时)。
·当一个新的设备插到系统中时,总线控制器驱动检测到这个设备并调用device_register(),在与驱动列表相关的总线中迭代,以找出是否有驱动能处理这个设备。bus_type结构体中提供的match()函数用来检查给定的驱动是否能驱动给定的设备。
·当驱动模块插入到内核中,驱动调用driver_register()时,迭代查找与总线相关的驱动列表,找出是否有这个驱动能处理的设备。match函数就是为此目的设计的。

当找到匹配的驱动后,这个设备就与特定的设备驱动关联,这个关联设备和设备驱动的过程叫绑定。下面给出的是一个bus_type在PHY管理总线上的例子:
struct bus_type mdio_bus_type = {
.name = “mdio_bus”,
.match = mdio_bus_match,
.suspend = mdio_bus_suspend,
.resume = mdio_bus_resume,
};

与定义bus_type不同的是,通用总线驱动定义了一个与总线确切相关的驱动结构和设备结构。这些结构添加总线成员,从而扩展了设备模型核心提供的struct device_driver和struct device。

通用总线驱动提供了帮助函数来注册和注销能驱动总线上的设备的设备驱动。这些函数封装了设备模型核心提供的通用函数。




阅读(1182) | 评论(0) | 转发(1) |
0

上一篇:container_of 理解

下一篇:linux设备模型详解

给主人留下些什么吧!~~