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驱动程序在总线上的挂牌过程,这些都需要弄明白,下一篇笔记看看能不能弄清楚。