register先后注册的影响和关系

开始Linux驱动的真正开发,也是从基层开始看的。相比以为Linux下的驱动就是点灯之类的Led来说,现在我的感受就是,那些完全就是表面的东西。核心层次的驱动,完全不是这么随随便便写出来的。也正好说明现在很多公司正在写驱动的不多,完全独立写的也不多,因为实在太复杂。只能靠着源码或者BSP来修改。半个多月来看了Linux2.6.10下面的音频驱动OSS架构,不是一般的复杂。熟悉了I2C驱动的整个架构( 见  )。

今天为何再写这个内容,因为最近开始看Linux下面的视频架构。恍惚间看到device_register和driver_register,这两个对驱动真正核心的东西,让我察觉到这两个到底谁需要先执行,还是没关系。百度了很多,都说的是表面文章,去qq上也是一肚子的灰,因此我依旧独立解决,虽然我知道这个问题基本没人去思考(除了写内核的大神们),因为这块内容和内核走的很近很近,代码量也大。所以基本可见的分析都在表面。故把我这次的分析总结写在这里,供大家借鉴,不对之处也请多指正。

从函数driver_register和device_register在源码中来看,这两个函数的执行顺序前后都有出现,但是之前都活在表面,没有深入的看过,因为知道内核在深入下去就是很复杂的东西。但为了解决问题只会硬着头皮去看。下面是我的一些分析,主要涉及到的是链表,kobject,kset,bus,device,device_driver几个结构体。

1. 先从driver_register的调用流程说起,主要介绍核心的调用,其间的某些函数不做解析。

driver_register->bus_add_driver->

int bus_add_driver(struct device_driver * drv)
{
 struct bus_type * bus = get_bus(drv->bus);
 int error = 0;

if (bus) {
  pr_debug("bus %s: add driver %s\n", bus->name, drv->name);
  error = kobject_set_name(&drv->kobj, "%s", drv->name);  //给kobj赋予名字
  if (error) {
   put_bus(bus);
   return error;
  }
  drv->kobj.kset = &bus->drivers;  //kset指向bus->drivers(类型为kset)
  if ((error = kobject_register(&drv->kobj))) {
   put_bus(bus);
   return error;
  }

down_read(&bus->subsys.rwsem);
  driver_attach(drv);
  up_read(&bus->subsys.rwsem);
  module_add_driver(drv->owner, drv);

driver_add_attrs(bus, drv);
 }
 return error;
}

在这个函数中,我觉得核心的是语句 drv->kobj.kset = &bus->drivers;,为何会这样说。因为实际上在设备和驱动在注册的过程中,都会将自己结构体的链表成员添加到bus->drivers和bus->devices为链表头的链表中去。最后都根据这些链表遍历所在成员的地址,然后找到设备和驱动依次执行是否probe。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/87ff9a856c051d401e55301cfa7c52a8.html