实验题目:linux内核编模块编程

本文介绍了两个具体的Linux内核模块编程案例。第一个案例展示了如何列出系统中所有内核线程的基本信息,如程序名、PID号等。第二个案例则通过指定PID号来展示特定进程及其家族成员的详细信息。

 

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

 

  1. 分析程序运行结果

insmod moduleone.ko

dmesg

rmmod moduleone

dmesg

第(1)小题运行结果

insmod module_two.ko pid=10

dmesg

rmmod module_two

dmesg

 

第(2)小题运行结果

  1. 程序完整代码

实验(1)代码:

#include<linux/init.h>

#include<linux/module.h>

#include<linux/kernel.h>

#include <linux/sched.h>

#include<linux/sched/signal.h>

static int moduleone_init(void)

{

        struct task_struct *p;

        printk(KERN_ALERT"Name \t\t PID \t State \t Prio\t");

        for_each_process(p)

        {

                if(p->mm == NULL)

                  printk(KERN_ALERT"%s\t%d\t%d\t%d\n",p->comm,p->pid, p->state,p->static_prio);

        }

        return 0;

}

static void moduleone_exit(void)

{

        printk(KERN_ALERT "MooduleOne has exit  successfully!\n");

}

module_init(moduleone_init);

module_exit(moduleone_exit);

MODULE_LICENSE("GPL");

实验(1makefile文件:

obj-m:=moduleone.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

实验(2)代码:
#include <linux/init.h>

#include <linux/module.h>

#include <linux/kernel.h>

#include <linux/sched.h>

#include <linux/moduleparam.h>

 

static pid_t pid;

module_param(pid,int,0644);

 

static int module_two_init(void)

{

    struct task_struct *p;

    struct list_head *pp;

    struct task_struct *psibling;

 

     p = pid_task(find_vpid(pid), PIDTYPE_PID);//根据pid值,找到task

    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)//遍历p的父亲节点的孩子节点(p的兄弟节点)

    {

         psibling=list_entry(pp,struct task_struct,sibling);

         printk("sibling %d %s \n",psibling->pid,psibling->comm);

    }

    list_for_each(pp,&p->children)//遍历p的孩子节点

    {

         psibling=list_entry(pp,struct task_struct,sibling);

            printk("children %d %s \n",psibling->pid,psibling->comm);

    }

        return 0;

}

static void module_two_exit(void)

{

        printk(KERN_ALERT "ModuleTwo has exit successfully!\n");

}

module_init(module_two_init);

module_exit(module_two_exit);

MODULE_LICENSE("GPL");

 

实验(2makefile文件:
obj-m:=module_two.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

 

实验linux 内核译及添加系统调用 设计目的 Linux 是开源操作系统,用户可以根据自身系统需要裁剪、修改内核,定制出功能更加 合适、运行效率更高的系统,因此,linux 内核是进行内核开发的必要基本功。 在系统中根据需要添加新的系统调用是修改内核的一种常用手段,通过本次实验,读 者应理解 linux 系统处理系统调用的流以及增加系统调用的方法。 内容要求 (1) 添加一个系统调用,实现对指定进程的 nice 值的修改或读取功能,并返回进程最 新的 nice 值及优先级 prio。建议调用原型为: int mysetnice(pid_t pid, int flag, int nicevalue, void __user * prio, void __user * nice); 参数含义: pid:进程 ID。 flag:若值为 0,表示读取 nice 值;若值为 1,表示修改 nice 值。 Prio、nice:进程当前优先级及 nice 值。 返回值:系统调用成功时返回 0,失败时返回错误码 EFAULT。 (2) 写一个简单的应用序测试(1)中添加的系统调用。 (3) 若序中调用了 linux内核函数,要求深入阅读相关函数源码。 实验linux 内核模块编程 设计目的 Linux 提供的模块机制能动态扩充 linux 功能而无需重新内核,已经广泛应用在 linux 内核的许多功能的实现中。在本实验中将学习模块的基本概念、原理及实现技术,然后利 用内核模块编程访问进程的基本信息,从而加深对进程概念的理解、对模块编程技术的掌 握。 内容要求 (1) 设计一个模块,要求列出系统中所有内核线序名、PID 进程状态及 进程优先级。 (2) 设计一个带参数模块,其参数为某个进程PID ,该模块功能列出进程的家族信息,包括父进程兄弟进程和子进程序名、PID 。 (3) 请根据自身情况,进一步阅读分析序中用到的相关内核函数的源码实现。 实验linux 进程管理 设计目的 (1) 熟悉 linux 的命令接口。 (2) 通过对 linux 进程控制的相关系统调用的编程应用,进一步加深对进程概念的理解, 明确进程序的联系和区别,理解进程并发执行的具体含义。 (3) 通过 Linux 管道通信机制、消息队列通信机制、共享内存通信机制的使用,加深 对不同类型的进程通信方式的理解。 (4) 通过对 linux 的 Posix 信量的应用,加深对信量同步机制的理解。 (5)请根据自身情况,进一步阅读分析相关系统调用的内核源码实现。 设计内容 (1)熟悉 linux 常用命令:pwd,useradd,passwd, who, ps, pstree, kill, top, ls, cd, mkdir, rmdir, cp, rm, mv, cat, more, grep 等。 (2) 实现一个模拟的 shell: 写三个不同的序 cmd1.c,cmd2.c,cmd3.c,每个序的功能自定,分别译成可执 行文件 cmd1,cmd2,cmd3。然后再一个序,模拟 shell 序的功能,能根据用户输 入的字符串(表示相应的命令名),去为相应的命令创建子进程并让它去执行相应的序,而父进程则等待子进程结束,然后再等待接收下一条命令。如果接收到的命令为 exit,则父 进程结束;如果接收到的命令是无效命令,则显示“Command not found”,继续等待。 (3) 实现一个管道通信: 由父进程创建一个管道,然后再创建 3 个子进程,并由这三个子进程利用管道与父进程 之间进行通信:进程发送信息,父进程等三个子进程全部发完消息后再接收信息。通信的 具体内容可根据自己的需要随意设计,要求能试验阻塞型读写过中的各种情况,测试管道 的默认大小,并且要求利用 Posix 信量机制实现进程间对管道的互斥访问。运行序,观 察各种情况下,进程实际读写的字节数以及进程阻塞唤醒的情况。 (4) 利用 linux 的消息队列通信机制实现两个线间的通信: 序创建两个线:sender 线和 receive 线,其中 sender 线运行函数 sender(), 它创建一个消息队列,然后,循环等待用户通过终端输入一串字符,将这串字符通过消息队 列发送给 receiver 线,直到用户输入“exit”为止;最后,它向 receiver 线发送消息“end”, 并且等待 receiver 的应答,等到应答消息后,将接收到的应答信息显示在终端屏幕上,删除 相关消息队列,结束序的运行。Receiver 线运行 rece
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值