Notes13内核模块,分配设备号,驱动模块,/设备节点,设备读写
Posted 码农编程录
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Notes13内核模块,分配设备号,驱动模块,/设备节点,设备读写相关的知识,希望对你有一定的参考价值。
文章目录
1.最简单的内核模块:必须包含module.h
如下安装内核源码树目录。
如下相当于Makefile里KERNELDIR目录,其实是个软连接。
如下generic大部分指向不带generic目录下文件。
如下make后显示的第一行就是make命令。
lsmod命令就是查看/pro/modules(不是/sys/module)
里文件。/sys是一个基于RAM的FS,和 /proc差不多。/sys将各种内核子系统,硬件设备和相关设备驱动程序的信息,从内核的设备模型导出到用户空间,进而提供一组虚拟文件。而且你还可以对这些文件进行配置。比如你可以更改MAC地址。
2.内核模块参数:权限位是用在sysfs文件系统里
如下0是cnt,1-6是数组里值。
如下nums为3是插入模块时修改了3个数组里的值。
如下只读权限用S_IRUGO设置。
有时候想要在一个模块中引用另一个模块的变量或函数。
extern声明来自另一个模块。
如下insmod分先后且只能一个。
如下大写的是全局的。
如下可以判断模块能不能正常被卸载。
3.分配设备号:字符设备&块设备
linux为每个设备分配了一个设备号(分为主设备号和次设备号
,主设备号对应驱动程序,所有具有相同主设备号设备使用相同驱动程序。次设备号用来标识连接系统中相同的设备,主设备号+次设备号唯一标识链接到系统唯一设备)。如下还有Block devices块设备。
3.1 字符设备申请主设备号:三个函数,三个宏
如下f0为主设备号,f0十进制就是240。
3.2 块设备申请主设备号:hello_major为0是系统自动分配的主设备号即register_blkdev函数分配,将ret返回值赋给hello_major
如下先将模块rmmod移除再插入。
4.最简单的字符设备的驱动程序:控制外部设备都是通过读写dev下设备文件实现
hc_devp是指向hello_char_dev结构体指针,后面会给这指针分配存储空间。
如上属性,如下方法。
如下白色背景是申请字符设备的设备号。kzalloc:字符结构大小*分配个数(这里是2)。
cdev_add最后一个参数通常为1。c语言不推荐goto,但内核goto灵活。
如上初始化成功,如下查看设备号。
如上设备驱动程序已经可以工作了。但如下文件夹里没有操作接口,系统不会自动生成设备文件。
如下手动创建这两文件,和驱动中申请的字符设备对应上的。
5.驱动模块加载后自动生成设备节点:让系统udev自动生成/dev目录下的设备节点,udevadm info
linux系统中有一个后台程序udev(用来自动生成设备节点的软件),当一个设备接入到系统中时会发送一个事件到udev。udev接到这事件后就会获取这些设备信息,这些信息大部分保存在/sys/class/xx文件系统中。udev获得到这些信息后就会根据获得到的信息以及udev规则在/dev下生成对应设备节点。
如下在hello_init函数中。device_create(类指针,父类指针,设备号,设备数据,设备名称)。
make,sudo insmod hello_chr.ko,dmesg。
如下测试读写。
如下修改udev规则。
6.实现具体的设备读写:container_of、copy_to_user、copy_from_user
container_of:通过成员地址获取整个结构地址。
copy_to_user函数第二个参数是字符串地址c。
如下一个进程写没问题,但是有两进程写的话,第一个进程运行到kzalloc时,第二个进程调用了kfree,这时第一个进程执行到copy_from_user会出现问题。第一个进程运行到kzalloc时,第二个进程也执行了kzalloc,这种情况下只有第二个进程地址保存在c中,第一个进程分配的内存空间地址就丢失了,造成了内存泄漏。
以上是关于Notes13内核模块,分配设备号,驱动模块,/设备节点,设备读写的主要内容,如果未能解决你的问题,请参考以下文章
C2内核模块,分配设备号,字符驱动,/设备节点,设备读写,/同步和互斥,ioctl函数,进程休眠,时间和延时,延缓,/proc文件系统,内存分配,数据类型,/内核中断,通过IO内存访问外设