下面的分析,米卢教练说了,内容不重要,重要的是态度。就像韩局长对待日记的态度那样,严谨而细致。
只要你使用这样的态度开始分析内核,那么无论你选择内核的哪个部分作为切入点,比如USB,比如进程管理,在花费相对不算很多的时间之后,你就会发 现你对内核的理解会上升到另外一个高度,一个抱着情景分析,抱着0.1内核完全注释,抱着各种各样的内核书籍翻来覆去的看很多遍又忘很多遍都无法达到的高 度。请相信我!让我们在Linux社区里发出号召:学习内核源码,从学习韩局长开始!
态度决定一切:从初始化函数开始
任小强们说房价高涨从现在开始,股评家们说牛市从5000点开始。他们的开始需要我们的钱袋,我们的开始只需要一台电脑,最好再有一杯茶,伴着几支小曲儿,不盯着钱总是会比较惬意的。生容易,活容易,生活不容易,因为总要盯着钱。
有了地图Kconfig和Makefile,我们可以在庞大复杂的内核代码中定位以及缩小了目标代码的范围。那么现在,为了研究内核对USB子系统的实现,我们还需要在目标代码中找到一个突破口,这个突破口就是USB子系统的初始化代码。
针对某个子系统或某个驱动,内核使用subsys_initcall或module_init宏指定初始化函数。在drivers/usb/core/usb.c文件中,我们可以发现下面的代码。
940 subsys_initcall(usb_init);
941 module_exit(usb_exit);
我们看到一个subsys_initcall,它也是一个宏,我们可以把它理解为module_init,只不过因为这部分代码比较核心,开发者们 把它看作一个子系统,而不仅仅是一个模块。这也很好理解,usbcore这个模块它代表的不是某一个设备,而是所有USB设备赖以生存的模块,Linux 中,像这样一个类别的设备驱动被归结为一个子系统。比如PCI子系统,比如SCSI子系统,基本上,drivers/目录下面第一层的每个目录都算一个子 系统,因为它们代表了一类设备。
subsys_initcall(usb_init)的意思就是告诉我们usb_init是USB子系统真正的初始化函数,而usb_exit() 将是整个USB子系统的结束时的清理函数。于是为了研究USB子系统在内核中的实现,
我们需要从usb_init函数开始看起。
866 {
867 int retval;
868 if (nousb) {
869 pr_info("%s: USB support disabled\n", usbcore_name);
870 return 0;
871 }
872
873 retval = ksuspend_usb_init();
874 if (retval)
875 goto out;
876 retval = bus_register(&usb_bus_type);
877 if (retval)
878 goto bus_register_failed;
879 retval = usb_host_init();
880 if (retval)
881 goto host_init_failed;
882 retval = usb_major_init();
883 if (retval)
884 goto major_init_failed;
885 retval = usb_register(&usbfs_driver);
886 if (retval)
887 goto driver_register_failed;
888 retval = usb_devio_init();
889 if (retval)
890 goto usb_devio_init_failed;
891 retval = usbfs_init();
892 if (retval)
893 goto fs_init_failed;
894 retval = usb_hub_init();
895 if (retval)
896 goto hub_init_failed;
897 retval = usb_register_device_driver(&usb_generic_driver, THIS_MODULE);
898 if (!retval)
899 goto out;
900
901 usb_hub_cleanup();
902 hub_init_failed:
903 usbfs_cleanup();
904 fs_init_failed:
905 usb_devio_cleanup();
906 usb_devio_init_failed:
907 usb_deregister(&usbfs_driver);
908 driver_register_failed:
909 usb_major_cleanup();
910 major_init_failed:
911 usb_host_cleanup();
912 host_init_failed:
913 bus_unregister(&usb_bus_type);
914 bus_register_failed:
915 ksuspend_usb_cleanup();
916 out:
917 return retval;
918 }