技术开发 频道

史上最经典的Linux内核学习方法论

  (2)模块参数。

  关于usb_init函数,第二个问题是,第868行的nousb表示什么?

  知道C语言的人都会知道nousb是一个标志,只是不同的标志有不一样的精彩,这里的nousb是用来让我们在启动内核的时候通过内核参数去掉 USB子系统的,Linux社会是一个很人性化的世界,它不会去逼迫我们接受USB,一切都只关乎我们自己的需要。不过我想我们一般来说是不会去指定nousb的吧。如果你真的指定了nousb,那它就只会幽怨的说一句“USB support disabled”,然后退出usb_init。

  nousb在drivers/usb/core/usb.c文件中定义为:

  static int nousb; /* Disable USB when built into kernel image */

  module_param_named(autosuspend, usb_autosuspend_delay, int, 0644);

  MODULE_PARM_DESC(autosuspend, "default autosuspend delay");

  从中可知nousb是个模块参数。关于模块参数,我们都知道可以在加载模块的时候可以指定,但是如何在内核启动的时候指定?

  打开系统的grub文件,然后找到kernel行,比如:

  kernel /boot/vmlinuz-2.6.18-kdb root=/dev/sda1 ro splash=silent vga=0x314

  其中的root,splash,vga等都表示内核参数。当某一模块被编译进内核的时候,它的模块参数便需要在kernel行来指定,格式为“模块名.参数=值”,比如:

  modprobe usbcore autosuspend=2

  对应到kernel行,即为 :

  usbcore.autosuspend=2

  通过命令“modinfo -p ${modulename}”可以得知一个模块有哪些参数可以使用。同时,对于已经加载到内核里的模块,它们的模块参数会列举在/sys/module /${modulename}/parameters/目录下面,可以使用“echo -n ${value} > /sys/module/${modulename}/parameters/$

  {parm}”这样的命令去修改。

  (3)可变参数宏。

  关于usb_init函数,第三个问题是,pr_info如何实现与使用?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");展开后,里面的字符串后面会多个多余的逗号。这个逗号你应该不会喜欢,而‘##’则会使预处理器去掉这个多余的逗号。

6
相关文章