免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1080 | 回复: 0
打印 上一主题 下一主题

linux设备模型深探(2) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-01-12 18:19 |只看该作者 |倒序浏览

linux设备模型深探(2)
v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
在前面一篇
linux设备模型深探(1)
我们详细了解了底层元素kset,kobject,ktype之间的关系后,本节讲解下驱动模型中另外几个概念(bus、driver、device)为后面具体分析特定驱动(platform,pci)模型打个基础。

BUS
在设备模型中,所有的device都是通过总线bus 连接,这里的bus包括通常意义的总线如usb,pci,也包括虚拟的platform总线。
[root@wangp bus]# pwd
/sys/bus
[root@wangp bus]# ls
ac97  acpi  bluetooth  gameport  i2c  ide  pci  pci_express  pcmcia  platform  pnp  scsi  serio  usb
[root@wangp platform]# pwd
/sys/bus/platform
[root@wangp platform]# ls
devices  drivers

struct bus_type {
       const char              * name;
       struct module         * owner;

       struct kset             subsys;
       struct kset             drivers;
       struct kset             devices;
       struct klist              klist_devices;
       struct klist              klist_drivers;

       struct blocking_notifier_head bus_notifier;

       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 (*suspend_late)(struct device * dev, pm_message_t state);
       int (*resume_early)(struct device * dev);
       int (*resume)(struct device * dev);

       unsigned int drivers_autoprobe:1;
};

name是总线的名字,每个总线下都有自己的子系统,其中包含2个kset,deviece和driver,分别代表已知总线的驱动和插入总线的设备
如platform总线的声明如下:

struct bus_type platform_bus_type = {
       .name             = "platform",
       .dev_attrs       = platform_dev_attrs,
       .match            = platform_match,
       .uevent          = platform_uevent,
       .suspend  = platform_suspend,
       .suspend_late  = platform_suspend_late,
       .resume_early  = platform_resume_early,
       .resume          = platform_resume,
};

只有很少的bus_type成员需要初始化,大部分交给kernel来处理


关于总线的操作常用的如下:
int  bus_register(struct bus_type * bus);
void bus_unregister(struct bus_type * bus);
/* iterator helpers for buses */

列举总线上从start之后的每个设备,并进行fn操作,通常用途是对bus上的设备和驱动进行绑定
int bus_for_each_dev(struct bus_type * bus, struct device * start, void * data, int (*fn)(struct device *, void *));

int driver_attach(struct device_driver * drv)
{
       return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
}

static int __driver_attach(struct device * dev, void * data)
{
       struct device_driver * drv = data;

       /*
        * Lock device and try to bind to it. We drop the error
        * here and always return 0, because we need to keep trying
        * to bind to devices and some drivers will return an error
        * simply if it didn't support the device.
        *
        * driver_probe_device() will spit a warning if there
        * is an error.
        */

       if (dev->parent)      /* Needed for USB */
              down(&dev->parent->sem);
       down(&dev->sem);
       if (!dev->driver)
              driver_probe_device(drv, dev);
       up(&dev->sem);
       if (dev->parent)
              up(&dev->parent->sem);

       return 0;
}

几乎linux设备模型的每一层都提供了添加属性的函数,总线也不例外
struct bus_attribute {
       struct attribute       attr;
       ssize_t (*show)(struct bus_type *, char * buf); //显示属性
       ssize_t (*store)(struct bus_type *, const char * buf, size_t count); //设置属性
};
创建属于一个总线的属性使用(在模块的加载时间完成)
int  bus_create_file(struct bus_type *,struct bus_attribute *);
void bus_remove_file(struct bus_type *, struct bus_attribute *);

在说明下bus在sysfs里面的结构,刚才已经讲过,bus_type中有2个kset结构对应于device和driver,也就是说每个bus下面都会有device何driver2个文件夹。

首先在总线上注册的驱动会得到一个文件夹driver,如platform驱动
[root@wangp platform]# pwd
/sys/bus/platform
[root@wangp platform]# ls
devices  drivers
[root@wangp drivers]# pwd
/sys/bus/platform/drivers
[root@wangp drivers]# ls
i8042  pcspkr  serial8250  vesafb

而任何在总线/sys/bus/xxx/上发现的设备会得到一个symlink(符号链接)即/sys/bus/xxx/device指向/sys/device/xxx下面的文件夹
[root@wangp devices]# pwd
/sys/bus/platform/devices
[root@wangp devices]# ls -l
total 0
lrwxrwxrwx 1 root root 0 Jun  6 10:37 bluetooth -> ../../../devices/platform/bluetooth
lrwxrwxrwx 1 root root 0 Jun  6 10:37 floppy.0 -> ../../../devices/platform/floppy.0
lrwxrwxrwx 1 root root 0 Jun  6 10:37 i8042 -> ../../../devices/platform/i8042
lrwxrwxrwx 1 root root 0 Jun  6 10:37 pcspkr -> ../../../devices/platform/pcspkr
lrwxrwxrwx 1 root root 0 Jun  6 10:37 serial8250 -> ../../../devices/platform/serial8250
lrwxrwxrwx 1 root root 0 Jun  6 10:37 vesafb.0 -> ../../../devices/platform/vesafb.0
<SPAN style="FONT-SIZE: 9pt; COLOR: black; FON

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/109300/showart_2146861.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP