今天上课的时候老师让练习书上的例子,是关于linux中的进程中的虚存。通过下面的例子可以清楚的知道linux内核是如何把共享库及各个程序段映射到进程的用户空间的。
#include<linux/interrupt.h>
#include<linux/sched.h>
#define find_task 0xc106a660
static int pid;
module_param(pid,int ,0644);
static int __init TestMemory_Init(void)
{
struct task_struct *p;
struct vm_area_struct *temp;
struct task_struct* (*func)(int id);
printk("the virtual memory areas are :\n");
func = find_task;
// p = find_task_by_vpid(pid);
p = (*func)(pid);
temp = p->mm->mmap;
while(temp)
{
printk("start:%p\t end:%p\n",(unsigned long *)temp->vm_start,(unsigned long *)temp->vm_end);
temp = temp->vm_next;
}
return 0;
}
static void __exit TestMemory_Exit(void)
{
printk("delete the module.....\n");
return ;
}
module_init(TestMemory_Init);
module_exit(TestMemory_Exit);
MODULE_LICENSE("GPL");
选择一个正在运行的进程id,作为该模块的输入参数。
$ sudo insmod test.ko pid=3278
$ dmesg
可以看出,输出的信息就是该进程的虚存区的起始地址和结束地址。
需要注意的是,由于内核版本的不同,系统函数find_task_by_vpid()可能使用不了,所以您可以使用函数指针来解决这个问题。首先,找到内核中find_task_by_vpid()的函数入口地址(每台机器上的地址都不一样),在这段代码里,它的入口地址是0xc106a660,然后定义一个返回值和find_task_by_vpid()一样的函数指针,将获取来的入口地址赋给这个指针,接着您就可以通过使用指针来达到和find_task_by_vpid()一样的效果。
ps:以下附上一篇介绍函数指针和指针函数的文章 http://www.cnblogs.com/gmh915/archive/2010/06/11/1756067.html