注:基于linux-2.6.38
在linux源码的根目录下有一个叫drivers的目录,可以发现linux源码根目录下也就那么十来二十个目录,linux把drivers作为根目录下的一个独立的目录,足见drivers在linux里占有的分量有多重。
打开drivers目录一看,有一种晕呼呼的感觉,好几十个目录就这样“活生生”地摆在眼前,不知该如何下手。任何东西如果多了,但没有秩序去维持,肯定
会变得很混乱,显然linux不会让这种情况出现。一般来说,里面的每一个目录可以说代表一类驱动,但linux整个driver的初始化操作在哪里?根
据前人的探索和经验可知,没错,就在/drivers/base/init.c里,打开它发现里面就一个driver_init()函数,有必要把它全部
贴出来:
1 void __init driver_init(
void)
2 {
3 /* These are the core pieces */
4 devtmpfs_init();
5 devices_init();
6 buses_init();
7 classes_init();
8 firmware_init();
9 hypervisor_init();
10
11 /* These are also core pieces, but must come after the
12 * core core pieces.
13 */
14 platform_bus_init();
15 system_bus_init();
16 cpu_dev_init();
17 memory_dev_init();
18 }
哟,原来是“禾草盖珍珠”,该函数内部全都是函数调用,其实这种现象在linux
里多的是。在这里我主要想沿着一条主线“走下去”,而不是走着走着就“跑到”老远去,然后再回来。对于学习这件事情,我更偏向于先看到结果然后再努力去搞
懂其内在的原理。好吧,接下就去寻找我想要的结果。
第4行调用devtmpfs_init()函数,从它的名字去理解它,就是/dev文件系统的初始化。第5行调用devices_init()函数,在drivers/base/core.c里定义,看看它怎么实现的:
1 int __init devices_init(
void)
2 {
3 devices_kset = kset_create_and_add(
"devices", &
device_uevent_ops, NULL);
4 if (!
devices_kset)
5 return -
ENOMEM;
6 dev_kobj = kobject_create_and_add(
"dev", NULL);
7 if (!
dev_kobj)
8 goto dev_kobj_err;
9 sysfs_dev_block_kobj = kobject_create_and_add(
"block", dev_kobj);
10 if (!
sysfs_dev_block_kobj)
11 goto block_kobj_err;
12 sysfs_dev_char_kobj = kobject_create_and_add(
"char", dev_kobj);
13 if (!
sysfs_dev_char_kobj)
14 goto char_kobj_err;
15
16 return 0;
17
18 char_kobj_err:
19 kobject_put(sysfs_dev_block_kobj);
20 block_kobj_err:
21 kobject_put(dev_kobj);
22 dev_kobj_err:
23 kset_unregister(devices_kset);
24 return -
ENOMEM;
25 }
还是比较简单的,第3行在/sys目录下创建了devices目录,第6行在/sys下创建了dev目录,第9,12行分别在/sys/dev下创建了block和char这两个目录。
接下来看在drivers/base/bus.c里定义的buses_init()函数:
1 int __init buses_init(
void)
2 {
3 bus_kset = kset_create_and_add(
"bus", &
bus_uevent_ops, NULL);
4 if (!
bus_kset)
5 return -
ENOMEM;
6 return 0;
7 }
第3行在/sys下创建了bus目录。
drivers/base/class.c里定义的classes_init()函数:
1 int __init classes_init(
void)
2 {
3 class_kset = kset_create_and_add(
"class", NULL, NULL);
4 if (!
class_kset)
5 return -
ENOMEM;
6 return 0;
7 }
第3行在/sys下创建了class目录。
对于firmware_init()和hypervisor_init这两个函数暂时掠过。
在drivers/base/platform.c里定义的platform_bus_init()函数:
1 int __init platform_bus_init(
void)
2 {
3 int error;
4
5 early_platform_cleanup();
6
7 error = device_register(&
platform_bus);
8 if (error)
9 return error;
10
11 error = bus_register(&
platform_bus_type);
12 if (error)
13 device_unregister(&
platform_bus);
14 return error;
15 }
第5行,在early_platform_cleanup()函数里通过遍历链表清除之前的平台代码。第7行,设备注册,不要被它的参数的名字骗了,先看参数platform_bus的定义:
1 struct device platform_bus = {
2 .init_name = "platform",
3 };
只定义了设备的名字为platform。再看device_register()函数:
1 int device_register(struct device *dev)
2 {
3 device_initialize(dev);
4 return device_add(dev);
5 }
只有两个函数调用,先看device_initialize()函数:
1 void device_initialize(
struct device *
dev)
2 {
3 dev->kobj.kset =
devices_kset;
4 kobject_init(&dev->kobj, &
device_ktype);
5 INIT_LIST_HEAD(&dev->
dma_pools);
6 mutex_init(&dev->
mutex);
7 lockdep_set_novalidate_class(&dev->
mutex);
8 spin_lock_init(&dev->
devres_lock);
9 INIT_LIST_HEAD(&dev->
devres_head);
10 device_pm_init(dev);
11 set_dev_node(dev, -
1);
12 }
第3行的devices_kset由之前的devices_init()里被赋值,作为所有设备的顶层kset。第4行初始化当前设备的kobject。第10行是该设备电源管理的初始化。第11行,看一下:
1 static inline void set_dev_node(struct device *dev, int node)
2 {
3 dev->numa_node = node;
4 }
没什么,就给dev里的成员numa_node赋值为node(这里是-1)。
回到device_register()里的device_add()函数,这个函数比较长,涉及的内容也很多,不过还是得看,暂时将它分为两部分吧,先看第一部分:
1 int device_add(
struct device *
dev)
2 {
3 struct device *parent =
NULL;
4 struct class_interface *
class_intf;
5 int error = -
EINVAL;
6
7 dev =
get_device(dev);
8 if (!
dev)
9 goto done;
10
11 if (!dev->
p) {
12 error =
device_private_init(dev);
13 if (error)
14 goto done;
15 }
16
17 /*
18 * for statically allocated devices, which should all be converted
19 * some day, we need to initialize the name. We prevent reading back
20 * the name, and force the use of dev_name()
21 */
22 if (dev->
init_name) {
23 dev_set_name(dev,
"%s", dev->
init_name);
24 dev->init_name =
NULL;
25 }
26
27 if (!
dev_name(dev)) {
28 error = -
EINVAL;
29 goto name_error;
30 }
31
32 pr_debug(
"device: '%s': %s\n", dev_name(dev), __func__);
33
34 parent = get_device(dev->
parent);
35 setup_parent(dev, parent);
36
37 /* use parent numa_node */
38 if (parent)
39 set_dev_node(dev, dev_to_node(parent));
40
41 /* first, register with generic layer. */
42 /* we require the name to be set before, and pass NULL */
43 error = kobject_add(&dev->kobj, dev->
kobj.parent, NULL);
44 if (error)
45 goto Error;
46
47 /* notify platform of device entry */
48 if (platform_notify)
49 platform_notify(dev);
50
51 error = device_create_file(dev, &
uevent_attr);
52 if (error)
53 goto attrError;
54
55 if (MAJOR(dev->
devt)) {
56 error = device_create_file(dev, &
devt_attr);
57 if (error)
58 goto ueventattrError;
59
60 error =
device_create_sys_dev_entry(dev);
61 if (error)
62 goto devtattrError;
63
64 devtmpfs_create_node(dev);
65 }
66 error =
device_add_class_symlinks(dev);
67 if (error)
68 goto SymlinkError;
69 error =
device_add_attrs(dev);
70 if (error)
71 goto AttrsError;
72 error =
bus_add_device(dev);
73 if (error)
74 goto BusError;
75 error =
dpm_sysfs_add(dev);
76 if (error)
77 goto DPMError;
78 device_pm_add(dev);
.....................
第7行,增加该设备的引用计数;第12行,主要为dev->p成员分配内
存,然后对p里面的一些成员作初始化;第22~30行是关与dev->name的一些操作;第35行,设置当前设备的父设备;第39行,看注释就知
道是将父设备numa_node成员的值赋给当前设备;第43行,调用kobject_add(),这个函数的内部调用关系挺复杂的,主要功能是建立当前
设备与父设备的kobject对象关系和在/sys相应的目录下建立一个目录;第51行,创建设备的属性文件;第55行,如果该设备定义了主设备号的话就
再生成一个设备文件,还有就是通过devtmpfs_create_node()函数在/dev下动态创建设备节点。第66~77行主要涉及sysfs文件系统的操作,在此暂时掠过;第78行是与电源管理相关的。
接下来看device_add()函数的第2部分:
1 if (dev->
bus)
2 blocking_notifier_call_chain(&dev->bus->p->
bus_notifier,
3 BUS_NOTIFY_ADD_DEVICE, dev);
4
5 kobject_uevent(&dev->
kobj, KOBJ_ADD);
6 bus_probe_device(dev);
7 if (parent)
8 klist_add_tail(&dev->p->
knode_parent,
9 &parent->p->
klist_children);
10
11 if (dev->
class) {
12 mutex_lock(&dev->
class->p->
class_mutex);
13 /* tie the class to the device */
14 klist_add_tail(&dev->
knode_class,
15 &dev->
class->p->
klist_devices);
16
17 /* notify any interfaces that the device is here */
18 list_for_each_entry(class_intf,
19 &dev->
class->p->
class_interfaces, node)
20 if (class_intf->
add_dev)
21 class_intf->
add_dev(dev, class_intf);
22 mutex_unlock(&dev->
class->p->
class_mutex);
23 }
24 done:
25 put_device(dev);
26 return error;
27 DPMError:
28 bus_remove_device(dev);
29 BusError:
30 device_remove_attrs(dev);
31 AttrsError:
32 device_remove_class_symlinks(dev);
33 SymlinkError:
34 if (MAJOR(dev->
devt))
35 devtmpfs_delete_node(dev);
36 if (MAJOR(dev->
devt))
37 device_remove_sys_dev_entry(dev);
38 devtattrError:
39 if (MAJOR(dev->
devt))
40 device_remove_file(dev, &
devt_attr);
41 ueventattrError:
42 device_remove_file(dev, &
uevent_attr);
43 attrError:
44 kobject_uevent(&dev->
kobj, KOBJ_REMOVE);
45 kobject_del(&dev->
kobj);
46 Error:
47 cleanup_device_parent(dev);
48 if (parent)
49 put_device(parent);
50 name_error:
51 kfree(dev->
p);
52 dev->p =
NULL;
53 goto done;
54 }
第5行kobject_uevent()这个函数的实现不是一般的复杂,主要是向用户空间发送消息,实现热插拔,暂时用不到,先掠过;第6行,bus_probe_device()这个函数非常重要,因此尽可能详细地分析一下,看它在drivers/base/bus.c里定义:
1 void bus_probe_device(
struct device *
dev)
2 {
3 struct bus_type *bus = dev->
bus;
4 int ret;
5
6 if (bus && bus->p->
drivers_autoprobe) {
7 ret =
device_attach(dev);
8 WARN_ON(ret <
0);
9 }
10 }
别看它那么短,其实没那么简单。if的条件很显然,直接看第7行的device_attach()函数,在drivers/base/dd.c里定义为:
1 int device_attach(
struct device *
dev)
2 {
3 int ret =
0;
4
5 device_lock(dev);
6 if (dev->
driver) {
7 ret =
device_bind_driver(dev);
8 if (ret ==
0)
9 ret =
1;
10 else {
11 dev->driver =
NULL;
12 ret =
0;
13 }
14 }
else {
15 pm_runtime_get_noresume(dev);
16 ret = bus_for_each_drv(dev->
bus, NULL, dev, __device_attach);
17 pm_runtime_put_sync(dev);
18 }
19 device_unlock(dev);
20 return ret;
21 }
第6行,如果当前设备已经绑定了相应的驱动程序,那么就调用device_bind_driver()。在这里有个疑问:先有设备还是先有驱动?一般来说是先有设备再有驱动,但对于热插拔设备来说的话则相反。不管怎样,去看看它是怎么定义的:
1 int device_bind_driver(
struct device *
dev)
2 {
3 int ret;
4
5 ret =
driver_sysfs_add(dev);
6 if (!
ret)
7 driver_bound(dev);
8 return ret;
9 }
第5行是与sysfs有关的,直接看第7行的driver_bound()函数:
1 static void driver_bound(
struct device *
dev)
2 {
3 if (klist_node_attached(&dev->p->
knode_driver)) {
4 printk(KERN_WARNING
"%s: device %s already bound\n",
5 __func__, kobject_name(&dev->
kobj));
6 return;
7 }
8
9 pr_debug(
"driver: '%s': %s: bound to device '%s'\n", dev_name(dev),
10 __func__, dev->driver->
name);
11
12 klist_add_tail(&dev->p->knode_driver, &dev->driver->p->
klist_devices);
13
14 if (dev->
bus)
15 blocking_notifier_call_chain(&dev->bus->p->
bus_notifier,
16 BUS_NOTIFY_BOUND_DRIVER, dev);
17 }
咋一看,都是与链表操作相关的,关键是第12行,实现将驱动程序和设备联系起来。
回到device_attach()函数的第16行,调用bus_for_each_drv()函数遍历设备所在总线上所有已经挂载了的驱动,每遍历一个就调用一次__device_attach()函数,直接看__device_attach()的定义:
1 static int __device_attach(
struct device_driver *drv,
void *
data)
2 {
3 struct device *dev =
data;
4
5 if (!
driver_match_device(drv, dev))
6 return 0;
7
8 return driver_probe_device(drv, dev);
9 }
第5行的函数是在drivers/base/base.h头文件中定义的,只有一行:
1 static inline int driver_match_device(struct device_driver *drv,
2 struct device *dev)
3 {
4 return drv->bus->match ? drv->bus->match(dev, drv) : 1;
5 }
如果驱动所在的总线上定义了match函数,那么就调用它,否则返回1。
如果driver_match_device()成功,接下来就调用driver_probe_device():
1 int driver_probe_device(
struct device_driver *drv,
struct device *
dev)
2 {
3 int ret =
0;
4
5 if (!
device_is_registered(dev))
6 return -
ENODEV;
7
8 pr_debug(
"bus: '%s': %s: matched device %s with driver %s\n",
9 drv->bus->name, __func__, dev_name(dev), drv->
name);
10
11 pm_runtime_get_noresume(dev);
12 pm_runtime_barrier(dev);
13 ret =
really_probe(dev, drv);
14 pm_runtime_put_sync(dev);
15
16 return ret;
17 }
主要是第13行的really_probe(),该函数有点长,主要看它的核心部分:
-->
阅读(2361) | 评论(0) | 转发(1) |