linux驱动开发详解 linux驱动开发入门与实战( 三 )


19、当参数读写权限为0时,表示该参数在sysfs文件系统中没有对应的文件节点 。如果该模块中存在参数读/写权限不为0的命令行参数,则该模块的目录下也会出现参数目录,其中包含一系列以参数名称命名的文件节点 。这些文件的权限值是传递给module_param()的参数读/写权限,以及此外,模块还可以有module_param_array(数组名、数组类型、数组长度、参数的读写权限)形式的参数数组 。
20、从0版到10版,数组长度的变量名必须赋给数组长度,从10版开始,数组长度变量的指针必须赋给数组长度,在不需要保存实际输入数组元素个数的情况下,可以设置为NULL 。当运行in *** od或modprobe命令时,应该使用逗号来分隔输入数组元素 。内核模块的符号导出该模块可以使用以下宏将符号导出到内核符号表中:EXPORT_SYMBOL(符号名);EXPORT_SYMBOL_GPL(符号名);导出的符号可以被其他模块使用,使用前声明即可 。
21、EXPORT_SYMBOL_GPL()仅适用于具有GPL许可证的模块 。下面的代码给出了一个内核模块的例子,这个内核模块派生出整数加减函数的符号(这些派生出的符号没有实际意义,只是为了演示) 。#include#includeMODULE_LICENSE("DualBSD/GPL");intadd_integar(inta,intb){returna+b;}intsub_integar(inta,intb){returna-b;}EXPORT_SYMBOL(add_integar);EXPORT_SYMBOL(sub_integar);内核模块的信息声明在Linux内核模块中,我们可以使用MODULE_AUTHOR、MODULE_DESCRIPTION、MODULE_VERSION、MODULE_DEVICE_TABLE和MODULE_ALIAS来声明模块的作者、描述、版本、设备表和别名,例如:MODULE_AUTHOR(author);MODULE_DESCRIPTION(description);MODULE_VERSION(version_string);MODULE_DEVICE_TABLE(table_info);MODULE_ALIAS(alternate_name);对于USB、PCI等设备驱动,通常会创建一个MODULE_DEVICE_TABLE 。22、内核模块的编译 *** 我们可以为代码清单1的模板编写一个简单的Makefile:你好并使用以下命令编译HelloWorld模块:make-C/usr/src/Linux-2.6.15.5/M=/driver_study/模块如果您当前位于模块所在的目录中,以下命令等效于上述命令:make–C/usr/src/Linux-2.6.15.5M=$(pwd)模块c指定Linux内核源代码的目录,M=指定hello.c和Makefile所在的目录 。编译结果如下:root@imx6:~$make-C/usr/src/linux-5/M=/driver_study/module *** ake:Enteringdirectory`/usr/src/linux-5'CC/driver_study/hello.o/driver_study/hello.c:18:35:warning:nonewlineatendoffileBuildingmodules,stageMODPOSTCC/driver_study/hello.mod.oLD/driver_study/hello.komake:Leavingdirectory`/usr/src/linux-5'可以看到,在编译过程中,有这样几个步骤:首先,进入Linux内核所在的目录,编译hello.o文件 。运行MODPOST会生成一个临时的hello.mod.c文件,然后根据这个文件编译hello.mod.o,再连接hello.o和hello.mod.o文件得到模块目标文件hello.ko,最后离开Linux内核所在的目录 。
23、示例分析现在让我们定义一个有两个参数的模块,观察模块加载和不加载时的输出 。#include#includeMODULE_LICENSE("DualBSD/GPL");staticchar*book_name="dissectingLinuxDeviceDriver";staticintnum=4000;staticintbook_init(void){printk(KERN_INFO"bookname:%sn",book_name);printk(KERN_INFO"booknum:%dn",num);return0;}staticvoidbook_exit(void){printk(KERN_INFO"Bookmoduleexitn");}module_init(book_init);module_exit(book_exit);module_param(num,int,S_IRUGO);module_param(book_name,charp,S_IRUGO);MODULE_AUTHOR("SongBaohua,author@linuxdriver.cn");MODULE_DESCRIPTION("AsimpleModulefortestingmoduleparams");MODULE_VERSION("V0");运行in *** odbook.ko命令加载上述模块,对应的输出是模块中的默认值 。您可以通过查看/var/log/messages日志文件来查看内核的输出:root@imx6:~$tail-n2/var/log/messagesJul201:03:10localhostkernel:<6>bookname:dissectingLinuxDeviceDriverJul201:03:10localhostkernel:booknum:4000当用户运行命令in *** odbook.kobook_name='goodbook'num=5000时,输出是用户传递的参数:root@imx6:~$tail-n2/var/log/messagesJul201:06:21localhostkernel:

推荐阅读