本实验通过编写Linux内核模块,加载内核模块,并测试结果,了解Linux内核模块的概念、编译方法、安装和测试方法。
任务描述- Linux 内核模块的基本概念
- Linux 内核模块的编写方法
- Linux 内核模块的加载和移除
- Linux内核模块的测试方法
- 学习掌握Linux 内核模块的编写
- 学习掌握Linux 内核模块的加载和移除
- 学习掌握测试Linux内核模块
a.切换至home目录(该目录初始应该是空目录)下输入“mkdir hello”新建hello文件,“cd hello”进入hello文件。
b.输入"vim myhello.c",输入以下代码
#include#include #include static int hello_init(void) { printk(KERN_ALERT"hello,wordn"); return 0; } static void hello_exit(void) { printk(KERN_ALERT"goodbyen"); } module_init(hello_init); module_exit(hello_exit); MODULE_LICENSE("GPL");
保存并退出(“esc”退出编辑模式,“:wq”保存并退出)
c.输入"vim Makefile",输入以下代码
obj-m :=hello.o
hello-objs:=myhello.o
KDIR :=/lib/modules/$(shell uname -r)/build
PWD :=$(shell pwd)
default:
make -C $(KDIR) M=$(PWD) modules//make前面为Tab,并不是空格,直接复制需要改下
clean:
make -C $(KDIR) M=$(PWD) clean
保存并退出(“esc”退出编辑模式,“:wq”保存并退出)
d.输入“make”,进行模块编译,如果报错很可能是代码格式问题,请仔细检查,一段代码前不是空格(直接“CV大法”导致的后果)
e.输入“insmod hello.ko”,加载模块
f.输入"dmesg",查看
g.输入“rmmod hello”,卸载模块
a.切换至home目录下输入“mkdir test1”新建test1文件,“cd test1”进入test1文件。
b.输入"vim module1.c",输入以下代码
#include#include #include #include #include static pid_t pid=1; module_param(pid, int, 0644); static int module1_init(void) { struct task_struct *p; struct list_head *pp; struct task_struct *psibling; //当前进程的PID p = pid_task(find_vpid(pid),PIDTYPE_PID); printk("me: %d %ld %s n",p->pid,p->state,p->comm); //父进程 if(p->parent == NULL){ printk("No Parentn"); } else{ printk("Parent:%d %ld %s n",p->parent->pid,p->parent->state,p->parent->comm); } //兄弟进程 list_for_each(pp,&p->parent->children) { psibling = list_entry(pp,struct task_struct,sibling); printk("Brother %d %ld %s n",psibling->pid,psibling->state,psibling->comm); } //子进程 list_for_each(pp,&p->children) { psibling = list_entry(pp,struct task_struct,sibling); printk("Children %d %ld %s n",psibling->pid,psibling->state,psibling->comm); } return 0; } static void module1_exit(void) { printk(KERN_ALERT"goodbye!n"); } module_init(module1_init); module_exit(module1_exit); MODULE_LICENSE("GPL");
保存并退出(“esc”退出编辑模式,“:wq”保存并退出)
c.输入"vim Makefile",输入以下代码
obj-m := module1.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
make -C $(KDIR) M=$(PWD) modules
clean:
make -C $(KDIR) M=$(PWD) clean
保存并退出(“esc”退出编辑模式,“:wq”保存并退出)
d.输入“make”,进行模块编译,如果报错很可能是代码格式问题,请仔细检查,一段代码前不是空格(直接CV导致的后果)
e.输入“insmod module1.ko pid=4”,加载模块
f.输入"dmesg",查看
g.输入“rmmod module1”,卸载模块
a.切换至home目录下输入“mkdir test2”新建test2文件,“cd test2”进入test2文件。
b.输入"vim module2.c",输入以下代码
#include#include #include #include // 初始化函数 static int hello_init(void) { printk("sysname:%s n version:%s",utsname()->sysname,utsname()->version); return 0; } // 清理函数 static void hello_exit(void) { printk("goodbye!n"); } module_init(hello_init); module_exit(hello_exit); MODULE_LICENSE("GPL");
保存并退出(“esc”退出编辑模式,“:wq”保存并退出)
c.输入"vim Makefile",输入以下代码
obj-m := module2.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
make -C $(KDIR) M=$(PWD) modules
clean:
make -C $(KDIR) M=$(PWD) clean
保存并退出(“esc”退出编辑模式,“:wq”保存并退出)
d.输入“make”,进行模块编译
e.输入“insmod module2.ko”,加载模块
f.输入"dmesg",查看
这个地方并没有出现我们想要的结果,先别急
g.输入“rmmod module2”,卸载模块,再次输入“dmesg”
卸载模块后结果就出来啦!!!
a.切换至home目录下输入“mkdir test3”新建test3文件,“cd test3”进入test3文件。
b.输入"vim dmodule3.c",输入以下代码
#include#include #include #include #include MODULE_LICENSE("GPL"); static pid_t pid=1; static int nice; module_param(pid,int,0644); module_param(nice,int,0644); // 初始化函数 static int hello_init(void) { struct task_struct *p; p = pid_task(find_vpid(pid),PIDTYPE_PID); printk("当前进程的pid:%d nice:%d ",p->pid,task_nice(p)); if(nice!=0) { set_user_nice(p,nice); printk("当前进程修改后的pid:%d nice:%d ",p->pid,task_nice(p)); } return 0; } // 清理函数 static void hello_exit(void) { printk("goodbye!n"); } module_init(hello_init); module_exit(hello_exit);
保存并退出(“esc”退出编辑模式,“:wq”保存并退出)
c.输入"vim Makefile",输入以下代码
obj-m := dmodule3.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
make -C $(KDIR) M=$(PWD) modules
clean:
make -C $(KDIR) M=$(PWD) clean
保存并退出(“esc”退出编辑模式,“:wq”保存并退出)
d.输入“make”,进行模块编译
e.输入“ps -l”,查看当前的进程
f.输入“insmod dmodule3.ko pid=2297 nice=5”(根据查看得到的pid值进行相应赋值),加载模块
g.输入"dmesg",查看
这个地方也没有出现我们想要的结果,先别急
h.输入“rmmod dmodule3”,卸载模块,再次输入“dmesg”
i.输入“ps -l”,再次查看,发现nice值已被修改
(PS:截止本篇完成时间为为止,博主还是有些问题没有解决,比如打印名称和版本这个实验,我们将打印放在初始函数中,但是加载模块后,日志中并没有出现信息,名称和版本的信息是在移除模块之后才在日志中出现,修改nice值实验也同样存在这个问题,希望有知道解决办法或其背后原因的小伙伴在评论区评论)
文章写作时间仓促,如有错误请指正,如有问题请在评论区中提问。
加油!



