本次的编程环境: CentOS 6.8
Linux centos 2.6.32-573.8.1.el6.x86_64
在内核的源代码中定义了很多进程和进程调度相关的内容。其实Linux内核中所有关于进程的表示全都放在“进程描述符”这个庞大的结构体当中,关于这个结构体的内容和定义,可以在内核的linux/sched.h文件中找到。
现在就来通过编程实现对进程描述符的操作,主要是读取。至于修改等操作,将在后面的内容中提到。
通过对进程描述符的读取,可以获取进程的一切内容,包括进程的ID,进程的地址空间等等。
不多说,上代码:
1 2 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文件如下:
1 2
| #Makefile obj-m += currentptr.o
|
编译的指令:
1
| make -C /usr/src/linux SUBDIRS=$PWD modules
|
然后通过insmod把模块装载进内核,首先tty输出了Hello tty!
同时在/var/log/message中,模块打印出了这些内容:
1 2 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行往后。
需要参考的进程具体信息都在其中,可随时参考,以备不时之需。