Linux课程设计
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Linux课程设计---编写proc文件系统相关的内核模块
学号:********
姓名:**
班级:08级网络一班
指导教师:**
日期:2011年6月29号
一、背景知识:
1、内核模块。
操作系统采用两种体系结构:微内核(Micro kernel),最常用的功能模块被设计成内核模式运行的一个或一组进程,而其它大部分不十分重要的功能模块都作为单独的进程在用户模式下运行!单内核(Monolithic kernel,有时也叫宏内核Macro kernel)!内核一般作为一个大进程的方式存在。该进程内部又可以被分为若干模块,在运行的时候,它是一个独立的二进制映象为了弥补单一体系结构的这一缺陷,Linux操作系统使用了模块机制。用户可以根据需要,在不需要对内核重新编译的情况下,模块可以动态地载入内核或从内核中移出!如图所示,模块可通过 insmod命令插入内核,也可以通过rmmod命令从内核中删除。
2、进程管理
Linux的每一个进程都有自己的属性,用一个task struct数据结构表示,即进程控制块Ⅲ(Process Concrol Block,PCB)。它对进程在其生命周期内涉及的所有事件进行全面的描述,主要有进程标识符(PID)、进程状态信息、进程调度信息、进程所占的内存区域、相关文件的文件描述符、处理器环境信息、信号处理、Linux操作系统内核分析与研究资源安排、同步处理等几个方面。在一个系统中,通常可拥有数百个甚至数千个进程,相应地就有很多进程控
制块。为了有效地对它们加以管理,应该用适当地方式将这些进程控制块组织起来。
进程控制块数据结构主要域定义如下:
task_struct结构:在linux/sched.h中
struct task_struct{
volatile long state;
//系统进程状态,一共有五种状态:
//0 可运行态
//1 可中断的等待态
//2 不可中断的等待态
//3 僵死态
//4 暂停态
struct list_head tasks;
struct mm_struct *mm;
pid_t pid; //进程号
pid_t tpid; //进程组号
struct task_struct *real_parent; //真正的父进程指针
struct task_struct *parent; //父进程指针
struct list_head children; //孩子进程指针
struct list_head sibling; //兄弟进程指针
char comm.[TASK_COMM_LEN]; //进程名
};
struct list_head结构:在Linux/list.h
struct list_head{
struct list_head *next,*prev;
};
pid_task(find_get_pid(pid),PIDTYPE_PID) //找进程号为pid的进程for_each_process //内核专门提供的宏,用来访问链表的每个进程list_for_each_entry //内核专门提供的宏,用来遍历链表
二、实验内容:
1、实验目的:
通过本次实验,达到掌握模块的加载,删除,以及运用的目的!!!
2、实验要求:
设计一个模块,该模块功能是列出系统中所有内核线程的程序名、PID 号和进程状态。再设计一个带参数的模块,参数为进程的PID号,功能是列出进程的家族信息,包括父进程、兄弟进程和子进程的程序名、PID号。
3、程序代码:
这个程序放在了/桌面/dusen/文件夹里;参照课本十三章例题框架进行设计;其中在文件夹dusen里有建了dusen1,dusen2 两个目录;dusen1里的dusen1.c 是程序的主要实现方法;dusen2是对dusen1的主要方法的调用!!!
dusen1.c的代码
#include
#include
#include
#include
MODULE_LICENSE("GPL"); //声明许可证
GPL
static int mod_init_dusen(void); //声明函数
static void mod_exit_dusen(void);
module_init(mod_init_dusen); //指定模块初始化函数
module_exit(mod_exit_dusen); //指定模块退出函数
void dusen(void); //定义要求的无参数函数
void dusen_para(int pid); //定义要求的带参数函数
void dusen(void)
{
struct task_struct *p,*t;
printk("所有内核进程信息:\n");
for_each_process(p)
{
printk("NAME: %s PID: %d STATE:%ld\n",p->comm,p->pid,p->state);
t=list_entry(&p->children,struct task_struct,children);
}
}
void dusen_para(int pid1)
{
pid_t pid=pid1;
struct task_struct *p1,*p2;
p1=pid_task(find_get_pid(pid),PIDTYPE_PID);
if(p1)
{
printk("这是您找的进程NAME:%s PID:%d STATE:%ld\n",p1->comm,p1->pid,p1->state);
p2=p1->parent;
printk(" parent NAME:%s PID:%d STATE:%ld\n",p2->comm,p2->pid,p2->state);
list_for_each_entry(p2, &p1->real_parent->children, sibling)
{
printk(" brother NAME:%s PID:%d STATE:%ld\n",p2->comm,p2->pid,p2->state);
}
list_for_each_entry(p2, &p1->children, sibling)
{
printk(" children NAME:%s PID:%d STATE:%ld\n",p2->comm,p2->pid,p2->state);
}
}
else
{
printk("no proccess\n");
}
}
EXPORT_SYMBOL(dusen); //导出函数
EXPORT_SYMBOL(dusen_para);
int mod_init_dusen(void)
{
printk(KERN_INFO"-------start-------\n");