实验目的
- 熟练掌握基本的Linux内核模块开发框架和编译方法。
- 熟练掌握Linux内核模块添加流程。
- 理解Linux内核模块代码中的一些常见宏和参数。
- 掌握Linux内核模块程序和应用程序的差异。
- 深入理解操作系统为用户提供服务的方式、方法
- 深入理解计算机程序的运行方式
实验要求
- 通过阅读、执行kello.c及其对应的Makefile文件,理解Linux内核模块LKM的基本框架和运行方式、原理。
- 对比kello.c和应用程序hello.c在编写、运行过程中的差异,理解操作系统为用户提供服务的方式、方法。
- 结合操作系统知识,通过实验深入理解计算机程序在操作系统支持下的运行方式。
实验原理及背景
- 用户态与内核态
- 应用程序调用操作系统服务完成特定功能
- 操作系统为应用程序提供服务
- 应用程序工作在用户空间,为用户态
- 操作系统模块工作在内核空间,为内核态
- LKM
- Linux是单内核多模块的操作系统
- 两种开发内核模块的方法
- 静态开发
- LKM
- LKM具有如下特点:
- 主要使用C语言编程,但也可以使用内联的汇编代码;
- LKM工作在内核空间,可以不受约束的运行,因此在一个LKM内部读者可以访问对应用程序屏蔽的内核数据结构、硬件设备等;
- LKM可以通过proc伪文件系统、内存映射、特定的系统调用函数等不同的机制实现内核空间和用户空间的数据交换。
- Linux是单内核多模块的操作系统
实验内容
- 从教材提供的电子资源中找到或者按教材提示自己编写简单的Linux内核模块kello.c及其对应的Makefile文件
///kello.c
#include<linux/module.h>
int hello_init(void)
{
printk("\n Hello,XXX.This is in kernel space!\n");
return 0;
}
void hello_exit(void)
{
printk("\n Goodbye,XXX! \n");
}
MODULE_AUTHOR("SDUSTOS<vircorns@163.com>");
MODULE_LICENSE("GPL");
module_init(hello_init);
module_exit(hello_exit);
ifneq ($(KERNELRELEASE),)
obj-m :=kello.o
else
KDIR :=/lib/modules/$(shell uname -r)/build
PWD :=$(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
rm -r -f .tmp_versions *.mod.c .*.cmd *.o *.symvers
endif
- 编译、安装、删除该模块,查看该模块的安装位置、运行情况
- 本次采用单独编译、动态插入内核;把将开发的内核代码文件直接进行编译,然后使用命令动态插入内核或者从内核卸载。
- 优点:编译速度快;单独调试代码
- 缺点:每次系统启动后都需要再加载代码
- dmesg后显示
- 删除模块
sudo rmmod kello.ko
- 显示
实验拓展
///kello.c
#include<linux/module.h>
int hello_init(void)
{
printk("\n Hello,XXX.This is in kernel space!\n");
printk(KERN_EMERG "\n Hello, SDUST\n");//test2
printk(KERN_DEBUG "We are here : %s : %d at %s()\n", __FILE__,__LINE__,__FUNCTION__);//homework3
return 0;
}
void hello_exit(void)
{
printk("\n Goodbye,XXX! \n");
}
MODULE_AUTHOR("SDUSTOS<vircorns@163.com>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("This is a smiple program");//homework2
module_init(hello_init);
module_exit(hello_exit);
-
拓展一:printk和某些常见宏
- 代码:
printk(KERN_EMERG "\n Hello, SDUST\n");//test2
- 输出:
- 代码:
-
作业12-1:
-
用Shell定义KDIR和PWD的好处:
- 用shell指令获得linux内核路径,适应不同电脑不同版本的linux内核
- 当程序路径更改时,系统无需修改也能正常执行
-
作业12-2:
- 代码:
MODULE_DESCRIPTION("This is a smiple program");
- 其中
MODULE_DESCRIPTION()
意思为描述模块的功能等
- 代码:
-
作业12-3:
- 代码:
printk(KERN_DEBUG "We are here : %s : %d at %s()\n", __FILE__,__LINE__,__FUNCTION__);//homework3
- 运行后截图:
- 代码:
-
作业12-4
return 1
后运行结果如下:代- 分析原因:按照约应当返回0是表示初始化成功,而此处返回了1,即认为是错误,这是一个报错代码