LDD 3rd 中文版实在是让我忍无可忍,USB驱动一章翻译得那是相当的晦涩,看得我云里雾里,索性扔下书来看代码,以后主要靠自己分析代码学习,多读网上前辈的笔记,这样不仅能加深对代码的理解,也看到了别人的思维角度,比抱着LDD 3rd啃强多了,开搞!
新手自学笔记,比较罗嗦,冗长,学到什么地方就写到什么地方,没有具体的层次和顺序。写这个笔记的目的,仅仅是当作备忘和一个过程的记录,如果高手看到了谬误之处,敬请斧正。
全部代码、笔记、实验都在Debian GNU/Linux 下进行,内核版本如下:
ganquan@debian:~$ uname -r
2.6.26-2-686
0.先从阅读usb-skeleton.c开始
ganquan@debian:~$ cat /usr/src/linux-source-2.6.26/drivers/usb/usb-skeleton.c | wc -l
525
还好,只有525行。不算吓人。
从驱动程序的Hello World开始看:
504 static int __init usb_skel_init(void)
505 {
506 int result;
507
508 /* register this driver with the USB subsystem */
509 result = usb_register(&skel_driver);
510 if (result)
511 err("usb_register failed. Error number %d", result);
512
513 return result;
514 }
515
516 static void __exit usb_skel_exit(void)
517 {
518 /* deregister this driver with the USB subsystem */
519 usb_deregister(&skel_driver);
520 }
显然的,504行的usb_skel_init(void)就是insmod之后被运行的初始化函数,它只干了一件事:调用usb_register函数,注册了一个叫skel_driver的东西,skel_driver是在usb-skeleton.c 文件67行定义的一个usb_driver类型的结构体。再来看看usb_driver到底是何方妖孽。
在linux-source-2.6.26/include/linux/usb.h里面,991行到1015行定义了这个结构体如下:
991 struct usb_driver {
992 const char *name;
993
994 int (*probe) (struct usb_interface *intf,
995 const struct usb_device_id *id);
996
997 void (*disconnect) (struct usb_interface *intf);
998
999 int (*ioctl) (struct usb_interface *intf, unsigned int code,
1000 void *buf);
1001
1002 int (*suspend) (struct usb_interface *intf, pm_message_t message);
1003 int (*resume) (struct usb_interface *intf);
1004 int (*reset_resume)(struct usb_interface *intf);
1005
1006 int (*pre_reset)(struct usb_interface *intf);
1007 int (*post_reset)(struct usb_interface *intf);
1008
1009 const struct usb_device_id *id_table;
1010
1011 struct usb_dynids dynids;
1012 struct usbdrv_wrap drvwrap;
1013 unsigned int no_dynamic_id:1;
1014 unsigned int supports_autosuspend:1;
1015 };
可见这个结构体包含了不少函数指针,通过名字大概猜了一下各个回调函数里面应该干啥,结构体中各个字段在内核代码中都有详细注释,不再一一叙述。总之,这个结构体现在看来,是用于标识我的USB驱动程序的。
搞清楚了传递给usb_register函数的参数,再看来看这个函数是干啥的。
还是在linux-source-2.6.26/include/linux/usb.h里面,有:
1075 static inline int usb_register(struct usb_driver *driver)
1076 {
1077 return usb_register_driver(driver, THIS_MODULE, KBUILD_MODNAME);
1078 }
这个内联函数居然又调用了另外一个函数,内核真是一个蜘蛛网,一点也不假,继续看:
usb_register_driver函数,第一个参数是用来标识USB驱动程序的usb_driver类型的结构体,第二、三个参数都是宏,但是第二个参数其实是一个module类型的结构体,第三个参数是字符指针,这两个参数暂时不分析。先放着就可以了。
接下来看一下usb_register_driver函数又干了什么。
在linux-source-2.6.26/driver/usb/core/driver.c中:
715 int usb_register_driver(struct usb_driver *new_driver, struct module *owner,
716 const char *mod_name)
717 {
718 int retval = 0;
719
720 if (usb_disabled())
721 return -ENODEV;
722
723 new_driver->drvwrap.for_devices = 0;
724 new_driver->drvwrap.driver.name = (char *) new_driver->name;
725 new_driver->drvwrap.driver.bus = &usb_bus_type;
726 new_driver->drvwrap.driver.probe = usb_probe_interface;
727 new_driver->drvwrap.driver.remove = usb_unbind_interface;
728 new_driver->drvwrap.driver.owner = owner;
729 new_driver->drvwrap.driver.mod_name = mod_name;
730 spin_lock_init(&new_driver->dynids.lock);
731 INIT_LIST_HEAD(&new_drive->dynids.list);
732
733 retval = driver_register(&new_driver->drvwrap.driver);
734
735 if (!retval) {
736 pr_info("%s: registered new interface driver %s\n",
737 usbcore_name, new_driver->name);
738 usbfs_update_special();
739 usb_create_newid_file(new_driver);
740 } else {
741 printk(KERN_ERR "%s: error %d registering interface "
742 " driver %s\n",
743 usbcore_name, retval, new_driver->name);
744 }
745
746 return retval;
747 }
以上可见usb_register_driver函数中对usb_driver结构体的一个成员赋值,也就是对drvwrap成员。drvwrap是一个结构体,函数中对它的driver成员的各个字段进行赋值,并且usb_register_driver函数中还调用了一个driver_register函数,传入参数是drvwap的driver字段,看来这个drvwap成员分量不轻,现在去探究一下 这个usbdrv_wrap类型的drvwrap又是什么。
在linux-source-2.6.26/include/linux/usb.h中:
934 struct usbdrv_wrap {
935 struct device_driver driver;
936 int for_devices;
937 };
可见,usbdrv_wrap只不过是一个对device_driver的封装,继续深入看一下device_driver又是什么。
在linux-source-2.6.26/include/linux/device.h中:
120 struct device_driver {
121 const char *name;
122 struct bus_type *bus;
123
124 struct module *owner;
125 const char *mod_name; /* used for built-in modules */
126
127 int (*probe) (struct device *dev);
128 int (*remove) (struct device *dev);
129 void (*shutdown) (struct device *dev);
130 int (*suspend) (struct device *dev, pm_message_t state);
131 int (*resume) (struct device *dev);
132 struct attribute_group **groups;
133
134 struct driver_private *p;
135 };
注意到device_driver的定义,134行又是一个driver_private结构体指针。非常有必要弄清楚这个结构体。
在linux-source-2.6.26/driver/base/base.h中,有:
30 struct driver_private {
31 struct kobject kobj;
32 struct klist klist_devices;
33 struct klist_node knode_bus;
34 struct module_kobject *mkobj;
35 struct device_driver *driver;
36 };
继续深入看看kobject又长什么样子。
在linux-source-2.6.26/include/linux/kobject.h中:
60 struct kobject {
61 const char *name;
62 struct kref kref;
63 struct list_head entry;
64 struct kobject *parent;
65 struct kset *kset;
66 struct kobj_type *ktype;
67 struct sysfs_dirent *sd;
68 unsigned int state_initialized:1;
69 unsigned int state_in_sysfs:1;
70 unsigned int state_add_uevent_sent:1;
71 unsigned int state_remove_uevent_sent:1;
72 };
到底了,为啥到底了。去看看linux-source-2.6.26/Document/kobject.txt就知道为啥到底了。
那么kobject到底是个啥?
kobject就是组成Linux的设备模型的基本数据结构。kobject的任务有:
(1)对内核对象的计数,对应数据结构就是struct kref
(2)sysfs表述
(3)数据结构关联
(4)热插拔处理
对usb_driver一层一层的拨开,最后走到了kobject。在内核设计中也用到了面向对象的思想,kobject就可以当作基类,其他的类都是从kobject继承的,由于C语言不能像C++那样继承,所以就一次又一次的封装。
我现在搞清楚了各个struct之间的关系:
kobject—>driver_private—>device_driver—>usbdrv_wrap—>usb_driver
总结他们之间的关系如下:
kobject是Linux设备模型的基本数据结构,它被作为“基类”,其他“子类”都是“继承”了kobject。在我分析的这个例子中,driver_private就是一个“子类”,它直接“继承”了kobject。事实上,老版本的内核(2.6.10)直接把kobject放在device_driver中,新版本的内核则是用driver_private来存放kobject,然后再把driver_private封装在device_driver中。device_driver中除了包含driver_private,还有很多函数指针,也就是驱动程序需要提供的服务。接下来,usbdrv_wrap再次封装了device_driver,这次封装很简单,没有增加过多额外的字段。最后usb_driver来封装usbdrv_wrap,usb_driver中也有很多的函数指针。
这些结构体的各个字段,具体作用是什么?尤其是最接近“基类”的那些“子类”的以k开头的字段,都用来实现什么功能?
驱动程序提供的服务又是什么样子,以及USB驱动程序在总线上的挂牌过程,这些都需要弄明白,下一篇笔记看看能不能弄清楚。