第六章 统计单词个数
Linux驱动的工作和访问方式是linux的亮点之一,linux系统将每一个驱动都映射成一个文件(又称设备文件或驱动文件),使得与linux驱动交换数据就很容易变成了与设备文件交换数据。在对设备文件实施操作,例如open()函数、ioctl()函数;最后通过回调函数来进行数据的传递,而编写linux驱动最重要的一步就是编写回调函数。
6.1 编写linux驱动程序的步骤
1、建立Linux驱动框架(装载和卸载linux驱动)
module_init();装载(进行一些初始化工作)
module_exit();卸载(退出并释放由linux驱动占用的资源)
2、注册和注销设备文件
misc_register注册设备文件函数,该工作一般在第一步编写的初始化工作的函数中。
misc_deregister注销设备文件函数,该工作一般在第一步编写的退出工作的函数中。
设备文件还需要一个结构体(miscdevice)来描述与其相关的信息。miscdevice结构体中有一个重要的成员变量fops,用于描述设备文件在各种可触发事件的函数指针。该成员变量的数据类型也是一个结构体file_operations。
static struct file_operations dev_fops =
{.owner = THIS_MODULE}; THIS_MODULE表示应用于当前驱动模块
static struct miscdevice misc =
{.minor = MISC_DYNAMIC_MINOR, .name = DEVICE_NAME, .fops = &dev_fops}
3、指定与驱动相关的信息
MODULE_AUTHOR 作者姓名
MODULE_LICENSE 开源协议(最常用的5种开源协议:GPL、LGPL、BSD、Apache License 2.0协议、MIT协议)
MODULE_ALIAS 别名
MOUDLE_DESCRIPTION 驱动描述
通过modinfo命令获得驱动程序信息
4、指定回调函数
一般的write和read回调函数。word_count_read函数中主要有copy_to_user语句(将内核空间的数据复制到用户空间);word_count_write函数中主要有copy_from_user语句(将用户空间的数据复制到内核空间)
要在file_operations 结构体中添加.read和.write 。
static struct file_operations dev_fops =
{.owner = THIS_MODULE, .read = word_count_read, .write = word_count_write};
5、编写业务逻辑
根据实际情况编写的一些功能,具体的业务逻辑与驱动的功能有关,例如打印机驱动会向打印机发送打印命令。在统计单词数的例子中编写了static char is_spacewhite(char c)函数(判断指定字符是否为空格)和static int get_word_count(const char *buf)(统计单词数)
6、编写Makefile文件
Linux内核源代码的编译规则是通过Makefile文件定义的。
echo ‘obj-m := word.count.o’ > Makefile
obj-m表示将Linux驱动作为模块(.ko文件)编译,obj-y则将Linux驱动编译进Linux内核。
当第七步使用make命令会把Linux驱动源代码目录中的word_count.c或word_count.s文件编译成word.count.o文件,如果使用obj-m,word.count.o会被连接进word_count.ko文件;
使用obj-y,word.count.o会被连接进built-in.o文件,最终会被连接进内核。
7、编译Linux驱动程序
两种方式(1)直接编译进内核
(2)作为模块单独编译
8、安装和卸载Linux驱动
Insmod或modprobe装载Linux驱动模块
rmmod卸载Linux驱动模块
insmod和modprobe的区别是modprobe可以检查驱动模块的依赖性。在使用modprobe命令装载驱动模块之前,需要先使用depmod命令检测Linux驱动模块的依赖关系。
6.2 零散知识点
1、Linux系统将内存分为了用户空间和内核空间,这两个空间的程序不能直接访问。因此在Linux内核中提供了替代品,在Linux内核中的大量的c语言头文件,这些头文件中定义的函数、宏等资源就是运行在用户空间的程序的替代品。
2、在加载(insmod)完Linux驱动后,查看模块是否加成功安装
lsmod | grep word_count
查看由Linux驱动输出的日志信息
dmesg | grep word_count | tail –n 2 和 cat /var/log/syslog | grep word_count | tail –n 2