内核子体系或设备驱动能够直接编译到内核,也能够编译成模块,假如编译到内核,能够运用前一节介绍的办法经过内核发动参数来向它们传递参数,假如编译成模块,则能够经过指令行在刺进模块时传递参数,或许在运转时,经过sysfs来设置或读取模块数据。
Sysfs是一个根据内存的文件体系,实际上它根据ramfs,sysfs供给了一种把内核数据结构、它们的特点以及特点与数据结构的联络开放给用户态的方法,它与kobject子体系严密地结合在一起,因而内核开发者不需要直接运用它,而是内核的各个子体系运用它。用户要想运用 sysfs 读取和设置内核参数,仅需装载 sysfs 就能够经过文件操作应用来读取和设置内核经过 sysfs 开放给用户的各个参数:
# mkdir -p /sysfs
$ mount -t sysfs sysfs /sysfs
留意,不要把 sysfs 和 sysctl 混杂,sysctl 是内核的一些操控参数,其意图是便使用户对内核的行为进行操控,而 sysfs 仅仅是把内核的 kobject 目标的层次联系与特点开放给用户检查,因而 sysfs 的绝大部分是只读的,模块作为一个 kobject 也被出口到 sysfs,模块参数则是作为模块特点出口的,内核完成者为模块的运用供给了更灵敏的方法,答应用户设置模块参数在 sysfs 的可见性并答应用户在编写模块时设置这些参数在 sysfs 下的拜访权限,然后用户就能够经过sysfs 来检查和设置模块参数,然后使得用户能在模块运转时操控模块行为。
关于模块而言,声明为 static 的变量都能够经过指令行来设置,但要想在 sysfs下可见,有必要经过宏 module_param 来显式声明,该宏有三个参数,第一个为参数名,即现已界说的变量名,第二个参数则为变量类型,可用的类型有 byte, short, ushort, int, uint, long, ulong, charp 和 bool 或 invbool,别离对应于 c 类型 char, short, unsigned short, int, unsigned int, long, unsigned long, char * 和 int,用户也能够自界说类型 XXX(假如用户自己界说了 param_get_XXX,param_set_XXX 和 param_check_XXX)。该宏的第三个参数用于指定拜访权限,假如为 0,该参数将不出现在 sysfs 文件体系中,答应的拜访权限为 S_IRUSR, S_IWUSR,S_IRGRP,S_IWGRP,S_IROTH 和 S_IWOTH 的组合,它们别离对应于用户读,用户写,用户组读,用户组写,其他用户读和其他用户写,因而用文件的拜访权限设置是共同的。
在源代码中的内核模块 module-param-exam.c 是一个使用模块参数和sysfs来进行用户态与内核态数据交互的比如。该模块有三个参数能够经过指令行设置,下面是作者体系上的运转成果示例:
# insmod 。/module-param-exam.ko my_invisible_int=10 my_visible_int=20 mystring=“Hello,World”
my_invisible_int = 10
my_visible_int = 20
mystring = ‘Hello,World’
# ls /sys/module/module_param_exam/parameters/
mystring my_visible_int
# cat /sys/module/module_param_exam/parameters/mystring
Hello,World
# cat /sys/module/module_param_exam/parameters/my_visible_int
20
# echo 2000 》 /sys/module/module_param_exam/parameters/my_visible_int
# cat /sys/module/module_param_exam/parameters/my_visible_int
2000
# echo “abc” 》 /sys/module/module_param_exam/parameters/mystring
# cat /sys/module/module_param_exam/parameters/mystring
abc
# rmmod module_param_exam
my_invisible_int = 10
my_visible_int = 2000
mystring = ‘abc’
以下为示例源码:
//filename: module-para-exam.c
#include 《linux/config.h》
#include 《linux/kernel.h》
#include 《linux/module.h》
#include 《linux/stat.h》
staTIc int my_invisible_int = 0;
staTIc int my_visible_int = 0;
staTIc char * mystring = “Hello, World”;
module_param(my_invisible_int, int, 0);
MODULE_PARM_DESC(my_invisible_int, “An invisible int under sysfs”);
module_param(my_visible_int, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
MODULE_PARM_DESC(my_visible_int, “An visible int under sysfs”);
module_param(mystring, charp, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
MODULE_PARM_DESC(mystring, “An visible string under sysfs”);
staTIc int __init exam_module_init(void)
{
printk(“my_invisible_int = %d\n”, my_invisible_int);
printk(“my_visible_int = %d\n”, my_visible_int);
printk(“mystring = ‘%s’\n”, mystring);
return 0;
}
static void __exit exam_module_exit(void)
{
printk(“my_invisible_int = %d\n”, my_invisible_int);
printk(“my_visible_int = %d\n”, my_visible_int);
printk(“mystring = ‘%s’\n”, mystring);
}
module_init(exam_module_init);
module_exit(exam_module_exit);
MODULE_AUTHOR(“Yang Yi”);
MODULE_DESCRIPTION(“A module_param example module”);
MODULE_LICENSE(“GPL”);