The kernel subsystem or device driver can be directly compiled into the kernel or a module. If it is compiled into the kernel, you can use the methods described in the previous section to pass parameters to the kernel startup parameters, if it is compiled into a module, you can pass parameters when inserting the module through the command line, or set or read module data through sysfs at runtime.
Sysfs is a memory-based file system. In fact, it is based on ramfs, sysfs provides a way to open the connection between the kernel data structure, their attributes, and the data structure to the user State. It is closely integrated with the kobject subsystem, therefore, the kernel developer does not need to use it directly, but the subsystems of the kernel use it. To use sysfs to read and set kernel parameters, you only need to load sysfs to read and set parameters that the kernel opens to you through sysfs through file operation applications:
# Mkdir-P/sysfs
$ Mount-T sysfs/sysfs
Note: Do not confuse sysfs with sysctl. sysctl is a control parameter of the kernel, so that you can easily control the behavior of the kernel, sysfs only opens the hierarchical relationship and attributes of the kernel's kobject object to users. Therefore, Most of sysfs are read-only, and modules are exported to sysfs as a kobject, module parameters are exported as module attributes. The kernel implementers provide a more flexible way to use modules, you can set the visibility of module parameters in sysfs and set the access permissions of these parameters under sysfs when writing a module. Then, you can view and set Module parameters through sysfs, this allows you to control module behavior during module operation.
For a module, all variables declared as static can be set through the command line, but to be visible under sysfs, the macro must be explicitly declared through the macro module_param. The macro has three parameters, the first parameter is the parameter name, that is, the defined variable name, and the second parameter is the variable type. Available types include byte, short, ushort, Int, uint, long, ulong, CHARP, bool, and invbool correspond to C-type char, short, unsigned short, Int, unsigned int, long, unsigned long, char *, and INT, respectively, you can also customize the xxx type (if you have defined param_get_xxx, param_set_xxx, and param_check_xxx ). The third parameter of the macro is used to specify the access permission. If it is set to 0, this parameter will not appear in the sysfs file system. The access permission is s_irusr, s_iwusr, s_irgrp, s_iwgrp, s_iroth and s_iwoth combinations correspond to user reading, user writing, user group reading, user group writing, other user reading, and other user writing, respectively, therefore, the access permission settings for files are consistent.
In the source code, the kernel module module-param-exam.c is an example of using the module parameters and sysfs to interact with the kernel state data. This module has three parameters that can be set through the command line. The following is an example of the running result on the author's system:
# 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'
The following is the sample source code:
//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");