本次的编程环境: CentOS 6.8
Linux centos 2.6.32-573.8.1.el6.x86_64
在内核的源代码中定义了很多进程和进程调度相关的内容。其实Linux内核中所有关于进程的表示全都放在“进程描述符”这个庞大的结构体当中,关于这个结构体的内容和定义,可以在内核的linux/sched.h文件中找到。
现在就来通过编程实现对进程描述符的操作,主要是读取。至于修改等操作,将在后面的内容中提到。
通过对进程描述符的读取,可以获取进程的一切内容,包括进程的ID,进程的地址空间等等。
不多说,上代码:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 
 | 
 
 #include <linux/tty.h>
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 
 
 void tty_write_message(struct tty_struct *tty,char *msg){
 if(tty && tty->ops->write){
 tty->ops->write(tty,msg,strlen(msg));
 }
 return;
 }
 
 static int my_init(void){
 char *msg="Hello tty!\n";
 tty_write_message(current->signal->tty,msg);
 printk("Hello -- from the kernel...\n");
 printk("Parent  pid: %d(%s)\n",current->parent->pid,current->parent->comm);
 printk("Current pid: %d(%s)\n",current->pid,current->comm);
 printk("Current fs: %d\n",current->fs);
 printk("Current mm: %d\n",current->mm);
 return 0;
 }
 
 static void my_cleanup(void){
 printk("Goodbye -- from the kernel...\n");
 }
 
 module_init(my_init);
 module_exit(my_cleanup);
 
 
 | 
以上的代码,主要就是通过引入内核头文件,进而引用进程描述符中的指针,并通过这种方式获取当前进程和相关进程的描述信息。
Makefile文件如下:
| 12
 
 | #Makefileobj-m += currentptr.o
 
 | 
编译的指令:
| 1
 | make -C /usr/src/linux SUBDIRS=$PWD modules
 | 
然后通过insmod把模块装载进内核,首先tty输出了Hello tty!
同时在/var/log/message中,模块打印出了这些内容:
| 12
 3
 4
 5
 
 | Sep 12 10:35:36 centos kernel: Hello -- from the kernel...Sep 12 10:35:36 centos kernel: Parent  pid: 2235(bash)
 Sep 12 10:35:36 centos kernel: Current pid: 13197(insmod)
 Sep 12 10:35:36 centos kernel: Current fs: 927961856
 Sep 12 10:35:36 centos kernel: Current mm: 932613056
 
 | 
分别是这个进程的相关信息。
对于进程描述符的定义,在本次实验用来编译的内核源码包(kernel-devel-2.6.32-642.4.2.el6.x86_64)中,
进程描述符具体定义在include/linux/sched.h的1326行往后。
 
需要参考的进程具体信息都在其中,可随时参考,以备不时之需。