Linux编写内核模块,实现在/sys目录下添加文件

sysfs是一种基于内存的虚拟文件系统,该文件系统将内核信息以文件的方式提供给用户程序使用,可以更方便地对系统设备进行管理。sysfs把连接在系统上的设备和总线组织成为一个分级的文件,由用户空间存取,并能向用户空间导出内核的数据结构以及它们的属性。其目录结果如下图所示。
在这里插入图片描述

现编写一个内核模块,在/sysfs文件系统中增加一个目录hello,并在这个目录中增加一个文件world,文件的内容为hello world。

实验环境

Ubuntu 18.04.1,源码内核版本:Linux-4.2.6

创建目录

sysfs内核官方文档中给出了sysfs文件系统的具体描述。

参照文档可知,sysfs会为每个注册在系统中的kobject对象创建一个目录,该目录是kobj对象的父对象的子目录,顶层的目录是所有其他对象的共同祖先。据此可知,创建一个kobj对象并将其注册在系统中后,即可在sys目录下生成一个子目录。
在这里插入图片描述
其中,创建目录的函数为kobject_init_and_add,该函数在初始化kobject对象后将其添加至kobjects构成的层级中(即添加至目录),其原型为:

int kobject_init_and_add (struct kobject * kobj,struct kobj_type * ktype,struct kobject * parent,const char * fmt,...);

函数的第一个参数为指向该目录的kobj指针,第二个参数是该kobj指针的类型,第三个参数是该指针的父指针,由于本实验是在sys顶层目录下创建新目录,因此该值为NULL,第四个参数为创建的目录的名称。

创建文件

同样参考上述官方文档可知,sysfs系统为Attributes结构体提供I/O接口以将Attributes映射为文件,因此没有直接创建文件的函数。该映射通过将kobject的ktype成员设置为自定义的my_type来完成:
在这里插入图片描述
在my_type的结构体中,release成员用于释放kobj对象,该操作可避免潜在的内存泄漏;default_attrs成员指定了该文件的Attr结构体,其name成员为“world”,即创建的文件名,并设置其拥有读写权限;sysfs_ops成员指定了要创建的文件的操作,由于在本实验中只需显示文件内容,因此只定义了show函数,其实现如下:
在这里插入图片描述
至此,便完成了该实验的大体框架。

结果

在这里插入图片描述

运行与验证

使用make命令编译模块,再使用sudo insmod sys_hello.ko命令安装模块,如下图所示。
在这里插入图片描述
再切换至/sys目录,即可看到上述结果。
此外,也可通过rmmod命令卸载该模块,由图可知,卸载模块后/sys/目录下已经没有hello目录了,这体现出模块可以在内核运行时动态插入和删除的特点。
在这里插入图片描述
完整实现代码已上传至我的github

参考资料

[1] Robert Love, Robert Love. Linux内核设计与实现(原书第3版)[M].陈莉君,译.机械工业出版社,2011
[2] Daniel P. Bovet, Marco Cesati. 深入理解LINUX内核(第三版)[M].陈莉君,张琼声,张宏伟,译.中国电力出版社,2007
[3] https://www.jianshu.com/p/a6c33bf39067 编译安装 Linux 内核并添加系统调用
[4] https://www.kernel.org/doc/Documentation/filesystems/sysfs.txt
[5] https://www.linuxtv.org/downloads/v4l-dvb-internals/device-drivers/API-kobject-init-and-add.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章