Chinaunix首页 | 论坛 | 博客
  • 博客访问: 378093
  • 博文数量: 56
  • 博客积分: 1449
  • 博客等级: 中尉
  • 技术积分: 822
  • 用 户 组: 普通用户
  • 注册时间: 2010-10-08 10:24
文章分类

全部博文(56)

文章存档

2014年(7)

2012年(13)

2011年(10)

2010年(26)

分类: LINUX

2011-02-26 18:19:57

  通过bus_register()函数可以弄清楚整个设备模型的骨架。大致的架构弄清楚之后就可以继续填充这个模型了。根据总线、设备、驱动由高层到底层的顺序,可以以设备为入口点来继续探索。
  设备的入口在device_register()函数当中。该函数相当简单,仅包含两个函数调用,第一个是device_initialize(),第二个是device_add()函数。根据调用顺序依次阅读其源码。抛开与设备模型无关的代码不谈,虽然sysfs也属于设备模型,但可以忽略它。没有显示的说明,所列出的代码都来自
drivers/base/core.c文件。
 
   首先第一个函数device_initialize()。
   570 dev->kobj.kset = devices_kset;
   由此可见,所有的设备都在这个名叫devices_kset的容器当中,可以称其为设备容器。
   571 kobject_init(&dev->kobj, &device_ktype);
   显然,所有的设备都属于device_ktype类型的。
   在设备模型当中,该函数的作用就是将该设备放入设备容器当中,并设置设备类型。
 
   第二个函数device_add()。
   971  parent = get_device(dev->parent);
   972  setup_parent(dev, parent);
   这两条语句设置该设备的内嵌kobject的父kobject为其父设备的kobject。当然,该设备可能没有父设备。再次体现出kobject在设备模型中对理清各个设备层次关系的重要性。
 
   980  error = kobject_add(&dev->kobj, dev->kobj.parent, NULL);
   将该设备添加到上层设备的内嵌kobject链表当中。即dev->kobj.parent.list链表。dev->kobj.parent可能为空,由kobject_add函数可知,会将dev->kobj.kset.kobj设置为dev->kobj.parent。
而dev->kobj.kset就是devices_kset。这样对于没有父设备的设备就直接在devices_kset的下层。而devices_kset只是一个容器.所以该设备就属于顶层设备。
 
    1010  error = bus_add_device(dev);
    这里在设备层次上暴露出与总线的交互关系.跟踪其函数调用。只有一条语句与设备模型相关。
    在drivers/base/bus.c文件当中:
    467  klist_add_tail(&dev->p->knode_bus, &bus->p->klist_devices);
    该语句就是将该设备添加到其所连接到的总线上设备链表当中。由此可知,通过总线的设备链表可以获知所有连接到该总线的设备。相当明了了... (有兴趣的童鞋可以浏览一下klist的接口)
 
     1026 bus_probe_device(dev);
     设备在驱动模型自设备往上的逻辑结构已经完成了.现在就该给device找个能够驱动它的驱动了。不在此做延伸.这里涉及到了总线、设备、驱动三者之间的关系.而这里仅以设备位主线来考察。留待驱动这个层次分析清楚之后再作展开。
 
      1027 if (parent)
      1028      klist_add_tail(&dev->p->knode_parent,
      1029              &parent->p->klist_children);
      如果该设备有父设备.就将其添加到父设备的子设备链表当中。
 
以上就是device_register所做的所有事情.其中主要就是理清该设备在设备模型中与总线、父设备以及驱动之间的所有复杂的关系.
  
   
阅读(1970) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~