美文网首页
模块参数

模块参数

作者: 网路元素 | 来源:发表于2019-10-04 10:53 被阅读0次

    了解了内核模块、中断、定时器等内容后,我们缓一下来补充之前的一些内容和相关内容,接下来主要是了解内核态与用户态之间数据传递的机制,这次先了解内核模块参数,该部分在中断时有使用到,但未整理说明,现在补充学习下。

    那么什么是内核态和用户态呢?简单来理解,内核模块和内核就是运行在内核态,而用户程序和命令行操作等则运行在用户态,即程序运行的空间状态不一样,那么两者如何通信?本次说到的内核模块参数会感受到。 

    作为内核模块参数,我们只有将驱动代码编译成ko文件,再使用insmod和modprobe命令加载时才会使用到(也可在加载模块后在/sys里修改),而一旦将其编译进内核,那么我们会使用到内核启动参数,这个后期再说明。

    include/linux/moduleparam.h文件里有关于内核模块参数的定义,而我们常用到的宏有如下:

    #define module_param(name, type, perm) \
            module_param_named(name, name, type, perm)

    #define module_param_array(name, type, nump, perm) \
            module_param_array_named(name, name, type, nump, perm)

    #define MODULE_PARM_DESC(_parm, desc) \
            __MODULE_INFO(parm, _parm, #_parm ":" desc)

    其中module_param 和module_param_array是定义相关参数时使用,而 MODULE_PARM_DESC仅仅是对参数进行描述,说明该参数的作用,上述宏的相关参数说明如下: 

    1.name与_parm是参数名;
    2.type:参数的类型,可使用的类型如下: byte, short, ushort, int, uint, long, ulong charp: a character pointer bool: a bool, values 0/1, y/n, Y/N. invbool: the above, only sense-reversed (N = true).
    3.perm:在include/uapi/linux/stat.h文件中有如下宏:

    #define S_IRWXU 00700
    #define S_IRUSR 00400
    #define S_IWUSR 00200
    #define S_IXUSR 00100
    #define S_IRWXG 00070
    #define S_IRGRP 00040
    #define S_IWGRP 00020
    #define S_IXGRP 00010
    #define S_IRWXO 00007
    #define S_IROTH 00004
    #define S_IWOTH 00002
    #define S_IXOTH 00001

    一般可使用其中一个或几个进行“或”操作的组合,但我们更常用8进制数来表示(如0644,0777等),如果该值为0,则在/sys下不会有相应的参数结点存在。
    4.nump:数组参数的大小;
    5.desc:参数描述字符串。 

    接下来我们看一例:

    #include <linux/init.h>
    #include <linux/module.h>
    #include <linux/moduleparam.h>

    static int int_param = 1;
    static int arr[] = {1,2,3,4,5,6};

    static int n = ARRAY_SIZE(arr);

    module_param(int_param, int, 0644);
    MODULE_PARM_DESC(int_param, "integer type parameter");

    module_param_array(arr, int, &n, 0644);
    MODULE_PARM_DESC(arr, "integer type array parameter");

    static __init int param_init(void)
    {
            int i;
            printk("Hello param!\n");
            printk("int_param=%d\n", int_param);

            for(i = 0; i < n; i++)
            {
                    printk("arr[%d] = %d\n", i, arr[i]);
            }

            return 0;
    }

    static __exit void param_exit(void)
    {
            printk("Bye param!\n");
    }

    module_init(param_init);
    module_exit(param_exit);
    MODULE_LICENSE("GPL");

    相应的Makefile如下:

    obj-m += module_param_exam.o

    CUR_PATH:=$(shell pwd)
    LINUX_KERNEL_PATH:=/home/xinu/linux-3.13.6

    all:
            make -C $(LINUX_KERNEL_PATH) M=$(CUR_PATH) modules

    clean:
            make -C $(LINUX_KERNEL_PATH) M=$(CUR_PATH) clean

    相应的源码文件目录树如下: 

    /home/xinu/xinu/linux_kernel_driver_l1/module_param_exam/
    ├── Makefile
    └── module_param_exam.c 

    从源码里可以看到在使用内核参数前需先定义变量,再使用module_param等宏来说明该变量作为参数使用。而make后如何加载呢?由于源码里的变量都有初始化,故而有如下形式: 

    sudo insmod module_param_exam.ko
    sudo insmod module_param_exam.ko int_param=2
    sudo insmod module_param_exam.ko arr=2,3,4,5,6,7
    sudo insmod module_param_exam.ko int_param=2 arr=3,4,5,6,7,8 

    那如果我们不知道模块文件有没有相关参数,该怎么办呢?可以找modinfo命令帮忙,我们的模块使用该命令有如下内容输出(重新整理的资料,下面排版可能跟实际有区别,请按实际来): 

    xinu@slam:~/xinu/linux_kernel_driver_l1/module_param_exam$ modinfo module_param_exam.ko
    filename: /home/xinu/xinu/linux_kernel_driver_l1/module_param_exam/module_param_exam.ko
    license: GPL
    srcversion: 09B84A711F0A86613CC18D8
    depends: vermagic: 3.13.6 SMP mod_unload modversions
    parm:
    int_param:integer type parameter (int) parm:
    arr:integer type array parameter (array of int) 

    还有,模块加载后,我们可在/sys目录查找相关结点,获得参数的值,以我们本例有如下内容: 

    xinu@slam:~/xinu/$ ls -l /sys/module/module_param_exam/parameters/
    total 0
    -rw-r–r– 1 root root 4096 Apr 28 18:15 arr
    -rw-r–r– 1 root root 4096 Apr 28 18:15 int_param
    xinu@slam:~/xinu/$ cat /sys/module/module_param_exam/parameters/int_param
    1
    xinu@slam:~/xinu/$ cat /sys/module/module_param_exam/parameters/arr
    1,2,3,4,5,6 

    至此,我们对内核模块参数加载了解了,这几天将继续说明内核态与用户态数据传递的其他方式。 

    参考网址: 

    http://blog.csdn.net/yao_guet/article/details/6542054
    http://www.ibm.com/developerworks/cn/linux/l-kerns-usrs/index.html
    http://www.embeddedlinux.org.cn/html/yingjianqudong/201304/17-2548.html

    相关文章

      网友评论

          本文标题:模块参数

          本文链接:https://www.haomeiwen.com/subject/yyblyctx.html