1添加最简单的Linux内核模块

1添加最简单的Linux内核模块

一.实验目的

1 熟练掌握基本的Linux内核模块开发框架和编译方法。
2 熟练掌握Linux内核模块添加流程。
3 理解Linux内核模块代码中的一些常见宏和参数。
4 掌握Linux内核模块程序和应用程序的差异。

二.实验背景

2.1用户态与内核态

图1.1 用户态与内核态关系示意图 图1.1 用户态与内核态关系示意图

2.2Linux内核模块LKM (Linux Kernel Module)

1)Linux是单内核多模块的操作系统
·两种开发内核模块的方法
·静态开发
·LKM

2)LKM具有如下特点:
·主要使用C语言编程,但也可以使用内联的汇编代码;
·LKM工作在内核空间,可以不受约束的运行,因此在一个LKM内部读者可以访问对应用程序屏蔽的内核数据结构、硬件设备等;
·LKM可以通过proc伪文件系统、内存映射、特定的系统调用函数等不同的机制实现内核空间和用户空间的数据交换。

三.关键代码及分析

实验1:添加最简单的内核模块kello

1.Kello.c
在这里插入图片描述

linux/module.h路径:/lib/modules/4.4.0-142-generic/build/include/linux
在这里插入图片描述
在这里插入图片描述在这里插入图片描述

1)任何一个内核模块文件必须要有两个模块管理函数,即模块初始化函数和模块回收函数,其原型如下所示:
int init_module( void ); // 模块初始化函数,在模块初始化时被调用
void cleanup_module( void ); //模块回收函数,在模块撤销时调用
2)为了模块更高效地被加载、执行和撤销,尤其是内存的分配和回收,在文件最后需要作如下声明:
module_init(init_module); //执行模块初始化函数
module_exit(cleanup_module); //执行模块回收函数

2.Makefile

在这里插入图片描述

在上述Makefile文件中KERNELRELEASE是在Linux内核源代码顶层Makelile中定义的一个变量,在第一次读取执行此 Makefile文件时,KERNELRELEASE没有被定义,所以make将读取执行else之后的内容。
如果make的目标是clean. 直接执行clean操作,然后结束。当没有声明make的目标时,make执行默认操作,即default 后的指令,此时-C $ (KDIR)指明跳转到内核源代码目染下读取那里的Makefiles SUBDIRS $ (PWD) 表明需要返回到当前目录继续读人、执行当前的Makefile.当从内核源代码目录返回时, KERNELRELEASE已被定义,kbuild也被启动去解析kbuild语法的语句,make将继续读取else之前的内容。

实验2:内核模块输出信息显示

·Linux内核定义的0~7总计8个日志级别时间,分别是:
static char * log_level[] = {
“KERN_EMERG”,
“KERN_ALERT”,
“KERN_CRIT”,
“KERN_ERR”,
“KERN_WARNING”,
“KERN_NOTICE”,
“KERN_INFO”,
“KERN_DEBUG”
};
其中KERN_EMERG为0,表示等级最高。如果在调用printk时使用该日志级别,则信息可以直接显示在文本控制台。
语法格式:
printk( “<0> Hello, students from SDUST! This is in kernel space! \n" );
或则:
printk( KERN_EMERG “\n Hello, students from SDUST! This is in kernel space! \n” );

1.kello.c
在这里插入图片描述
2.Makefile和实验1一样
在这里插入图片描述

四.实验结果与分析

实验1:添加最简单的内核模块kello

1.kello.c的编译

·make

在这里插入图片描述

生成两个文件,一个是kello.ko,一个是modules.order。打开modules.order文件可以看到其内容为kernel//home/wct/os/ch12/kello.ko,其中kernel表明这是内核模块,//后的字符串指明了内核模块的位置。

在这里插入图片描述

2.LKM的添加和删除

添加和撤销LKM模块都需要root权限。在运行时需要在命令前面加sudo命令来执行。添加和撤销LKM模块的命令分别是insmod和rmmod

1)insmod添加
在这里插入图片描述

·查看内核日志中的信息(dmesg)

模块初始化成功后日志写入 Hello, students from SDUST! This is in kernel space!
在这里插入图片描述

·通过lsmod命令查看linux中已经加载的模块信息
在这里插入图片描述

2)rmmod撤销

在这里插入图片描述
·查看日志
在这里插入图片描述

撤销成功后日志中写入了 Goodbye now… students from SDUST!

实验2:内核模块输出信息显示

1.kello.c的编译

·make
在这里插入图片描述

由于某些Linux系统只能在命令行界面显示内核信息。可用Ctrl+Alt+F1 和 Ctrl+Alt+F7 实现图形界面和命令行界面之间的切换。

1)insmod添加
在这里插入图片描述

2)rmmod撤销
在这里插入图片描述
由于日志设置的是最高等级所以在命令行界面直接显示了内核信息。

3)dmesg查看日志
在这里插入图片描述

练习:

在这里插入图片描述

12-1:
在这里插入图片描述
这样定义KDIR和PWD不用手动的写出系统的发行号和当前路径,执行是自动获取,使得程序换了路径和系统后不用修改也能正常执行。

12-2:
linux/module.h路径:/lib/modules/4.4.0-142-generic/build/include/linux
在这里插入图片描述·MODULE_DESCRIPTION(); // 描述模块的功能

12-3:显示位置信息
在这里插入图片描述
__FILE__表示源代码文件的名称,以绝对路径的方式表示;__LINE__表示行,即printk在这个源代码文件中的第几行,给出了调测点具体观察位置的信息;FUNCYION,表示处在哪个函数中。
在这里插入图片描述

12-4:
在这里插入图片描述
在这里插入图片描述
因为kello_init()为模块的初始化,按照约应当返回0是表示初始化成功,而此处返回了1他会认为是可疑的。但是模块添加到了内核中。

发布了170 篇原创文章 · 获赞 9 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/wct3344142/article/details/104132737