Linux 提供的模块机制能动态扩充 linux 功能而无需重新编译内核,已经广泛应用在 linux内核的许多功能的实现中。在本实验中将学习模块的基本概念、原理及实现技术,然后利用内核模块编程访问进程的基本信息,从而加深对进程概念的理解,掌握基本的模块编程技术
(1) 设计一个模块,要求列出系统中所有内核线程的程序名、PID 号、进程状态及进程优先级。
(2) 设计一个带参数的模块,其参数为某个进程的 PID 号,该模块的功能是列出该进程的家族信息,包括父进程、兄弟进程和子进程的程序名、PID 号。
(3) 请根据自身情况,进一步阅读分析程序中用到的相关内核函数的源码实现。
三、实验步骤
实验内容一
(1) 编写模块代码(文件名module1.c)
#include
#include
#include
#include
#include
// 初始化函数
static int hello_init(void)
{
struct task_struct *p;
printk(KERN_ALERT"名称\t进程号\t状态\t优先级\t");
for_each_process(p)
{
if(p->mm == NULL){ //内核线程的mm成员为空
printk(KERN_ALERT"%s\t%d\t%ld\t%d\n",p->comm,p->pid, p->state,p->normal_prio);
}
}
return 0;
}
// 清理函数
static void hello_exit(void)
{
printk(KERN_ALERT"goodbye!\n");
}
// 函数注册
module_init(hello_init);
module_exit(hello_exit);
// 模块许可申明
MODULE_LICENSE("GPL");
(2) 编写Makefile(文件名Makefile,下面代码中,$(MAKE)前面的是Tab,不是单纯的空格)
这个文件和module1.c写在一个文件夹内
(3) 编译,添加模块,并输出日志
1. make(如果for_each_process
报错,看看for_eache_process报错)
2. insmod module1.ko
3. dmesg
实验内容二
(1) 编写模块(文件名module2.c)
#include<linux/init.h>
#include<linux/module.h>
#include<linux/kernel.h>
#include <linux/sched.h>
#include <linux/moduleparam.h>
static pid_t pid=1;
module_param(pid,int,0644);
static int hello_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 %s\n", p->pid, p->comm);
// 父进程
if(p->parent == NULL) {
printk("No Parent\n");
}
else {
printk("Parent: %d %s\n", p->parent->pid, p->parent->comm);
}
// 兄弟进程
list_for_each(pp, &p->parent->children)
{
psibling = list_entry(pp, struct task_struct, sibling);
printk("sibling %d %s \n", psibling->pid, psibling->comm);
}
// 子进程
list_for_each(pp, &p->children)
{
psibling = list_entry(pp, struct task_struct, sibling);
printk("children %d %s \n", psibling->pid, psibling->comm);
}
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT"goodbye!\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
(3) 编译,添加模块,并输出日志
1. make
2. insmod module1.ko pid=223 (ps,这里的进程数可以利用实验内容一读取出来的进程数,不然随便写一个数字很可能由于没有该进程从而报错)
3. dmesg