操作系统课程设计(二):linux内核模块编程

一、实验目的

Linux 提供的模块机制能动态扩充 linux 功能而无需重新编译内核,已经广泛应用在 linux内核的许多功能的实现中。在本实验中将学习模块的基本概念、原理及实现技术,然后利用内核模块编程访问进程的基本信息,从而加深对进程概念的理解,掌握基本的模块编程技术

二、实验内容

(1) 设计一个模块,要求列出系统中所有内核线程的程序名、PID 号、进程状态及进程优先级。
(2) 设计一个带参数的模块,其参数为某个进程的 PID 号,该模块的功能是列出该进程的家族信息,包括父进程、兄弟进程和子进程的程序名、PID 号。
(3) 请根据自身情况,进一步阅读分析程序中用到的相关内核函数的源码实现。

三、实验步骤

实验内容一
(1) 编写模块代码(文件名module1.c)

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/sched/signal.h>

// 初始化函数
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");

(2) 编写Makefile(文件名Makefie)
这里写图片描述

(3) 编译,添加模块,并输出日志
1. make
2. insmod module1.ko pid=223 (ps,这里的进程数可以利用实验内容一读取出来的进程数,不然随便写一个数字很可能由于没有该进程从而报错)
3. dmesg
这里写图片描述

猜你喜欢

转载自blog.csdn.net/zyf2333/article/details/80043817