刚写的一个unix作业,关于内核编程的--2010-1-8 18:13

转自我另一个的博客,书写日期

2010-1-8 18:13

作业题目:

内核模块编程练习

设计两个内核模块,它们分别完成以下工作:

1) 设计一个模块,该模块的功能是列出系统中所有内核进程的程序名、PID号和进程的状态。

2) 设计一个带有参数的内核模块,其参数为某个进程的PID号;该模块的功能是列出该进程的家族信息,包括父进程、兄弟进程和子进程的程序名、PID号。

 

作业1的答案:

 1  #include  < linux / init.h >     // 定义在init.h
 2  #include  < linux / module.h >
 3  #include  < linux / sched.h >
 4  #include  < linux / list.h >
 5 
 6  MODULE_LICENSE( " GPL " );
 7 
 8  static   int  name_init( void // 初始化函数,注册和申请资源。返回0表示初始化成功;其他值表示失败
 9  {
10      printk( " My name is Liu Xu/n " );
11       struct  task_struct  * p, * task1;
12       struct  list_head  * ptr;
13      for_each_process(p)
14      {    
15          printk( " /nProcess info:/n " );
16          printk( " comm=%s,pid=%d,state=%ld/n " ,p -> comm,p -> pid,p -> state);
17          task1 = list_entry( & p -> children, struct  task_struct,children);
18          printk( " /nChildren info:/n " );
19          list_for_each(ptr, & (p -> children)){
20              task1 = list_entry(ptr, struct  task_struct,sibling);
21              printk( " child:comm=%s,pid=%d,state=%ld/n " ,task1 -> comm,task1 -> pid,task1 -> state);
22          
23          }
24          printk( " /n " );
25      }
26 
27       return   0 ;    
28  }
29  static   void  name_exit( void )   //  退出的函数,注销和释放资源
30  {
31      printk( " Goodbye!/n " );
32  }
33 
34  module_init(name_init);  // 标记的name_init函数在模块加载时调用
35  module_exit(name_exit);  // 标记的name_exit函数在卸载模块时调用
36 


作业2的答案:

 1  #include  < linux / init.h >     // 定义在init.h
 2  #include  < linux / module.h >
 3  #include  < linux / sched.h >
 4  #include  < linux / list.h >
 5 
 6  MODULE_LICENSE( " GPL " );
 7  static   int  pid = 1 ;
 8  module_param(pid, int ,S_IRUGO); // 给模块传递参数
 9 
10  static   int  name_init( void // 初始化函数,注册和申请资源。返回0表示初始化成功;其他值表示失败
11  {
12       struct  task_struct  * task1, * task2;
13       struct  list_head  * ptr;
14 
15      printk( " My name is Liu Xu/n " );
16       // find_task_by_pid 和 find_task_by_vpid在2.6.30版后内核都没有被声明为extern
17       // find_get_pid是获得pid_t对应的pid结构指针,以给pid_task调用,在内核版本号为2.6.31-17-generic下测试通过
18      task1 = pid_task(find_get_pid(pid),PIDTYPE_PID);    
19       if (task1){
20          printk( " The wanted process info:/n " );
21          printk( " ##Wanted:comm=%s,pid=%d,state=%ld/n " ,task1 -> comm,task1 -> pid,task1 -> state);
22          task2 = task1 -> parent;
23          printk( " ##His Parent:comm=%s,pid=%d,state=%ld/n " ,task2 -> comm,task2 -> pid,task2 -> state);
24           /* list_for_each(ptr,&task1->children){
25              task2=list_entry(ptr,struct task_struct,tasks);//ptr是task1的child,是task2的sibiling,双链表
26              printk("##His child:comm=%s,pid=%d,state=%ld/n",task2->comm,task2->pid,task2->state);
27          } */
28           // searching the children
29             list_for_each_entry(task2,  & task1 -> children, sibling) {
30              printk( " ##His child:comm=%s,pid=%d,state=%ld/n " ,task2 -> comm,task2 -> pid,task2 -> state);
31          }
32           // searching the siblings
33          list_for_each_entry(task2,  & task1 -> real_parent -> children, sibling) {
34              printk( " ##His siblings:comm=%s,pid=%d,state=%ld/n " ,task2 -> comm,task2 -> pid,task2 -> state);
35          }
36          
37      } else {
38          printk( " process %d does not exist!/n " ,pid);
39      }    
40       return   0 ;    
41  }
42  static   void  name_exit( void )   //  退出的函数,注销和释放资源
43  {
44      printk( " Goodbye!/n " );
45  }
46 
47  module_init(name_init);  // 标记的name_init函数在模块加载时调用
48  module_exit(name_exit);  // 标记的name_exit函数在卸载模块时调用
49 

作业2因为在linux内核版本2.6.30以后,没有把find_task_by_vpid声明为extern,所以不能当作API函数调用,我在网上搜了好多方法才最终找到解决方案的。。
第18行的那句话,在2.6.24版本以前的内核,应该写成
task1=find_task_by_pid(pid);

在2.6.30版本以前内核应该写成

task1=find_task_by_vpid(pid);

最后把那个超级通用的内核编译的Makefile发出来吧。。

ifneq ($(KERNELRELEASE),)
    obj
- m: = name.o
else
    KDIR:
=/ lib / modules / $(shell uname  - r) / build
    PWD:
= $(shell pwd)

default :
    $(MAKE) 
- C $(KDIR) M = $(PWD) modules
clean:
    $(MAKE) 
- C $(KDIR) M = $(PWD) clean

endif

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值