当前位置:文档之家› Linux课程设计

Linux课程设计

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.hstruct 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<linux/init.h>#include<linux/module.h>#include<linux/sched.h>#include<linux/list.h>MODULE_LICENSE("GPL"); //声明许可证GPLstatic 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");return 0;}void mod_exit_dusen(void){printk(KERN_INFO"--------end--------\n");}dusen2.c的代码#include<linux/init.h>#include<linux/module.h>MODULE_LICENSE("GPL"); //声明许可证GPLstatic int mod_init_dusen1(void);static void mod_exit_dusen1(void);module_init(mod_init_dusen1);//指定模块初始化函数module_exit(mod_exit_dusen1); //指定模块退出函数static int pid=0;extern void dusen(void);extern void dusen_para(int pid);int mod_init_dusen1(void){printk(KERN_INFO"-----HELLO!WELCOME--------\n");dusen();dusen_para(pid);return 0;}void mod_exit_dusen1(void){printk(KERN_INFO"--------GOODBYE!!!--------\n");}module_param(pid,int,S_IRUGO);三、运行结果:1.进入dusen1 make一下,生成dusen1.ko然后将dusen1.ko加载到内核,并将Module.symvers文件复制到dusen2中.2.进入dusen2 make一下,将dusne2加载到内核时用名林那个如下sudo insmod dusen2.ko pid=2(查看进程号为2的进程)3.键入命令dmesg,结果如下[ 913.475912] -----HELLO!WELCOME--------[ 913.475947] NAME: init PID: 1 STATE:1[ 913.475954] NAME: kthreadd PID: 2 STATE:1[ 913.475960] NAME: ksoftirqd/0 PID: 3 STATE:1[ 913.475965] NAME: migration/0 PID: 4 STATE:1[ 913.475971] NAME: watchdog/0 PID: 5 STATE:1[ 913.475976] NAME: events/0 PID: 6 STATE:1[ 913.475981] NAME: cpuset PID: 7 STATE:1[ 913.475986] NAME: khelper PID: 8 STATE:1[ 913.475991] NAME: netns PID: 9 STATE:1[ 913.475997] NAME: async/mgr PID: 10 STATE:1[ 913.476002] NAME: pm PID: 11 STATE:1 ...........................[ 913.476586] NAME: wnck-applet PID: 1307 STATE:1[ 913.476592] NAME: gvfs-afc-volume PID: 1309 STATE:1[ 913.476598] NAME: gvfs-gphoto2-vo PID: 1312 STATE:1[ 913.476604] NAME: gvfsd-burn PID: 1325 STATE:1[ 913.476609] NAME: indicator-apple PID: 1337 STATE:1[ 913.476615] NAME: clock-applet PID: 1338 STATE:1[ 913.476621] NAME: indicator-apple PID: 1339 STATE:1[ 913.476627] NAME: notification-ar PID: 1343 STATE:1[ 913.476633] NAME: gdu-notificatio PID: 1350 STATE:1[ 913.476639] NAME: gvfsd-metadata PID: 1369 STATE:1 [ 913.476645] NAME: indicator-sound PID: 1372 STATE:1 [ 913.476651] NAME: indicator-messa PID: 1376 STATE:1 [ 913.476656] NAME: indicator-appli PID: 1379 STATE:1 [ 913.476755] NAME: indicator-sessi PID: 1383 STATE:1 [ 913.476761] NAME: indicator-me-se PID: 1385 STATE:1 [ 913.476767] NAME: applet.py PID: 1412 STATE:1[ 913.476772] NAME: gnome-settings- PID: 1419 STATE:1 [ 913.476778] NAME: update-notifier PID: 1427 STATE:1 [ 913.476784] NAME: system-service- PID: 1441 STATE:1 [ 913.476789] NAME: udevd PID: 1458 STATE:1[ 913.476794] NAME: udevd PID: 1459 STATE:1[ 913.476799] NAME: dconf-service PID: 1507 STATE:1 [ 913.476805] NAME: soffice.bin PID: 1536 STATE:1 [ 913.476811] NAME: gnome-terminal PID: 1558 STATE:1 [ 913.476816] NAME: gnome-pty-helpe PID: 1561 STATE:1 [ 913.476822] NAME: bash PID: 1562 STATE:1[ 913.476827] NAME: insmod PID: 2090 STATE:0[ 913.476875] NAME:kthreadd PID:2 STATE:1[ 913.476900] parent NAME:swapper PID:0 STATE:0[ 913.476935] brother NAME:init PID:1 STATE:1[ 913.476960] brother NAME:kthreadd PID:2 STATE:1[ 913.476992] children NAME:ksoftirqd/0 PID:3 STATE:1[ 913.477014] children NAME:migration/0 PID:4 STATE:1[ 913.477020] children NAME:watchdog/0 PID:5 STATE:1[ 913.477026] children NAME:events/0 PID:6 STATE:1[ 913.477031] children NAME:cpuset PID:7 STATE:1[ 913.477037] children NAME:khelper PID:8 STATE:1[ 913.477042] children NAME:netns PID:9 STATE:1[ 913.477048] children NAME:async/mgr PID:10 STATE:1[ 913.477053] children NAME:pm PID:11 STATE:1...................[ 913.477200] children NAME:kconservative/0 PID:45 STATE:1 [ 913.477206] children NAME:mpt_poll_0 PID:172 STATE:1[ 913.477211] children NAME:mpt/0 PID:173 STATE:1[ 913.477217] children NAME:scsi_eh_2 PID:174 STATE:1[ 913.477223] children NAME:jbd2/sda1-8 PID:191 STATE:1 [ 913.477229] children NAME:ext4-dio-unwrit PID:192 STATE:1 [ 913.477234] children NAME:flush-8:0 PID:225 STATE:1[ 913.477240] children NAME:kpsmoused PID:395 STATE:1[ 913.477246] children NAME:vmmemctl PID:405 STATE:1[ 913.477572] children NAME:kgameportd PID:549 STATE:1四、实验心得:通过本次试验自己学到了很多东西,也了解了一些错误,对此自己总结了一下几条:1、L inux内核中不能调用标准c函数以及一些内核函数;2、L inux2.6以后的版本必须对Module.symvers进行复制,这是课本里提到的,开始没有注意到,所以费了很大的功夫;3、开始对于task_struct理解认识的并不够,只是简单的借用网上的代码4、程序做的不够完整,在加载dusen2时,如果必须先不要写pid,然后查看进程,之后若要查看某一进程,还要把dusen2rm掉重新加载。

相关主题