关闭

Linux那些事儿 之 戏说USB(13)面纱

标签: linuxmodule生活gcc语言c
4606人阅读 评论(2) 收藏 举报
分类:
在爱情、背叛与死亡的漩涡中挣扎的凯蒂,亲历了幻想破灭与生死离别之后,终将生活的面纱从她的眼前渐渐揭去,从此踏上了不悔的精神成长之路。
向大家推荐这部片子《面纱》,没有那些小电影精彩,但是绝对值得一看。为什么会想到它,只在乎于现在的心情。前面说了那么多,才接触到usb_init,有点一窥usb面纱下神秘容颜的味道。当然,我们并不需要去经历爱情、被判与死亡,所需要经历的只是忍受前面大段大段的唠叨。
人往往可以被高尚感动,但始终不能因为高尚而爱上。因为被__init给盯上,usb_init在做牛做马的辛勤劳作之后便不得不灰飞烟灭,不可谓不高尚,但它始终只能是我们了解面纱后面内容的跳板,是起点,却不是终点,我们不会为它停留太久,有太多的精彩和苦恼在等着我们。
865         int retval;
866         if (nousb) {
867                 pr_info("%s: USB support disabled/n", usbcore_name);
868                 return 0;
869         }
866行,知道C语言的人都会知道nousb是一个标志,只是不同的标志有不一样的精彩,这里的nousb是用来让我们在启动内核的时候通过内核参数去掉USB子系统的,linux社会是一个很人性化的世界,它不会去逼迫我们接受USB,一切都只关乎我们自己的需要。不过我想我们一般来说是不会去指定nousb的吧,毕竟它那么的讨人可爱。如果你真的定义了nousb,那它就只会幽怨的说一句“USB support disabled”,然后退出usb_init。
867行,pr_info只是一个打印信息的宏,printk的变体,在include/linux/kernel.h里定义:
242 #define pr_info(fmt,arg...) /
243         printk(KERN_INFO fmt,##arg)
这个可变参数宏要不要说一下?地球人都知道了,不过还是聊一下吧,我有多话症。99年的ISO C标准里规定了可变参数宏,和函数语法类似,给个例子
#define debug(format, ...) fprintf (stderr, format, __VA_ARGS__)
里面的“…”就表示可变参数,调用时,它们就会替代宏体里的__VA_ARGS__。GCC总是会显得特立独行一些,它支持更复杂的形式,可以给可变参数取个名字,再给个这种形式的例子
#define debug(format, args...) fprintf (stderr, format, args)
是不是显得更容易读了些?有了名字总是会容易交流一些。是不是与咱们的pr_info比较接近了?除了‘##’,它主要是针对空参数的情况。既然说是可变参数,那传递空参数也总是可以的,空即是多,多即是空,股市里的哲理这里同样也是适合的。如果没有‘##’,传递空参数的时候,比如
debug ("A message")
宏展开后,里面的字符串后面会多个多余的逗号。这个逗号你应该不会喜欢,它是表错情了,而‘##’则会使预处理器去掉这个多余的逗号。
871         retval = ksuspend_usb_init();
872         if (retval)
873                 goto out;
874         retval = bus_register(&usb_bus_type);
875         if (retval)
876                 goto bus_register_failed;
877         retval = usb_host_init();
878         if (retval)
879                 goto host_init_failed;
880         retval = usb_major_init();
881         if (retval)
882                 goto major_init_failed;
883         retval = usb_register(&usbfs_driver);
884         if (retval)
885                 goto driver_register_failed;
886         retval = usb_devio_init();
887         if (retval)
888                 goto usb_devio_init_failed;
889         retval = usbfs_init();
890         if (retval)
891                 goto fs_init_failed;
892         retval = usb_hub_init();
893         if (retval)
894                 goto hub_init_failed;
896         if (!retval)
897                 goto out;
871到897这些行是代码里的排比句,相似的init不相似的内容,很显然都是在完成一些初始化,也是usb_init任劳任怨所付出的全部。这里先简单的说一下。
871行,电源管理方面的。如果在编译内核时没有打开电源管理,也就是说没有定义CONFIG_PM,它就什么也不做。
874行,注册USB总线,只有成功的将USB总线子系统注册到系统中,我们才可以向这个总线添加USB设备。基于它显要的江湖地位,就拿它做为日后突破的方向了,擒贼先擒王,这个越老越青春的道理在linux中也是同样适用的。
877行,执行host controller相关的初始化。
880行,一个实际的总线也是一个设备,必须单独注册,因为USB是通过快速串行通信来读写数据,这里把它当作了字符设备来注册。
883~891行,都是usbfs相关的初始化。
892行,hub的初始化,这个复旦人甲正在讲。
895行,注册USB device driver,戴好眼镜看清楚了,是USB device driver而不是USB driver,前面说过,一个设备可以有多个接口,每个接口对应不同的驱动程序,这里所谓的device driver对应的是整个设备,而不是某个接口。内核里结构到处有,只是USB这儿格外多。
剩下的几行代码都是有关资源清除的,usb_init这个短短的函数在承载着我们的希望的时候嘎然而止了,你的感觉是什么?我的感觉是:这哪是我能说的清楚的啊。它的每个分叉都更像是一个陷阱,黑黝黝看不到底,但是已经没有回头的路。
 
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:2431810次
    • 积分:7538
    • 等级:
    • 排名:第3004名
    • 原创:297篇
    • 转载:0篇
    • 译文:0篇
    • 评论:2042条
    博客专栏