实验目的
编写一个内核模块,要求:
(1)编译该模块
(2)加载、卸载该模块
写内核程序需要注意:
- 内核编程时不能访问C库
- 内核编程时必须使用GUN C
- 内核编程时缺乏像用户空间那样的内存保护机制
- 内核编程时浮点数很难使用
- 内核只有一个很小的定长堆栈
- 由于内核支持异步中断、抢占SMP,因此必须时刻注意同步和并发
- 要考虑可移植性的重要性
实验记录
我的虚拟机版本Ubuntu 20.04.1 x64,内核版本5.4.0-42-generic。
首先切换到root权限,随后编写exp03.c和Makefile
exp03.c
点击查看详细内容
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
static int init_hello(void)
{
printk("Exp03_init...
");
return 0;
}
static void exit_hello(void)
{
printk("Exp03_exit...
");
}
module_init(init_hello);
module_exit(exit_hello);
MODULE_LICENSE("GPL"); //告诉内核该模块遵循GPL协议
MODULE_AUTHOR("Tea"); //模块作者
MODULE_DESCRIPTION("Linux_Exp_03"); //模块描述
MODULE_SUPPORTED_DEVICE("ExpDevice"); //模块支持的设备
Makefile
点击查看详细内容
bj-m:=exp03.o
all:
make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) clean
实验过程
执行make命令
安装内核模块exp03.ko,然后在已安装的模块中查找exp03
卸载内核模块exp03.ko,然后使用dmesg查看printk输出的内容
问题记录
1、在exp03.c中使用了printk命令打印内容,但是控制台却没有显示打印的内容
原因:
(1)查看当前控制台的打印级别
cat /proc/sys/kernel/printk
4 4 1 7
其中第一个“4”表示内核打印函数printk的打印级别,只有级别比他高的信息才能在控制台上打印出来,既 0-3级别的信息
(2)修改打印
echo "新的打印级别 4 1 7" >/proc/sys/kernel/printk
(3)不够打印级别的信息会被写到日志中可通过dmesg命令来查看
(4)printk的打印级别,在c文件中开头部分加入以下内容,如果引入了<linux/kernel.h>,就不用加入了,直接使用关键字即可
#define KERN_EMERG "<0>" /* system is unusable */
#define KERN_ALERT "<1>" /* action must be taken immediately */
#define KERN_CRIT "<2>" /* critical conditions */
#define KERN_ERR "<3>" /* error conditions */
#define KERN_WARNING "<4>" /* warning conditions */
#define KERN_NOTICE "<5>" /* normal but significant condition */
#define KERN_INFO "<6>" /* informational */
#define KERN_DEBUG "<7>" /* debug-level messages */
(5)printk函数的使用
printk(打印级别 “要打印的信息”)
打印级别:既上面定义的几个宏
解决方案1
通过命令:dmesg | grep Exp03来查看输出内容
解决方案2
在printk中加入关键字“KERN_ERR”,控制台就会输出相应的内容
printk(KERN_ERR "Exp03_init...
");